/** * This code is released under a BSD License. */ #include #include #include #include #include "simdcomp.h" #ifdef _MSC_VER # include __int64 freq; typedef __int64 time_snap_t; static time_snap_t time_snap(void) { __int64 now; QueryPerformanceCounter((LARGE_INTEGER *)&now); return (__int64)((now*1000000)/freq); } # define TIME_SNAP_FMT "%I64d" #else # define time_snap clock # define TIME_SNAP_FMT "%lu" typedef clock_t time_snap_t; #endif void benchmarkSelect() { uint32_t buffer[128]; uint32_t backbuffer[128]; uint32_t initial = 33; uint32_t b; time_snap_t S1, S2, S3; int i; printf("benchmarking select \n"); /* this test creates delta encoded buffers with different bits, then * performs lower bound searches for each key */ for (b = 0; b <= 32; b++) { uint32_t prev = initial; uint32_t out[128]; /* initialize the buffer */ for (i = 0; i < 128; i++) { buffer[i] = ((uint32_t)(1655765 * i )) ; if(b < 32) buffer[i] %= (1< *ib) return 1; return 0; } /* adapted from wikipedia */ int binary_search(uint32_t * A, uint32_t key, int imin, int imax) { int imid; imax --; while(imin + 1 < imax) { imid = imin + ((imax - imin) / 2); if (A[imid] > key) { imax = imid; } else if (A[imid] < key) { imin = imid; } else { return imid; } } return imax; } /* adapted from wikipedia */ int lower_bound(uint32_t * A, uint32_t key, int imin, int imax) { int imid; imax --; while(imin + 1 < imax) { imid = imin + ((imax - imin) / 2); if (A[imid] >= key) { imax = imid; } else if (A[imid] < key) { imin = imid; } } if(A[imin] >= key) return imin; return imax; } void benchmarkSearch() { uint32_t buffer[128]; uint32_t backbuffer[128]; uint32_t out[128]; uint32_t result, initial = 0; uint32_t b, i; time_snap_t S1, S2, S3, S4; printf("benchmarking search \n"); /* this test creates delta encoded buffers with different bits, then * performs lower bound searches for each key */ for (b = 0; b <= 32; b++) { uint32_t prev = initial; /* initialize the buffer */ for (i = 0; i < 128; i++) { buffer[i] = ((uint32_t)rand()) ; if(b < 32) buffer[i] %= (1< 0) { if(buffer[pos-1] >= pseudorandomkey) printf("bug B.\n"); } } S2 = time_snap(); for (i = 0; i < 128 * 10; i++) { int pos; uint32_t pseudorandomkey = buffer[i%128]; simdunpackd1(initial, (__m128i *)out, backbuffer, b); pos = lower_bound(backbuffer, pseudorandomkey, 0, 128); result = backbuffer[pos]; if((result < pseudorandomkey) || (buffer[pos] != result)) { printf("bug C.\n"); } else if (pos > 0) { if(buffer[pos-1] >= pseudorandomkey) printf("bug D.\n"); } } S3 = time_snap(); for (i = 0; i < 128 * 10; i++) { int pos; uint32_t pseudorandomkey = buffer[i%128]; pos = simdsearchwithlengthd1(initial, (__m128i *)out, b, 128, pseudorandomkey, &result); if((result < pseudorandomkey) || (buffer[pos] != result)) { printf("bug A.\n"); } else if (pos > 0) { if(buffer[pos-1] >= pseudorandomkey) printf("bug B.\n"); } } S4 = time_snap(); printf("bit width = %d, fast search function time = " TIME_SNAP_FMT ", naive time = " TIME_SNAP_FMT " , fast with length time = " TIME_SNAP_FMT " \n", b, (S2-S1), (S3-S2), (S4-S3) ); } } int main() { #ifdef _MSC_VER QueryPerformanceFrequency((LARGE_INTEGER *)&freq); #endif benchmarkSearch(); benchmarkSelect(); return 0; }