On Monday 11 May 2009 16:53:23 Jay Pipes wrote:
> Francesco Riosa wrote:
> > gcc -c -Q -O3 --help=optimizers | grep funroll-loops
> >   -funroll-loops                        [disabled]
> >
> > -funroll-loops is the first branch in the root of evil, don't rely on it,
> > even force -O3 isn't as good as it seem often.
>
> Hehe, yes, I'm aware of the dangers :)  /me is not a Gentoo user ;)

No comment, you little anti-gentoo fanboy :)

> But, since loop unrolling was involved in the particular case I thought
> it might be worth benchmarking it.  Then again, I'm more in favor of
> Roy's solution of targeting the tightest loops.

BTW just out of curiosity, would the tecniques described here:
http://www.flipcode.com/archives/Unrolling_Loops_With_Meta-Programming.shtml
do unrolling in a more controlled way?
disclaimer, I don't speak c++

>
> Cheers!
>
> jay
>
> > On Sunday 10 May 2009 19:11:14 Jay Pipes wrote:
> >> Have we tried running the benchmarks with and without -funroll-loops?
> >>
> >> -j
> >>
> >> Stewart Smith wrote:
> >>> So i broke out mtaylor's patch that we were bumming around with at the
> >>> UC to replace ptr_compare with a simple memcmp call.
> >>>
> >>> At the UC I benched that this patch actually caused a measurable
> >>> performance regresssion.
> >>>
> >>> So what's the difference?
> >>> (same benchmark and machine as in previous mail)
> >>>
> >>> MAX_FIELDS=64 with std::bitset
> >>>     read/write requests:                 70000  (3374.50 per sec.)
> >>>     read/write requests:                 70000  (3102.42 per sec.)
> >>>     read/write requests:                 70000  (3113.47 per sec.)
> >>>     read/write requests:                 70000  (3401.89 per sec.)
> >>>     read/write requests:                 70000  (3164.61 per sec.)
> >>> AVERAGE= 3231.37
> >>>
> >>> With ptr_compare replaced with memcmp:
> >>>     read/write requests:                 70000  (3090.33 per sec.)
> >>>     read/write requests:                 70000  (3066.97 per sec.)
> >>>     read/write requests:                 70000  (2954.93 per sec.)
> >>>     read/write requests:                 70000  (2875.57 per sec.)
> >>>     read/write requests:                 70000  (2953.99 per sec.)
> >>> AVERAGE= 2988.35
> >>>
> >>> With ptr_compare replaced with __builtin_memcmp:
> >>>     read/write requests:                 70000  (3245.37 per sec.)
> >>>     read/write requests:                 70000  (3001.91 per sec.)
> >>>     read/write requests:                 70000  (3254.99 per sec.)
> >>>     read/write requests:                 70000  (3177.13 per sec.)
> >>>     read/write requests:                 70000  (3195.49 per sec.)
> >>> AVERAGE= 3174.97
> >>>
> >>>
> >>> So, I  thought that with just using the __builtin_memcmp automatically,
> >>> we may be okay with merging this.
> >>>
> >>> However... I do have the following concerns:
> >>> 1) I'm pretty sure that __builtin_memcmp is gcc only, and that
> >>> SunStudio may have an issue (yay - wrappers!)
> >>> 2) Is this perf difference going to be true on different platforms?
> >>> 3) the various memcmp implementations do seem to be dependent on a few
> >>> things for performance: alignment, size of data.
> >>>
> >>> For what we're seeing in sysbench, the parameters are things like this:
> >>> "SELECT c from sbtest where id between 9942 and 10041 order by c"
> >>>
> >>> 0xc30780,0xc2c340,240
> >>> 0xc2e560,0xc2c340,240
> >>> 0xc30780,0xc2e560,240
> >>> 0xc37390,0xc32f50,240
> >>> 0xc35170,0xc32f50,240
> >>> 0xc37390,0xc35170,240
> >>> 0xc3dcc8,0xc39888,240
> >>> 0xc3baa8,0xc2e560,240
> >>> 0xc35170,0xc2e560,240
> >>> 0xc3baa8,0xc35170,240
> >>> 0xc2c340,0xc35170,240
> >>> 0xc35170,0xc3dcc8,240
> >>> 0xc2c618,0xc35170,240
> >>> 0xc35170,0xc3d9f0,240
> >>> 0xc2c8f0,0xc35170,240
> >>> 0x7fbed85f10f0,0x7fbed85eccb0,240
> >>>
> >>> and from the CREATE TABLE:
> >>>         `c` VARCHAR(120) NOT NULL  COLLATE utf8_general_ci DEFAULT `` ,
> >>>
> >>> So here it's large, and aligned.
> >>>
> >>> For some other micro-benchmarks I've clocked things looking much
> >>> different.... so it's possibly query dependent as to what ends up being
> >>> better (i.e. how much data we're comparing).
> >>>
> >>> (1st parameter is number of repetitions, 2nd is number of bytes to
> >>> memcmp)
> >>>
> >>>
> >>> For comparing equal values:
> >>>
> >>> stew...@willster:~/src/test/memcmp$ ./a.out 168435455 8
> >>> 168435455 repetitions
> >>>
> >>> Testing memcmp ..... done,      7.432 seconds
> >>> Testing builtin memcmp ....... done,     16.313 seconds
> >>> Testing loop .... done,      6.144 seconds
> >>> Testing loop32 .... done,      2.764 seconds
> >>> Testing loop64 .... done,      2.128 seconds
> >>> Testing no-op .... done,      1.488 seconds
> >>> stew...@willster:~/src/test/memcmp$ ./a.out 168435455 16
> >>> 168435455 repetitions
> >>>
> >>> Testing memcmp ..... done,      5.912 seconds
> >>> Testing builtin memcmp ....... done,     26.418 seconds
> >>> Testing loop .... done,     11.201 seconds
> >>> Testing loop32 .... done,      3.980 seconds
> >>> Testing loop64 .... done,      2.564 seconds
> >>> Testing no-op .... done,      1.492 seconds
> >>> stew...@willster:~/src/test/memcmp$ ./a.out 168435455 32
> >>> 168435455 repetitions
> >>>
> >>> Testing memcmp ..... done,      6.828 seconds
> >>> Testing builtin memcmp ....... done,     46.891 seconds
> >>> Testing loop .... done,     21.473 seconds
> >>> Testing loop32 .... done,      6.536 seconds
> >>> Testing loop64 .... done,      3.804 seconds
> >>> Testing no-op .... done,      1.476 seconds
> >>> stew...@willster:~/src/test/memcmp$ ./a.out 168435455 64
> >>> 168435455 repetitions
> >>>
> >>> Testing memcmp ..... done,      9.549 seconds
> >>> Testing builtin memcmp ....... done,     87.513 seconds
> >>> Testing loop .... done,     41.455 seconds
> >>> Testing loop32 .... done,     11.669 seconds
> >>> Testing loop64 .... done,      6.368 seconds
> >>> Testing no-op .... done,      1.468 seconds
> >>> stew...@willster:~/src/test/memcmp$ ./a.out 168435455 128
> >>> 168435455 repetitions
> >>>
> >>> Testing memcmp ..... done,     15.081 seconds
> >>> Testing builtin memcmp ....... done,    169.143 seconds
> >>> Testing loop .... done,     86.397 seconds
> >>> Testing loop32 .... done,     21.877 seconds
> >>> Testing loop64 .... done,     11.445 seconds
> >>> Testing no-op .... done,      1.488 seconds
> >>> stew...@willster:~/src/test/memcmp$ gcc -O3 -fno-builtin memcmpbench.c
> >>> stew...@willster:~/src/test/memcmp$ ./a.out 168435455 256
> >>> 168435455 repetitions
> >>>
> >>> Testing memcmp ..... done,     26.134 seconds
> >>> Testing loop64 .... done,     21.549 seconds
> >>> Testing no-op .... done,      1.500 seconds
> >>>
> >>>
> >>>
> >>> Completely inequal values are all about the same:
> >>>
> >>> stew...@willster:~/src/test/memcmp$ ./a.out 168435455 8
> >>> 168435455 repetitions
> >>>
> >>> Testing memcmp ..... done,      3.204 seconds
> >>> Testing builtin memcmp ....... done,     13.945 seconds
> >>> Testing loop .... done,      1.896 seconds
> >>> Testing loop32 .... done,      2.092 seconds
> >>> Testing loop64 .... done,      2.136 seconds
> >>> Testing no-op .... done,      1.488 seconds
> >>>
> >>> stew...@willster:~/src/test/memcmp$ ./a.out 168435455 240
> >>> 168435455 repetitions
> >>>
> >>> Testing memcmp ..... done,      5.520 seconds
> >>> Testing builtin memcmp ....... done,     13.973 seconds
> >>> Testing loop .... done,      1.912 seconds
> >>> Testing loop32 .... done,      2.124 seconds
> >>> Testing loop64 .... done,      2.104 seconds
> >>> Testing no-op .... done,      1.468 seconds
> >>>
> >>>
> >>> For half the same:
> >>> stew...@willster:~/src/test/memcmp$ ./a.out 168435455 8
> >>> 168435455 repetitions
> >>>
> >>> Testing memcmp ..... done,      7.340 seconds
> >>> Testing builtin memcmp ....... done,     19.193 seconds
> >>> Testing loop .... done,      4.212 seconds
> >>> Testing loop32 .... done,      2.956 seconds
> >>> Testing loop64 .... done,      2.112 seconds
> >>> Testing no-op .... done,      1.476 seconds
> >>>
> >>> stew...@willster:~/src/test/memcmp$ ./a.out 168435455 32
> >>> 168435455 repetitions
> >>>
> >>> Testing memcmp ..... done,      5.920 seconds
> >>> Testing builtin memcmp ....... done,     34.526 seconds
> >>> Testing loop .... done,     11.885 seconds
> >>> Testing loop32 .... done,      4.444 seconds
> >>> Testing loop64 .... done,      3.388 seconds
> >>> Testing no-op .... done,      1.468 seconds
> >>>
> >>> stew...@willster:~/src/test/memcmp$ ./a.out 168435455 64
> >>> 168435455 repetitions
> >>>
> >>> Testing memcmp ..... done,      6.948 seconds
> >>> Testing builtin memcmp ....... done,     54.923 seconds
> >>> Testing loop .... done,     22.081 seconds
> >>> Testing loop32 .... done,      7.000 seconds
> >>> Testing loop64 .... done,      4.444 seconds
> >>> Testing no-op .... done,      1.488 seconds
> >>>
> >>>
> >>> Is concurrency an issue here and not raw single threaded performance?
> >>>
> >>> Let's try with 64 threads (on the same 2 core box):
> >>>
> >>> 64 threads, __builtin_memcmp:
> >>>     read/write requests:                 70000  (3184.20 per sec.)
> >>>     read/write requests:                 70000  (3184.87 per sec.)
> >>>     read/write requests:                 70000  (3166.83 per sec.)
> >>>     read/write requests:                 70000  (3085.69 per sec.)
> >>> AVERAGE=3155.39
> >>>
> >>> 64 threads, memcmp:
> >>>     read/write requests:                 70000  (3218.07 per sec.)
> >>>     read/write requests:                 70000  (3219.04 per sec.)
> >>>     read/write requests:                 70000  (3222.48 per sec.)
> >>>     read/write requests:                 70000  (3116.00 per sec.)
> >>> AVERAGE=3193.89
> >>>
> >>>
> >>> 64 threads, 32bit cmp loop:
> >>>     read/write requests:                 70000  (3173.76 per sec.)
> >>>     read/write requests:                 70000  (3156.23 per sec.)
> >>>     read/write requests:                 70000  (3206.70 per sec.)
> >>>     read/write requests:                 70000  (3247.61 per sec.)
> >>> AVERAGE=3196.07
> >>>
> >>> 64 threads, 64bit cmp loop:
> >>>     read/write requests:                 70000  (3210.02 per sec.)
> >>>     read/write requests:                 70000  (3218.87 per sec.)
> >>>     read/write requests:                 70000  (3225.98 per sec.)
> >>>     read/write requests:                 70000  (3131.60 per sec.)
> >>> AVERAGE= 3196.61
> >>>
> >>> 64 threads, baseline (using original ptr_compare):
> >>>     read/write requests:                 70000  (3542.95 per sec.)
> >>>     read/write requests:                 70000  (3556.15 per sec.)
> >>>     read/write requests:                 70000  (3560.71 per sec.)
> >>>     read/write requests:                 70000  (3476.80 per sec.)
> >>> AVERAGE=3534.15
> >>>
> >>> i.e. the old ptr_compare whoops the arse of any of the memcmp calls
> >>> with higher concurrency.
> >>>
> >>>
> >>> So, after this I can conclude:
> >>> - memcmp is nothing if not consistent across various microbenchmarks
> >>> - builtin_memcmp seems to help a bit at lower concurrency, not at all
> >>> at higher and is seldom useful in micro benchmark.
> >>>
> >>> - the 64bit loop isn't so good at higher concurrency
> >>> - the 64bit loop is favourable in microbenchmarks
> >>> - memcmp is close to the 64bit loop performance (at most only 2x
> >>> slower)
> >>>
> >>> Unrolling loops being the key?
> >>>
> >>> Testing loop .... done,     11.813 seconds
> >>> Testing unrollloop .... done,      7.628 seconds
> >>> Testing unrollloop32 .... done,      2.532 seconds
> >>> Testing unrollloop64 .... done,      2.536 seconds
> >>> Testing loop32 .... done,      4.432 seconds
> >>> Testing loop64 .... done,      3.792 seconds
> >>> Testing no-op .... done,      1.276 seconds
> >>>
> >>> (32 and 64 do 32,64 bit compares in an unrolled loop)
> >>>
> >>> Questions:
> >>> - Why does my 64bit compare loop not equal performance of ptr_compare
> >>> unrolled loop? (in a microbenchmark, it beats it). Concurrency again?
> >>>
> >>>
> >>> So what should we do?
> >>>
> >>> Certainly a  call to memcmp is easier to understand and keeps the code
> >>> nice and simple, but we're talking up to a 10% speed hit here at higher
> >>> concurrency (at least on my hardware).
> >>>
> >>> I wonder what the difference is on various other hardware setups.
> >>>
> >>> I'd be very interested to see what happens on sparc.
> >>>
> >>> I'd also like to see it micro-benchmarked - preferably something we
> >>> could repeat in future (even in ./configure ? on server startup ?)
> >>>
> >>> I'm voting to keep the current ptr_compare code, and hope that somebody
> >>> provides further explanation on top of what I've looked at here.
> >>>
> >>>
> >>>
> >>>
> >>> Below is the patch, followed by the code i used for microbenchmarking
> >>> (note the commented out 64bit loop i used for the above loop tests):
> >>>
> >>> === modified file 'drizzled/filesort.cc'
> >>> --- drizzled/filesort.cc  2009-04-28 00:17:10 +0000
> >>> +++ drizzled/filesort.cc  2009-05-08 05:59:11 +0000
> >>> @@ -1135,7 +1135,7 @@ int merge_buffers(SORTPARAM *param, IO_C
> >>>    }
> >>>    else
> >>>    {
> >>> -    cmp= get_ptr_compare(sort_length);
> >>> +    cmp= (qsort2_cmp)ptr_compare;
> >>>      first_cmp_arg= (void*) &sort_length;
> >>>    }
> >>>    priority_queue<BUFFPEK *, vector<BUFFPEK *>, compare_functor >
> >>>
> >>> === modified file 'mysys/mf_sort.cc'
> >>> --- mysys/mf_sort.cc      2009-04-17 21:01:47 +0000
> >>> +++ mysys/mf_sort.cc      2009-05-08 05:59:11 +0000
> >>> @@ -34,7 +34,7 @@ void my_string_ptr_sort(unsigned char *b
> >>>    {
> >>>      if (size && items)
> >>>      {
> >>> -      my_qsort2(base,items, sizeof(unsigned char*),
> >>> get_ptr_compare(size), +      my_qsort2(base,items, sizeof(unsigned
> >>> char*), (qsort2_cmp)ptr_compare, (void*) &size);
> >>>      }
> >>>    }
> >>>
> >>> === modified file 'mysys/my_sys.h'
> >>> --- mysys/my_sys.h        2009-04-27 22:05:43 +0000
> >>> +++ mysys/my_sys.h        2009-05-08 05:59:11 +0000
> >>> @@ -420,7 +420,12 @@ extern void my_qsort(void *base_ptr, siz
> >>>                       qsort_cmp cmp);
> >>>  extern void my_qsort2(void *base_ptr, size_t total_elems, size_t size,
> >>>                        qsort2_cmp cmp, void *cmp_argument);
> >>> -extern qsort2_cmp get_ptr_compare(size_t);
> >>> +
> >>> +#if defined(__cplusplus)
> >>> +extern "C"
> >>> +#endif
> >>> +int ptr_compare(size_t *compare_length, unsigned char **a, unsigned
> >>> char **b); +
> >>>  void my_store_ptr(unsigned char *buff, size_t pack_length, my_off_t
> >>> pos); my_off_t my_get_ptr(unsigned char *ptr, size_t pack_length);
> >>>  File create_temp_file(char *to, const char *dir, const char *pfx,
> >>>
> >>> === modified file 'mysys/ptr_cmp.cc'
> >>> --- mysys/ptr_cmp.cc      2009-04-26 16:53:32 +0000
> >>> +++ mysys/ptr_cmp.cc      2009-05-08 05:59:11 +0000
> >>> @@ -21,137 +21,33 @@
> >>>
> >>>  #include "mysys/mysys_priv.h"
> >>>  #include "plugin/myisam/myisampack.h"
> >>> -
> >>> -static int ptr_compare(size_t *compare_length, unsigned char **a,
> >>> unsigned char **b); -static int ptr_compare_0(size_t *compare_length,
> >>> unsigned char **a, unsigned char **b); -static int ptr_compare_1(size_t
> >>> *compare_length, unsigned char **a, unsigned char **b); -static int
> >>> ptr_compare_2(size_t *compare_length, unsigned char **a, unsigned char
> >>> **b); -static int ptr_compare_3(size_t *compare_length, unsigned char
> >>> **a, unsigned char **b); -
> >>> - /* Get a pointer to a optimal byte-compare function for a given size
> >>> */ -
> >>> -qsort2_cmp get_ptr_compare (size_t size)
> >>> -{
> >>> -  if (size < 4)
> >>> -    return (qsort2_cmp) ptr_compare;
> >>> -  switch (size & 3) {
> >>> -    case 0: return (qsort2_cmp) ptr_compare_0;
> >>> -    case 1: return (qsort2_cmp) ptr_compare_1;
> >>> -    case 2: return (qsort2_cmp) ptr_compare_2;
> >>> -    case 3: return (qsort2_cmp) ptr_compare_3;
> >>> -    }
> >>> -  return 0;                                      /* Impossible */
> >>> -}
> >>> -
> >>> +#include <string.h>
> >>>
> >>>   /*
> >>>     Compare to keys to see witch is smaller.
> >>> -   Loop unrolled to make it quick !!
> >>>   */
> >>>
> >>> -#define cmp(N) if (first[N] != last[N]) return (int) first[N] - (int)
> >>> last[N] -
> >>> -static int ptr_compare(size_t *compare_length, unsigned char **a,
> >>> unsigned char **b) -{
> >>> -  register int length= *compare_length;
> >>> -  register unsigned char *first,*last;
> >>> -
> >>> -  first= *a; last= *b;
> >>> -  while (--length)
> >>> -  {
> >>> -    if (*first++ != *last++)
> >>> -      return (int) first[-1] - (int) last[-1];
> >>> -  }
> >>> -  return (int) first[0] - (int) last[0];
> >>> -}
> >>> -
> >>> -
> >>> -static int ptr_compare_0(size_t *compare_length,unsigned char **a,
> >>> unsigned char **b) +extern "C"
> >>> +int ptr_compare(size_t *compare_length, unsigned char **a, unsigned
> >>> char **b) {
> >>> -  register int length= *compare_length;
> >>> -  register unsigned char *first,*last;
> >>> -
> >>> -  first= *a; last= *b;
> >>> - loop:
> >>> -  cmp(0);
> >>> -  cmp(1);
> >>> -  cmp(2);
> >>> -  cmp(3);
> >>> -  if ((length-=4))
> >>> +/*  size_t l= *compare_length / sizeof(uint64_t);
> >>> +  uint64_t *aa= (uint64_t*)*a;
> >>> +  uint64_t *bb= (uint64_t*)*b;
> >>> +  while(l--)
> >>>    {
> >>> -    first+=4;
> >>> -    last+=4;
> >>> -    goto loop;
> >>> -  }
> >>> -  return (0);
> >>> -}
> >>> -
> >>> -
> >>> -static int ptr_compare_1(size_t *compare_length,unsigned char **a,
> >>> unsigned char **b) -{
> >>> -  register int length= *compare_length-1;
> >>> -  register unsigned char *first,*last;
> >>> -
> >>> -  first= *a+1; last= *b+1;
> >>> -  cmp(-1);
> >>> - loop:
> >>> -  cmp(0);
> >>> -  cmp(1);
> >>> -  cmp(2);
> >>> -  cmp(3);
> >>> -  if ((length-=4))
> >>> -  {
> >>> -    first+=4;
> >>> -    last+=4;
> >>> -    goto loop;
> >>> -  }
> >>> -  return (0);
> >>> -}
> >>> -
> >>> -static int ptr_compare_2(size_t *compare_length,unsigned char **a,
> >>> unsigned char **b) -{
> >>> -  register int length= *compare_length-2;
> >>> -  register unsigned char *first,*last;
> >>> -
> >>> -  first= *a +2 ; last= *b +2;
> >>> -  cmp(-2);
> >>> -  cmp(-1);
> >>> - loop:
> >>> -  cmp(0);
> >>> -  cmp(1);
> >>> -  cmp(2);
> >>> -  cmp(3);
> >>> -  if ((length-=4))
> >>> -  {
> >>> -    first+=4;
> >>> -    last+=4;
> >>> -    goto loop;
> >>> +    if(*aa != *bb)
> >>> +    {
> >>> +      if(*aa < *bb)
> >>> + return -1;
> >>> +      else
> >>> + return 1;
> >>> +    }
> >>> +    aa++, bb++;
> >>>    }
> >>> -  return (0);
> >>> +  return 0;
> >>> +*/  return memcmp(*a, *b, *compare_length);
> >>>  }
> >>>
> >>> -static int ptr_compare_3(size_t *compare_length,unsigned char **a,
> >>> unsigned char **b) -{
> >>> -  register int length= *compare_length-3;
> >>> -  register unsigned char *first,*last;
> >>> -
> >>> -  first= *a +3 ; last= *b +3;
> >>> -  cmp(-3);
> >>> -  cmp(-2);
> >>> -  cmp(-1);
> >>> - loop:
> >>> -  cmp(0);
> >>> -  cmp(1);
> >>> -  cmp(2);
> >>> -  cmp(3);
> >>> -  if ((length-=4))
> >>> -  {
> >>> -    first+=4;
> >>> -    last+=4;
> >>> -    goto loop;
> >>> -  }
> >>> -  return (0);
> >>> -}
> >>>
> >>>  void my_store_ptr(unsigned char *buff, size_t pack_length, my_off_t
> >>> pos) {
> >>>
> >>>
> >>> For those interested, i started with the code at
> >>> http://gcc.gnu.org/ml/gcc/2002-10/msg01666.html
> >>>
> >>> and ended up with something like this:
> >>>
> >>> #include <sys/resource.h>
> >>> #include <sys/time.h>
> >>> #include <stdio.h>
> >>> #include <assert.h>
> >>> #include <stdlib.h>
> >>>
> >>> char s1[256];
> >>> char s2[256];
> >>>
> >>> int cmpsize= 240;
> >>>
> >>> int
> >>> speed_memcmp ()
> >>> {
> >>>   return memcmp (s1, s2, cmpsize);
> >>> }
> >>>
> >>> int
> >>> speed_bimemcmp ()
> >>> {
> >>>   return __builtin_memcmp (s1, s2, cmpsize);
> >>> }
> >>>
> >>> int
> >>> speed_loop ()
> >>> {
> >>>   int i=cmpsize;
> >>>   char *a= s1;
> >>>   char *b= s2;
> >>>   while(i--)
> >>>   {
> >>>     if(*a != *b)
> >>>       return -1;
> >>>     a++, b++;
> >>>   };
> >>>   return 0;
> >>> }
> >>>
> >>> int
> >>> speed_loop32 ()
> >>> {
> >>>   int i=cmpsize/4;
> >>>   int *a= (int*)s1;
> >>>   int *b= (int*)s2;
> >>>   while(i--)
> >>>   {
> >>>     if(*a != *b)
> >>>       return -1;
> >>>     a++, b++;
> >>>   };
> >>>   return 0;
> >>> }
> >>>
> >>> int
> >>> speed_loop64 ()
> >>> {
> >>>   int i=cmpsize/8;
> >>>   long long *a= (long long*)s1;
> >>>   long long *b= (long long*)s2;
> >>>   while(i--)
> >>>   {
> >>>     if(*a != *b)
> >>>       return -1;
> >>>     a++, b++;
> >>>   };
> >>>
> >>>   return 0;
> >>> }
> >>>
> >>> int speed_null()
> >>> {
> >>>   return 0;
> >>> }
> >>>
> >>>
> >>> double
> >>> do_test (int repetitions, int (*test_function) ())
> >>> {
> >>>   struct rusage r1, r2;
> >>>
> >>>   getrusage(RUSAGE_SELF, &r1);
> >>>
> >>>   while (repetitions--)
> >>>     test_function ();
> >>>
> >>>   getrusage(RUSAGE_SELF, &r2);
> >>>   return (r2.ru_utime.tv_sec - r1.ru_utime.tv_sec) +
> >>>    (r2.ru_utime.tv_usec - r1.ru_utime.tv_usec) / 1000000.0;
> >>> }
> >>>
> >>> main(int argc, char **argv)
> >>> {
> >>>   int repetitions = (argc == 1) ? 0x0fffffff : atoi(argv[1]);
> >>>   cmpsize = (argc == 2) ? 240 : atoi(argv[2]);
> >>>
> >>>   memset(s1, 42, 256);
> >>>   memset(s2, 42, 256);
> >>>   memset(s2+(cmpsize/2), 55, cmpsize/2);
> >>>
> >>>   printf ("%d repetitions\n\n", repetitions);
> >>>   printf ("Testing memcmp .....");
> >>>   fflush (stdout);
> >>>   printf (" done, %10.3f seconds\n", do_test (repetitions,
> >>> speed_memcmp));
> >>>
> >>>   printf ("Testing builtin memcmp .......");
> >>>   fflush (stdout);
> >>>   printf (" done, %10.3f seconds\n", do_test (repetitions,
> >>> speed_bimemcmp));
> >>>
> >>>   printf ("Testing loop ....");
> >>>   fflush (stdout);
> >>>   printf (" done, %10.3f seconds\n", do_test (repetitions,
> >>> speed_loop));
> >>>
> >>>   printf ("Testing loop32 ....");
> >>>   fflush (stdout);
> >>>   printf (" done, %10.3f seconds\n", do_test (repetitions,
> >>> speed_loop32));
> >>>
> >>>   printf ("Testing loop64 ....");
> >>>   fflush (stdout);
> >>>   printf (" done, %10.3f seconds\n", do_test (repetitions,
> >>> speed_loop64));
> >>>
> >>>   printf ("Testing no-op ....");
> >>>   fflush (stdout);
> >>>   printf (" done, %10.3f seconds\n", do_test (repetitions,
> >>> speed_null));
> >>>
> >>>   exit (0);
> >>> }
> >>
> >> _______________________________________________
> >> Mailing list: https://launchpad.net/~drizzle-discuss
> >> Post to     : [email protected]
> >> Unsubscribe : https://launchpad.net/~drizzle-discuss
> >> More help   : https://help.launchpad.net/ListHelp
> >
> > _______________________________________________
> > Mailing list: https://launchpad.net/~drizzle-discuss
> > Post to     : [email protected]
> > Unsubscribe : https://launchpad.net/~drizzle-discuss
> > More help   : https://help.launchpad.net/ListHelp


_______________________________________________
Mailing list: https://launchpad.net/~drizzle-discuss
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~drizzle-discuss
More help   : https://help.launchpad.net/ListHelp

Reply via email to