From e2f231b345801a670b9e817c1248c7ae53bdd96d Mon Sep 17 00:00:00 2001 From: Brian Demsky Date: Thu, 14 Mar 2013 00:24:25 -0700 Subject: [PATCH] optimizations to mpmc-queue yield placement simpler test case for concurrent readers/writers of mpmc-queue --- bench.sh | 2 ++ mpmc-queue/Makefile | 6 ++++-- mpmc-queue/mpmc-queue.cc | 28 ++++++++++++++++++++++++++-- mpmc-queue/mpmc-queue.h | 4 ++++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/bench.sh b/bench.sh index 94d041f..88f114b 100755 --- a/bench.sh +++ b/bench.sh @@ -23,6 +23,8 @@ TESTS+=" spsc-bugfix/spsc-queue" TESTS+=" dekker-fences/dekker-fences" TESTS+=" mpmc-queue/mpmc-2r1w" TESTS+=" mpmc-queue/mpmc-1r2w-noinit" +TESTS+=" mpmc-queue/mpmc-queue-rdwr" +TESTS+=" mpmc-queue/mpmc-rdwr-noinit" TESTS+=" mpmc-queue/mpmc-queue-noinit" TESTS+=" linuxrwlocks/linuxrwlocks" diff --git a/mpmc-queue/Makefile b/mpmc-queue/Makefile index 472b794..cfd4fee 100644 --- a/mpmc-queue/Makefile +++ b/mpmc-queue/Makefile @@ -1,17 +1,19 @@ include ../benchmarks.mk TESTNAME = mpmc-queue -TESTS = mpmc-queue mpmc-1r2w mpmc-2r1w -TESTS += mpmc-queue-noinit mpmc-1r2w-noinit mpmc-2r1w-noinit +TESTS = mpmc-queue mpmc-1r2w mpmc-2r1w mpmc-queue-rdwr +TESTS += mpmc-queue-noinit mpmc-1r2w-noinit mpmc-2r1w-noinit mpmc-rdwr-noinit all: $(TESTS) mpmc-queue: CPPFLAGS += -DCONFIG_MPMC_READERS=2 -DCONFIG_MPMC_WRITERS=2 +mpmc-queue-rdwr: CPPFLAGS += -DCONFIG_MPMC_READERS=0 -DCONFIG_MPMC_WRITERS=0 -DCONFIG_MPMC_RDWR=2 mpmc-1r2w: CPPFLAGS += -DCONFIG_MPMC_READERS=1 -DCONFIG_MPMC_WRITERS=2 mpmc-2r1w: CPPFLAGS += -DCONFIG_MPMC_READERS=2 -DCONFIG_MPMC_WRITERS=1 mpmc-queue-noinit: CPPFLAGS += -DCONFIG_MPMC_READERS=2 -DCONFIG_MPMC_WRITERS=2 -DCONFIG_MPMC_NO_INITIAL_ELEMENT mpmc-1r2w-noinit: CPPFLAGS += -DCONFIG_MPMC_READERS=1 -DCONFIG_MPMC_WRITERS=2 -DCONFIG_MPMC_NO_INITIAL_ELEMENT mpmc-2r1w-noinit: CPPFLAGS += -DCONFIG_MPMC_READERS=2 -DCONFIG_MPMC_WRITERS=1 -DCONFIG_MPMC_NO_INITIAL_ELEMENT +mpmc-rdwr-noinit: CPPFLAGS += -DCONFIG_MPMC_READERS=0 -DCONFIG_MPMC_WRITERS=0 -DCONFIG_MPMC_RDWR=2 -DCONFIG_MPMC_NO_INITIAL_ELEMENT $(TESTS): $(TESTNAME).cc $(TESTNAME).h $(CXX) -o $@ $< $(CPPFLAGS) $(LDFLAGS) diff --git a/mpmc-queue/mpmc-queue.cc b/mpmc-queue/mpmc-queue.cc index baca598..b62d8d3 100644 --- a/mpmc-queue/mpmc-queue.cc +++ b/mpmc-queue/mpmc-queue.cc @@ -24,8 +24,21 @@ void threadB(struct mpmc_boundq_1_alt *queue) } } +void threadC(struct mpmc_boundq_1_alt *queue) +{ + int32_t *bin = queue->write_prepare(); + store_32(bin, 1); + queue->write_publish(); + + while (bin = queue->read_fetch()) { + printf("Read: %d\n", load_32(bin)); + queue->read_consume(); + } +} + #define MAXREADERS 3 #define MAXWRITERS 3 +#define MAXRDWR 3 #ifdef CONFIG_MPMC_READERS #define DEFAULT_READERS (CONFIG_MPMC_READERS) @@ -39,7 +52,13 @@ void threadB(struct mpmc_boundq_1_alt *queue) #define DEFAULT_WRITERS 2 #endif -int readers = DEFAULT_READERS, writers = DEFAULT_WRITERS; +#ifdef CONFIG_MPMC_RDWR +#define DEFAULT_RDWR (CONFIG_MPMC_RDWR) +#else +#define DEFAULT_RDWR 0 +#endif + +int readers = DEFAULT_READERS, writers = DEFAULT_WRITERS, rdwr = DEFAULT_RDWR; void print_usage() { @@ -84,7 +103,7 @@ void process_params(int argc, char **argv) int user_main(int argc, char **argv) { struct mpmc_boundq_1_alt queue; - thrd_t A[MAXWRITERS], B[MAXREADERS]; + thrd_t A[MAXWRITERS], B[MAXREADERS], C[MAXRDWR]; /* Note: optarg() / optind is broken in model-checker - workaround is * to just copy&paste this test a few times */ @@ -105,10 +124,15 @@ int user_main(int argc, char **argv) for (int i = 0; i < readers; i++) thrd_create(&B[i], (thrd_start_t)&threadB, &queue); + for (int i = 0; i < rdwr; i++) + thrd_create(&C[i], (thrd_start_t)&threadC, &queue); + for (int i = 0; i < writers; i++) thrd_join(A[i]); for (int i = 0; i < readers; i++) thrd_join(B[i]); + for (int i = 0; i < rdwr; i++) + thrd_join(C[i]); printf("Threads complete\n"); diff --git a/mpmc-queue/mpmc-queue.h b/mpmc-queue/mpmc-queue.h index dc2b561..918415f 100644 --- a/mpmc-queue/mpmc-queue.h +++ b/mpmc-queue/mpmc-queue.h @@ -38,6 +38,8 @@ public: if ( m_rdwr.compare_exchange_weak(rdwr,rdwr+(1<<16),mo_acq_rel) ) break; + else + thrd_yield(); } // (*1) @@ -69,6 +71,8 @@ public: if ( m_rdwr.compare_exchange_weak(rdwr,(rd<<16) | ((wr+1)&0xFFFF),mo_acq_rel) ) break; + else + thrd_yield(); } // (*1) -- 2.34.1