I think updating an atomic value this way inside a thread is not good (the sum doesn't look good sometimes)
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 );
};
std::vector<std::thread> threads(DynamicConfig::threads);
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();
}
while using a lock guard seems to be ok
std::atomic<double> e(0);
std::mutex m;
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];
}
{
const std::lock_guard<std::mutex> lock(m);
acc.store( acc.load() + ee );
}
};
std::vector<std::thread> threads(DynamicConfig::threads);
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();
}
Am I right, what am I missing here ? is the std::ref(e) the issue ?
Aucun commentaire:
Enregistrer un commentaire