Results 1 to 5 of 5

Thread: Linux C shared libraries question

  1. #1
    Senior Member frpeter's Avatar
    Join Date
    Dec 2004
    Posts
    131

    Question Linux C shared libraries question

    Hi,

    I'm experiencing a rather unusual situation that isn't making sense to me. I'm not as familiar with linux's shared library mechanisms as I perhaps should be. This code was stripped down from a much larger project, so it'll look a little strange, but it easily demonstrates the questions I'll ask at the bottom on this:

    Here is the script I am using to compile this test:

    Code:
    #!/bin/sh
    
    clear
    
    export DEF="-D_USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE"
    export SRC="-D_REENTRANT -D_BSD_SOURCE"
    export OPT="-w -O3 -march=i686 -mtune=i686 -ffast-math -funroll-loops -fno-exceptions -minline-all-stringops"
    
    gcc -c -o test.o test.c $DEF $SRC $OPT
    
    ar rcs libtest.a test.o
    
    gcc -fPIC -c -o test.o test.c $DEF $SRC $OPT
    
    gcc -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.0.0 test.o -lc
    
    ldconfig -n .
    
    export DEF="-D_USE_LARGEFILE64 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE"
    export SRC="-D_REENTRANT -D_BSD_SOURCE"
    export SHLIB="-ltest -L."
    export OPT="-w -O3 -march=i686 -mtune=i686 -ffast-math -funroll-loops -fno-exceptions -minline-all-stringops"
    
    gcc -o StrICmpTest StrICmpTest.c $DEF $SRC $SHLIB $OPT
    Here is my test library code - test.c:

    Code:
    #include <stdio.h>
    
    #define C                           unsigned char
    #define D                           double
    #define F                           float
    #define I                           int
    #define L                           long
    #define UL2                         unsigned long long
    #define L2                          long long
    #define LD                          long double
    #define S                           struct
    #define SC                          signed char
    #define SI                          signed int
    #define STR                         string
    #define U                           union
    #define UC                          unsigned char
    #define UI                          unsigned int
    #define UL                          unsigned long
    #define US                          unsigned short
    #define V                           void
    
    #define dStrIsLower(c)              (c>='a'&&c<='z')
    #define dStrIsUpper(c)              (c>='A'&&c<='Z')
    #define dStrToLower(c)              (dStrIsUpper(c)?c-'a'-'A':c)
    #define dStrToUpper(c)              (dStrIsLower(c)?c+'a'-'A':c)
    
    
    I stricmp7(C *s1, C *s2)
      {
        UL  i, l1, l2, m;
        C   d1, d2;
    
        l1=strlen(s1);
        l2=strlen(s2);
    
        m=l1<l2?l1:l2;
    
        if(l1!=l2)
          return(l1-l2);
    
        for(i=0;i<m;i++)
          {
            d1=dStrToLower(s1[i]);
            d2=dStrToLower(s2[i]);
    
            if(d1!=d2)
              return(d1-d2);
          }
    
        return(0);
      }
    The main program - StrICmpTest.c:

    Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <time.h>
    #include <sys/time.h>
    
    #define MEGABYTE        1048576
    
    typedef unsigned char               string[256];
    
    #define C                           unsigned char
    #define D                           double
    #define F                           float
    #define I                           int
    #define L                           long
    #define UL2                         unsigned long long
    #define L2                          long long
    #define LD                          long double
    #define S                           struct
    #define SC                          signed char
    #define SI                          signed int
    #define STR                         string
    #define U                           union
    #define UC                          unsigned char
    #define UI                          unsigned int
    #define UL                          unsigned long
    #define US                          unsigned short
    #define V                           void
    
    #define dStrIsLower(c)              (c>='a'&&c<='z')                                                                           
    #define dStrIsUpper(c)              (c>='A'&&c<='Z')                                                                           
    #define dStrToLower(c)              (dStrIsUpper(c)?c-'a'-'A':c)                                                               
    #define dStrToUpper(c)              (dStrIsLower(c)?c+'a'-'A':c)                                                               
                                                                                                                                   
    #define NFACTOR     3072
    #define NTIMES      (NFACTOR*NFACTOR)
    
    I stricmp1(C *s1, C *s2)
      {
        UL  i, l1, l2, m;
        C   d1, d2;
    
        l1=strlen(s1);
        l2=strlen(s2);
    
        m=l1<l2?l1:l2;
    
        if(l1!=l2)
          return(l1-l2);
    
        for(i=0;i<m;i++)
          {
            d1=dStrToLower(s1[i]);
            d2=dStrToLower(s2[i]);
    
            if(d1!=d2)
              return(d1-d2);
          }
    
        return(0);
      }
    
    I main(I argc, C *argv[])
      {
        clock_t      st, et;
        STR          buffer;
        I            i, l1;
        
        strcpy(buffer,"Hello World ABCDEFGHIJKLMNOPQRSTUVWXYZ");
    
        st=clock();
        for(i=0;i<NTIMES;i++) {
        l1=strcasecmp(buffer,buffer);
        l1=strcasecmp(buffer,"Hello World ABCDEFGHIJKLMNOPQRSTUVWXYZ Kitty"); }
        et=clock();
        
        printf("strcasecmp,          %f\n",((D)(et-st))/((D)CLOCKS_PER_SEC));
        
        st=clock();
        for(i=0;i<NTIMES;i++) {
        l1=stricmp1(buffer,buffer);
        l1=stricmp1(buffer,"Hello World ABCDEFGHIJKLMNOPQRSTUVWXYZ Kitty"); }
        et=clock();
        
        printf("stricmp1,            %f\n",((D)(et-st))/((D)CLOCKS_PER_SEC));
        
        st=clock();
        for(i=0;i<NTIMES;i++) {
        l1=stricmp7(buffer,buffer);
        l1=stricmp7(buffer,"Hello World ABCDEFGHIJKLMNOPQRSTUVWXYZ Kitty"); }
        et=clock();
        
        printf("stricmp7,            %f\n",((D)(et-st))/((D)CLOCKS_PER_SEC));
    
        return(0);
      }
    Now for the output:

    Code:
    ./MKTlib && ./StrICmpTest
    
    strcasecmp,          0.000000
    stricmp1,            0.020000
    stricmp7,            1.910000
    As you can see, the program runs perfectly. I'm using a full and clean install of Slackware 13.1, gcc version of 4.4.4

    Now for the questions:

    1. Why does stricmp7 take so much longer to run then stricmp1 when the code of both is identical?

    Code:
    ldd StrICmpTest
            linux-gate.so.1 =>  (0xb7794000)
            libc.so.6 => /lib/libc.so.6 (0xb761b000)
            /lib/ld-linux.so.2 (0xb7795000)
    2. Why does libtest NOT show up in the above?

    3. What can be done to fix this problem?

    Thank you in advance.

  2. #2
    Just Another Geek
    Join Date
    Jul 2002
    Location
    Rotterdam, Netherlands
    Posts
    3,401
    Quote Originally Posted by frpeter View Post
    1. Why does stricmp7 take so much longer to run then stricmp1 when the code of both is identical?
    You used different compiler options.
    Oliver's Law:
    Experience is something you don't get until just after you need it.

  3. #3
    Senior Member frpeter's Avatar
    Join Date
    Dec 2004
    Posts
    131
    Hi,

    Quote Originally Posted by SirDice View Post
    You used different compiler options.
    I must be dense as I'm not understanding where the options are different. I specified the below options for both the library and the main code:

    -w -O3 -march=i686 -mtune=i686 -ffast-math -funroll-loops -fno-exceptions
    -minline-all-stringops

    Are there different options required for the library to be properly optimized?

    Thanks.

  4. #4
    Just Another Geek
    Join Date
    Jul 2002
    Location
    Rotterdam, Netherlands
    Posts
    3,401
    No, you're right. I'm the one that's being dense.

    It might be because of the overhead though. The library needs to be loaded and initialized before it's used. The built-in function obviously doesn't.

    See what happens if you execute both functions multiple times. I'm sure the times will converge more as the overhead of loading the library only happens once.
    Oliver's Law:
    Experience is something you don't get until just after you need it.

  5. #5
    Senior Member frpeter's Avatar
    Join Date
    Dec 2004
    Posts
    131
    Quote Originally Posted by SirDice View Post
    It might be because of the overhead though. The library needs to be loaded and initialized before it's used. The built-in function obviously doesn't.

    See what happens if you execute both functions multiple times. I'm sure the times will converge more as the overhead of loading the library only happens once.
    I actually tried this several times against strcasecmp thinking the same thing, but I didn't get the same results with the standard library as you'll see in the example I provided. I know the standard library is optimized in assembly, but the load time should still be a factor with the standard library as with my test library.

    I repeated the tests several hundred times with and without debugging turned on as well as a myriad of different compiler options and even on a different linux platform seeing if I had a broken linker trying to trace this. The timing of my test library actually behaves as if debugging is turned on even though it isn't. I also did an strace and gprof to see if anything unusual showed up. Everything went as one would expect.

    The timing difference is relatively small, usually on the order of 0.01 to 0.05 ms... I do need to post the code over as I noticed a few typos, but those have no baring on the load and run times of the library.

    Thanks.

Similar Threads

  1. Which version of Linux to use
    By gore in forum Operating Systems
    Replies: 83
    Last Post: June 1st, 2017, 01:33 PM
  2. freeBSD and Linux and windows... how?
    By rider_royal in forum Newbie Security Questions
    Replies: 25
    Last Post: July 3rd, 2005, 10:43 AM
  3. Asking smart questions
    By pwaring in forum Other Tutorials Forum
    Replies: 60
    Last Post: October 22nd, 2004, 09:15 PM
  4. Replies: 6
    Last Post: October 5th, 2004, 08:26 AM
  5. The history of the Mac line of Operating systems
    By gore in forum Operating Systems
    Replies: 3
    Last Post: March 7th, 2004, 08:02 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •