我知道对于并行进程,如果没有适当的关注,你可以获得竞争条件,其中一个线程修改另一个正在访问的变量,导致各种错误等。
我正在尝试编写使用' parallel_for'的代码,这是一个全局变量' count'以及增加'计数的条件。
一旦条件满足,我从并行内部调用count ++。
用于数据验证我设置了一个parallel_reduce,它也检查相同的条件,并且我收到的结果不同于parallel_for的结果,这就是为什么我知道parallel_for导致问题的原因。
我是否正确地认为使用' count ++'仍然会导致竞争条件,因为我最初的假设是,计数++将起作用,因为我永远不会存储一个值,只是在时间点上,只是在任何'计数'是。 我想尽可能避免使用互斥锁或锁。
int count = 0;
parallel_for(blocked_range2d<int, int>(0, smallestHeight, 0, smallestWidth), [&](const blocked_range2d<int, int>&r) {
auto y1 = r.rows().begin();
auto y2 = r.rows().end();
auto x1 = r.cols().begin();
auto x2 = r.cols().end();
for (auto y = y1; y < y2; y++) {
for (auto x = x1; x < x2; x++) {
int pixelValue = rgbDiffVal[y][x].rgbRed + rgbDiffVal[y][x].rgbGreen + rgbDiffVal[y][x].rgbBlue;
if (pixelValue > bThreshold) {
count++;
}
}
}
});
答案 0 :(得分:3)
tbb::parallel_for
假设循环体是线程安全的,即没有种族。在这种情况下,它确实有竞争,因为它修改了一个没有同步的全局变量。修改只是“无论当前值是什么”的增量并不重要,它仍然是一个竞赛(例如,某些硬件可能实现++从内存中读取值来注册,更改寄存器,编写新的价值回到记忆中。)
为了修复此代码,请将count
声明为原子变量:std::atomic<int>
如果您使用C ++ 11,或tbb::atomic<int>
用于该语言的早期版本。