Skip to content

Instantly share code, notes, and snippets.

@jsnyder
Created May 26, 2010 19:34
Show Gist options
  • Save jsnyder/414938 to your computer and use it in GitHub Desktop.
Save jsnyder/414938 to your computer and use it in GitHub Desktop.
#include <mach/mach_time.h>
#include <time.h>
#include <stdio.h>
#define DUFF_DEVICE_8(aCount, aAction) \
do { \
int count_ = (aCount); \
int times_ = (count_ + 7) >> 3; \
switch (count_ & 7){ \
case 0: do { aAction; \
case 7: aAction; \
case 6: aAction; \
case 5: aAction; \
case 4: aAction; \
case 3: aAction; \
case 2: aAction; \
case 1: aAction; \
} while (--times_ > 0); \
} \
} while (0)
void mach_absolute_difference(uint64_t end, uint64_t start, struct timespec *tp) {
uint64_t difference = end - start;
static mach_timebase_info_data_t info = {0,0};
if (info.denom == 0)
mach_timebase_info(&info);
uint64_t elapsednano = difference * (info.numer / info.denom);
tp->tv_sec = elapsednano * 1e-9;
tp->tv_nsec = elapsednano - (tp->tv_sec * 1e9);
}
void *simplememset(void *_p, unsigned v, unsigned count)
{
unsigned char *p = _p;
while(count-- > 0) *p++ = v;
return _p;
}
void *duffmemset(void *_p, unsigned v, unsigned count)
{
register n = (count + 7) / 8; /* count > 0 assumed */
unsigned char *p = _p;
switch (count % 8)
{
case 0: do {*p++ = v;
case 7: *p++ = v;
case 6: *p++ = v;
case 5: *p++ = v;
case 4: *p++ = v;
case 3: *p++ = v;
case 2: *p++ = v;
case 1: *p++ = v;
} while (--n > 0);
}
return _p;
}
int main(int argc, char *argv[])
{
uint64_t start,end;
struct timespec tp;
int rep;
int i;
int arraylen = atoi(argv[1]);
unsigned *array, *tmp;
printf("Array Length: %d\n", arraylen);
for( rep = 0; rep < 5; rep++ )
{
array = ( unsigned * )malloc( arraylen * sizeof( unsigned ) );
start = mach_absolute_time();
memset(array, 0, arraylen * sizeof( unsigned ));
end = mach_absolute_time();
mach_absolute_difference(end, start, &tp);
if( rep > 0 )
printf("Native: %lu seconds, %lu nanoseconds\n", tp.tv_sec, tp.tv_nsec);
free( array );
array = ( unsigned * )malloc( arraylen * sizeof( unsigned ) );
start = mach_absolute_time();
duffmemset(array, 0, arraylen);
//tmp = array;
//DUFF_DEVICE_8( arraylen, *tmp++ = 0 );
end = mach_absolute_time();
mach_absolute_difference(end, start, &tp);
if( rep > 0 )
printf("Duff: %lu seconds, %lu nanoseconds\n", tp.tv_sec, tp.tv_nsec);
free( array );
array = ( unsigned * )malloc( arraylen * sizeof( unsigned ) );
start = mach_absolute_time();
simplememset(array, 4, arraylen * sizeof( unsigned ) );
end = mach_absolute_time();
mach_absolute_difference(end, start, &tp);
if( rep > 0 )
printf("Simple: %lu seconds, %lu nanoseconds\n", tp.tv_sec, tp.tv_nsec);
free( array );
printf("\n");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment