#include #include #include #include #include #include #define rdtscll(val) \ __asm__ __volatile__ ("rdtsc;" : "=A" (val)) #define SECS 3ULL volatile unsigned int count_array[1000] __attribute__((aligned(256))); int atomic = 0; unsigned long long delta = 0; void *loop(void *arg) { unsigned long long start, now, mhz = 525000000, limit = mhz * SECS, min = -1ULL, tmp; volatile unsigned int *count, offset = (int)arg; int j; printf("offset: %u (atomic: %d).\n", offset, atomic); count = (void *)count_array + offset; if (!arg) { for (j = 0; j < 10; j++) { limit = mhz/10; *count = 0; rdtscll(start); for (;;) { (*count)++; rdtscll(now); if (now - start > limit) break; } rdtscll(now); tmp = (now-start)/(*count); if (tmp < min) min = tmp; } printf("delta: %Ld\n", min); delta = min; } else while (!delta) usleep(100000); limit = mhz*SECS; repeat: *count = 0; rdtscll(start); if (atomic) for (;;) { asm ("lock; incl %0" : "=m" (*count) : "m" (*count)); rdtscll(now); if (now - start > limit) break; } else for (;;) { (*count)++; rdtscll(now); if (now - start > limit) break; } printf("speed: %Ld loops (%Ld cycles per iteration).\n", (*count)/SECS, (limit/(*count)-delta)); fflush(stdout); goto repeat; } int main (int argc, char **argv) { unsigned int nr_threads, i, ret, offset = 0; pthread_t *t; if (argc != 2 && argc != 3 && argc != 4) { usage: printf("usage: loop_print2 [] []\n"); exit(-1); } nr_threads = atol(argv[1]); if (!nr_threads) goto usage; t = calloc(nr_threads, sizeof(*t)); if (argc >= 3) offset = atol(argv[2]); if (offset < sizeof(unsigned int)) offset = sizeof(unsigned int); atomic = 0; if (argc >= 4) { atomic = atol(argv[3]); printf("a: %d\n", atomic); } for (i = 1; i < nr_threads; i++) { ret = pthread_create (t+i, NULL, loop, (void *)(i*offset)); if (ret) exit(-1); } loop((void *)0); return 0; }