TBB免费图像lambda阵列比较错误

TBB Free Image lambda array comparison error

本文关键字:比较 错误 阵列 lambda 免费 图像 TBB      更新时间:2023-10-16

我一直在使用Linux上的免费图像加上线程构建块。我一直在尝试比较从另一个图像中减去一个图像时的顺序和并行方法之间的速度,但是我注意到,使用并行方法时的最终结果会产生一些我不确定现在解决并需要一些建议的异常。

我的问题是:为什么图像在使用并行时似乎会生成更多数组比较错误,但使用顺序时工作正常(图像应该是黑色的,有几个白色斑点,因此第二张图像中的白色像素是2个图像像素阵列(类型rgbquad(之间的比较错误(。

rgbquads在呼吁这些方法之前声明并充当全局变量。

RGBQUAD rgb;    
RGBQUAD rgb2;

https://i.stack.imgur.com/qf8rs.jpg" sequential"。

for (auto y = 0; y < height; y++)
{
    for(auto x= 0; x < width; x++)
    {
        inputImage.getPixelColor(x, y, &rgb);
        inputImage2.getPixelColor(x, y, &rgb2);
        rgbDiffVal[y][x].rgbRed = abs(rgb.rgbRed - rgb2.rgbRed);
        rgbDiffVal[y][x].rgbBlue = abs(rgb.rgbBlue - rgb2.rgbBlue);
        rgbDiffVal[y][x].rgbGreen = abs(rgb.rgbGreen - rgb2.rgbGreen);
    }
}

https://i.stack.imgur.com/nzulz.jpg" with tbb Parallel"。

parallel_for(blocked_range2d<int,int>(0,height, 0, width), [&] (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++) {
            inputImage.getPixelColor(x, y, &rgb);
            inputImage2.getPixelColor(x, y, &rgb2);
            rgbDiffVal[y][x].rgbRed = abs(rgb.rgbRed - rgb2.rgbRed);
            rgbDiffVal[y][x].rgbBlue = abs(rgb.rgbBlue - rgb2.rgbBlue);
            rgbDiffVal[y][x].rgbGreen = abs(rgb.rgbGreen - rgb2.rgbGreen);
        }
    }
});

我相信这可能与传递参考指针在lambda中的传递有关,该指针无论如何都是通过参考复制值,因为这是我唯一能想到的可能会影响该过程的事情。(RGB,RGB2(。我已经观察到,如果我将阻塞范围的平行更改为高度和宽度,这将解决问题,但是这首先击败了使用并行方法的点。

我要做的第一件事是在更新周围放置一个旋转的mutex锁(内部循环的最后三行,您要存储结果。(很多,但是会告诉您您的更新是否存在同步问题。(这不是很明显,但是您将相邻值存储在同一缓存线上的某些结果。测试是回答此问题的唯一方法。(

如果是这样,您可以进行原子交换以更新结果,但这是超级廉价的。如果没有,对不起,我没有发现你的问题。

即使这不是问题,您也可以通过使用1-D blocked_range来获得更好的性能。我会留给您进行血腥的实现。

如果这些变量应该暂时存储像素颜色,也许您只需要将声明移至lambda中,从而使每个线程本地变量。 - Alexey Kukanov。

变量确实被放置在lambda的边界之外,因此每个线程正在修改引用变量,从而导致竞赛条件,其中一个线程将尝试从变量中读取数据,因为另一个线程正在修改它。