#include #include #include #include #include #include #define BLCKSZ 8192 #define LOOPS 1000 static inline bool allzeros_char(const void *ptr, size_t len) { const char *p = (const char *) ptr; for (size_t i = 0; i < len; i++) { if (p[i] != 0) return false; } return true; } static inline bool allzeros_size_t(const void *ptr, size_t len) { const size_t *p = (const size_t *) ptr; for (size_t i = 0; i < len / sizeof(size_t); i++) { if (p[i] != 0) return false; } return true; } bool pg_memory_is_all_zeros(const void *ptr, size_t len) { const char *p = (const char *) ptr; const char *end = &p[len]; #ifdef RANIERS_OPTIMIZATION const char *aligned_end; #else const char *aligned_end = (const char *) ((uintptr_t) end & (~(sizeof(size_t) - 1))); #endif while (((uintptr_t) p & (sizeof(size_t) - 1)) != 0) { if (p == end) return true; if (*p++ != 0) return false; } #ifdef RANIERS_OPTIMIZATION aligned_end = (const char *) ((uintptr_t) end & (~(sizeof(size_t) - 1))); #endif for (; p < aligned_end; p += sizeof(size_t)) { if (*(size_t *) p != 0) return false; } while (p < end) { if (*p++ != 0) return false; } return true; } #define NANOSEC_PER_SEC 1000000000 // Returns difference in nanoseconds int64_t get_clock_diff(struct timespec *t1, struct timespec *t2) { int64_t nanosec = (t1->tv_sec - t2->tv_sec) * NANOSEC_PER_SEC; nanosec += (t1->tv_nsec - t2->tv_nsec); return nanosec; } int main() { size_t pagebytes[BLCKSZ] = {0}; volatile bool result; struct timespec start,end; int64_t char_time, size_t_time; clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); for (int i = 0; i < LOOPS; i++) { result = allzeros_char(pagebytes, BLCKSZ); } clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); char_time = get_clock_diff(&end, &start); printf("char: done in %ld nanoseconds\n", char_time); #if TEST_PRE_ALIGNED_VERSION clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); for (int i = 0; i < LOOPS; i++) { result = allzeros_size_t(pagebytes, BLCKSZ); } clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); size_t_time = get_clock_diff(&end, &start); printf("size_t: done in %ld nanoseconds (%g times faster than char)\n", size_t_time, (double) char_time / size_t_time); #endif clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start); for (int i = 0; i < LOOPS; i++) { result = pg_memory_is_all_zeros(pagebytes, BLCKSZ); } clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end); size_t_time = get_clock_diff(&end, &start); printf("size_t: done in %ld nanoseconds (%g times faster than char)\n", size_t_time, (double) char_time / size_t_time); return 0; }