#include #include #include #include #include #include #include #include #include #include #include #include static inline uint64_t rdtsc(void) { uint32_t low, high; __asm__ __volatile__("rdtsc" : "=a"(low), "=d"(high)); return low | ((uint64_t) high) << 32; } void * mmapfile( const char * filename, uint64_t len ) { int perms = 0666; int open_flag = O_RDWR | O_CREAT; int mmap_flags = PROT_READ | PROT_WRITE; const int fd = open(filename, open_flag, perms); if (fd < 0) goto fail; // Ensure that the file is empty and the right size if (ftruncate(fd, 0) < 0) goto fail; if (ftruncate(fd, len) < 0) goto fail; // Map the entire actual length of the file void * const base = mmap( NULL, len, mmap_flags, MAP_SHARED | MAP_POPULATE, fd, 0 ); if (base == MAP_FAILED) goto fail; close(fd); return base; fail: err(1, "%s: Unable to map %"PRIu64" bytes", filename, len); } int main( int argc, char ** argv ) { const char * filename = argv[1]; const uint64_t len = argc > 2 ? strtoul(argv[2], NULL, 0) : (5ul << 30); const uint64_t max_index = len / sizeof(uint64_t); uint64_t mmap_time = -rdtsc(); uint64_t * const buf = mmapfile(filename, len); mmap_time += rdtsc(); fprintf(stderr, "%s: mapped %"PRIu64" bytes in %"PRIu64" ticks\n", filename, len, mmap_time ); while (1) { uint64_t max = 0; uint64_t sum = 0; uint64_t i; const uint64_t loop_start = rdtsc(); const uint64_t iters = 1 << 30; uint64_t start = loop_start; for (i = 0 ; i < iters ; i++) { uint64_t i = lrand48() % max_index; buf[i] += start; uint64_t end = rdtsc(); const uint64_t delta = end - start; start = end; sum += delta; if (delta > max) max = delta; // Force a report every 10 billion ticks ~= 3 seconds if (end - loop_start > 10e9) break; } printf("%"PRIu64": avg %"PRIu64" max %"PRIu64" ticks\n", i, i ? sum / i : 0, max ); } return 0; }