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

时间:2018-02-14 14:23:38

标签: c++ multithreading concurrency tbb

我知道对于并行进程,如果没有适当的关注,你可以获得竞争条件,其中一个线程修改另一个正在访问的变量,导致各种错误等。

我正在尝试编写使用' 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++;
                }
            }
        }
    });

1 个答案:

答案 0 :(得分:3)

tbb::parallel_for假设循环体是线程安全的,即没有种族。在这种情况下,它确实有竞争,因为它修改了一个没有同步的全局变量。修改只是“无论当前值是什么”的增量并不重要,它仍然是一个竞赛(例如,某些硬件可能实现++从内存中读取值来注册,更改寄存器,编写新的价值回到记忆中。)

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