Created
May 26, 2010 19:34
-
-
Save jsnyder/414938 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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