Проблема в строке:
acc.store( acc.load() + ee );
есть 2 операции загрузки и сохранения, в промежутке между ними другой поток может изменить значение.
К сожалению, atomi c не поддерживает fetch_add.
Вы можете попробовать это:
auto atomic_fetch_add = [](std::atomic<double>* obj, double arg)
{
auto expected = obj->load();
while (!atomic_compare_exchange_weak(obj, &expected, expected + arg))
;
return expected;
};
std::atomic<double> e(0);
auto worker = [&] (size_t begin, size_t end, std::atomic<double> & acc) {
double ee = 0;
for(auto k = begin; k != end; ++k) {
ee += something[k];
}
// acc.store( acc.load() + ee );
atomic_fetch_add(&acc, ee);
};
std::vector<std::thread> threads(nbThreads);
const size_t grainsize = miniBatchSize / nbThreads;
size_t work_iter = 0;
for(auto it = std::begin(threads); it != std::end(threads) - 1; ++it) {
*it = std::thread(worker, work_iter, work_iter + grainsize, std::ref(e));
work_iter += grainsize;
}
threads.back() = std::thread(worker, work_iter, miniBatchSize, std::ref(e));
for(auto&& i : threads) {
i.join();
}
Хотя нет никакой гарантии, что atomi c не использует мьютексы, поэтому вы ' Я должен проверить вашу реализацию.