TBB Parallel_for 计数,增量变量不准确

TBB Parallel_for count, increment variable inaccurate

我知道在并行进程中,如果不加以适当注意,您可能会出现竞争条件,其中一个线程修改了另一个线程正在访问的变量,从而导致各种错误等。

我正在尝试编写使用 'parallel_for'、全局变量 'count' 和递增条件 'count' 的代码。

一旦满足条件,我就从并行 for 中调用 count++。

为了数据验证,我设置了一个 parallel_reduce,它也检查相同的条件,但我收到了不同的结果,这比我用 parallel_for 得到的结果要高,这就是我知道的原因parallel_for 导致了这个问题。

我认为使用 'count++' 仍然会导致竞争条件是否正确,因为我最初的假设是 count++ 会起作用,因为我从不存储值,只是在时间点上,说只需将 'count' 加 1 即可。 如果可能,我想尝试避免使用互斥锁或锁。

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++;
                }
            }
        }
    });

tbb::parallel_for 假定循环体是线程安全的,即没有竞争。在这种情况下,它确实存在竞争,因为它在没有同步的情况下修改了一个全局变量。修改只是 "whatever the current value is" 的增量这一事实并不重要,它仍然是一场竞赛(例如,某些硬件可能将 ++ 实现为从内存读取值到寄存器,更改寄存器,写回新值记忆)。

为了修复此代码,请将 count 声明为原子变量:std::atomic<int> 如果您使用 C++11,或 tbb::atomic<int> 对于早期版本的语言。