From 9516618923f915d3dcf1d19ed19fe1c96f8bd38f Mon Sep 17 00:00:00 2001 From: Umar Farooq Date: Wed, 28 Sep 2016 17:58:09 +0200 Subject: [PATCH] Replace rdtscp with rdtsc for older CPU version testing --- mpmc_test_fib.c | 42 ++++++++++++++---------------- spsc_test_fib.c | 64 +++++++++++++++++++++------------------------- spsc_ub_test_fib.c | 31 ++++++++++------------ 3 files changed, 62 insertions(+), 75 deletions(-) diff --git a/mpmc_test_fib.c b/mpmc_test_fib.c index 8bbfd67..7b5e5f1 100644 --- a/mpmc_test_fib.c +++ b/mpmc_test_fib.c @@ -36,8 +36,8 @@ uint64_t thread_get_id() __attribute__((always_inline)) static inline uint64_t rdtscp() { uint64_t tsc; - - __asm__ ("rdtscp;" + /** @todo not recommended to use rdtsc on multicore machine */ + __asm__ ("rdtsc;" "shl $32, %%rdx;" "or %%rdx,%%rax" : "=a" (tsc) @@ -58,7 +58,7 @@ int fibs[N]; int producer(void *ctx) { - printf("producer\n"); //DELETEME + //printf("producer\n"); //DELETEME struct mpmc_queue *q = (struct mpmc_queue *) ctx; srand((unsigned) time(0) + thread_get_id()); @@ -79,7 +79,7 @@ int producer(void *ctx) void *fibptr = (void *) &fibs[count]; if (!mpmc_queue_push(q, fibptr)) { - printf("Queue push failed\n"); + printf("Queue push failed at count %lu\n", count); return -1; } @@ -91,7 +91,7 @@ int producer(void *ctx) int consumer(void *ctx) { - printf("consumer\n"); //DELETEME + //printf("consumer\n"); //DELETEME struct mpmc_queue *q = (struct mpmc_queue *) ctx; srand((unsigned) time(0) + thread_get_id()); @@ -129,17 +129,18 @@ int consumer(void *ctx) int test_single_threaded(struct mpmc_queue *q) { int resp, resc; + g_start = 1; resp = producer(q); if (resp) - printf("Enqueuing failed"); + printf("Enqueuing failed\n"); resc = consumer(q); if (resc) - printf("Consumer failed"); + printf("Consumer failed\n"); if (resc || resp) - printf("Single Thread Test Failed"); + printf("Single Thread Test Failed\n"); else printf("Single Thread Test Complete\n"); @@ -151,42 +152,37 @@ int test_multi_threaded(struct mpmc_queue *q) thrd_t thrp, thrc; int resp, resc; + g_start = 0; + thrd_create(&thrp, consumer, q); /** @todo Why producer thread runs earlier? */ thrd_create(&thrc, producer, q); sleep(1); - long long starttime, endtime; - struct timespec start, end; - - if(clock_gettime(CLOCK_REALTIME, &start)) - return -1; + uint64_t start_tsc_time, end_tsc_time; + start_tsc_time = rdtscp(); g_start = 1; thrd_join(thrp, &resp); thrd_join(thrc, &resc); - if(clock_gettime(CLOCK_REALTIME, &end)) - return -1; - - starttime = start.tv_sec*1000000000LL + start.tv_nsec; - endtime = end.tv_sec*1000000000LL + end.tv_nsec; + end_tsc_time = rdtscp(); if (resc || resp) - printf("Queue Test failed"); + printf("Queue Test failed\n"); else printf("Two-thread Test Complete\n"); - printf("cycles/op = %lld\n", (endtime - starttime) / N ); - + printf("cycles/op for rdtsc %lu\n", (end_tsc_time - start_tsc_time)/N); + size_t used = mpmc_queue_available(q); if (used > 0) printf("%zu slots in use? There is something wrong with the test\n", used); int ret = mpmc_queue_destroy(q); if (ret) - printf("Failed to destroy queue: %d", ret); + printf("Failed to destroy queue: %d\n", ret); return 0; } @@ -195,7 +191,7 @@ int main() { struct mpmc_queue q; mpmc_queue_init(&q, 1<<20, &memtype_heap); /** @todo change size>1 in case of bounded queue impl. memtype_hugepage impl for un_spsc */ - + test_multi_threaded(&q); return 0; diff --git a/spsc_test_fib.c b/spsc_test_fib.c index 01aa62d..ae65133 100644 --- a/spsc_test_fib.c +++ b/spsc_test_fib.c @@ -36,8 +36,8 @@ uint64_t thread_get_id() __attribute__((always_inline)) static inline uint64_t rdtscp() { uint64_t tsc; - - __asm__ ("rdtscp;" + /** @todo not recommended to use rdtsc on multicore machine */ + __asm__ ("rdtsc;" "shl $32, %%rdx;" "or %%rdx,%%rax" : "=a" (tsc) @@ -58,7 +58,7 @@ int fibs[N]; int producer(void *ctx) { - printf("producer\n"); + //printf("producer\n"); //DELETEME struct spsc_queue *q = (struct spsc_queue *) ctx; srand((unsigned) time(0) + thread_get_id()); @@ -79,10 +79,10 @@ int producer(void *ctx) void *fibptr = (void *) &fibs[count]; if (!spsc_queue_push(q, fibptr)) { - printf("Queue push failed at count %lu\n", count); + printf("Queue push failed at count %lu, %d\n", count, 1<<20); return -1; } - + n1 = n2; n2 = fibs[count]; } @@ -91,7 +91,7 @@ int producer(void *ctx) int consumer(void *ctx) { - printf("consumer\n"); + //printf("consumer\n"); //DELETEME struct spsc_queue *q = (struct spsc_queue *) ctx; srand((unsigned) time(0) + thread_get_id()); @@ -101,7 +101,7 @@ int consumer(void *ctx) while (g_start == 0) thrd_yield(); - /* Wait for a random time */ + /* Wait for a random time */ for (size_t i = 0; i != pause; i += 1) nop(); @@ -118,7 +118,7 @@ int consumer(void *ctx) if (*pulled != fib) { printf("Pulled != fib\n"); return -1; - } + } n1 = n2; n2 = fib; } @@ -129,9 +129,7 @@ int consumer(void *ctx) int test_single_threaded(struct spsc_queue *q) { int resp, resc; - g_start = 1; - resp = producer(q); if (resp) printf("Enqueuing failed\n"); @@ -150,51 +148,36 @@ int test_single_threaded(struct spsc_queue *q) int test_multi_threaded(struct spsc_queue *q) { - g_start = 0; - thrd_t thrp, thrc; int resp, resc; + g_start = 0; + thrd_create(&thrp, consumer, q); /** @todo Why producer thread runs earlier? */ thrd_create(&thrc, producer, q); sleep(1); - long long starttime, endtime; - struct timespec start, end; - if(clock_gettime(CLOCK_REALTIME, &start)) - return -1; + uint64_t start_tsc_time, end_tsc_time; + start_tsc_time = rdtscp(); g_start = 1; thrd_join(thrp, &resp); thrd_join(thrc, &resc); - if(clock_gettime(CLOCK_REALTIME, &end)) - return -1; + end_tsc_time = rdtscp(); if (resc || resp) printf("Queue Test failed\n"); else printf("Two-thread Test Complete\n"); - - starttime = start.tv_sec*1000000000LL + start.tv_nsec; - endtime = end.tv_sec*1000000000LL + end.tv_nsec; - printf("cycles/op = %lld\n", (endtime - starttime) / N ); - - if (spsc_queue_available(q) != q->capacity) - printf("slots in use? There is something wrong with the test %d\n", spsc_queue_available(q)); - - return 0; -} -int main() -{ - struct spsc_queue * q = NULL; - q = spsc_queue_init(q, 1<<20, &memtype_heap); - - //test_single_threaded(q); /** Single threaded test fails with N > queue size*/ - test_multi_threaded(q); + printf("cycles/op for rdtsc %lu\n", (end_tsc_time - start_tsc_time)/N); + + size_t used = spsc_queue_available(q); + if (spsc_queue_available(q) != q->capacity) + printf("%zu slots in use? There is something wrong with the test\n", used); int ret = spsc_queue_destroy(q); if (ret) @@ -202,3 +185,14 @@ int main() return 0; } + +int main() +{ + struct spsc_queue* q = NULL; + q = spsc_queue_init(q, 1<<20, &memtype_heap); + + test_multi_threaded(q); + //test_single_threaded(q); /** Single threaded test fails with N > queue size*/ + + return 0; +} diff --git a/spsc_ub_test_fib.c b/spsc_ub_test_fib.c index 5464333..78ddabd 100644 --- a/spsc_ub_test_fib.c +++ b/spsc_ub_test_fib.c @@ -36,8 +36,8 @@ uint64_t thread_get_id() __attribute__((always_inline)) static inline uint64_t rdtscp() { uint64_t tsc; - - __asm__ ("rdtscp;" + /** @todo not recommended to use rdtsc on multicore machine */ + __asm__ ("rdtsc;" "shl $32, %%rdx;" "or %%rdx,%%rax" : "=a" (tsc) @@ -132,14 +132,14 @@ int test_single_threaded(struct spsc_ub_queue *q) resp = producer(q); if (resp) - printf("Enqueuing failed"); + printf("Enqueuing failed\n"); resc = consumer(q); if (resc) - printf("Consumer failed"); + printf("Consumer failed\n"); if (resc || resp) - printf("Single Thread Test Failed"); + printf("Single Thread Test Failed\n"); else printf("Single Thread Test Complete\n"); @@ -151,39 +151,36 @@ int test_multi_threaded(struct spsc_ub_queue *q) thrd_t thrp, thrc; int resp, resc; + g_start = 0; + thrd_create(&thrp, consumer, q); /** @todo Why producer thread runs earlier? */ thrd_create(&thrc, producer, q); sleep(1); - long long starttime, endtime; - struct timespec start, end; - if(clock_gettime(CLOCK_REALTIME, &start)) - return -1; + uint64_t start_tsc_time, end_tsc_time; + start_tsc_time = rdtscp(); g_start = 1; thrd_join(thrp, &resp); thrd_join(thrc, &resc); - if(clock_gettime(CLOCK_REALTIME, &end)) - return -1; + end_tsc_time = rdtscp(); if (resc || resp) - printf("Queue Test failed"); + printf("Queue Test failed\n"); else printf("Two-thread Test Complete\n"); - - starttime = start.tv_sec*1000000000LL + start.tv_nsec; - endtime = end.tv_sec*1000000000LL + end.tv_nsec; - printf("cycles/op = %lld\n", (endtime - starttime) / N ); + + printf("cycles/op for rdtsc %lu\n", (end_tsc_time - start_tsc_time)/N); if (q->_tail->_next != NULL) printf("slots in use? There is something wrong with the test\n"); int ret = spsc_ub_queue_destroy(q); if (ret) - printf("Failed to destroy queue: %d", ret); + printf("Failed to destroy queue: %d\n", ret); return 0; }