multithreading - C++ threads: shared memory not updated despite absence of race -
multithreading - C++ threads: shared memory not updated despite absence of race -
i'm experimenting c++ standard threads. wrote little benchmark test performance overhead , overall throughput. principle run in 1 or several threads loop of 1 billion iterations, making little pause time time.
in first version used counters in shared memory (i.e. normal variables). exepected next output:
sequential 1e+009 loops 4703 ms 212630 loops/ms 2 thrds:t1 1e+009 loops 4734 ms 211238 loops/ms 2 thrds:t2 1e+009 loops 4734 ms 211238 loops/ms 2 thrds:tt 2e+009 loops 4734 ms 422476 loops/ms manythrd tn 1e+009 loops 7094 ms 140964 loops/ms ... manythrd tt 6e+009 loops 7094 ms 845785 loops/ms unfortunately display showed counters if uninitialised !
i solve issue storing end value of each counter in atomic<> later display. i not understand why version based on simple shared memory not work properly: each thread uses own counter, there no racing condition. display thread accesses counters after counting threads finished. using volatile did not help either.
could explain me unusual behaviour (as if memory not updated) , tell me if missed ?
here shared variables:
const int maxthread = 6; atomic<bool> other_finished = false; atomic<long> acounter[maxthread]; here code of threaded function:
void foo(long& count, int ic, long maxcount) { count = 0; while (count < maxcount) { count++; if (count % 10000000 == 0) this_thread::sleep_for(chrono::microseconds(1)); } other_finished = true; // atomic: announce work finished acounter[ic] = count; // atomic: share result } here illustration of how phone call benchmark threads:
mytimer.on(); // sec run, 2 threadeds thread t1(foo, counter[0], 0, maxcount); // additional thread foo(counter[1], 1, maxcount); // main thread t1.join(); // wait end of additional thread perf = mytimer.off(); display_perf("2 thrds:t1", counter[0], perf); // non atomic version of code display_perf("2 thrds:t2", counter[1], perf); display_perf("2 thrds:tt", counter[0] + counter[1], perf);
here simplified version reproduce problem:
void deep_thought(int& value) { value = 6 * 9; } int main() { int reply = 42; std::thread{deep_thought, answer).join(); homecoming answer; // 42 } it looks passing reference answer worker function, , assigning 6 * 9 reference , hence answer. however, constructor of std::thread makes re-create of answer , passes reference re-create worker function, , variable answer in main thread never changed.
both gcc-4.9 , clang-3.5 reject above code, because worker function can not invoked lvalue reference. can solve problem passing variable std::ref:
std::thread{deep_thought, std::ref(answer)}.join(); c++ multithreading c++11 benchmarking stdthread
Comments
Post a Comment