我有一个将拜耳图像通道转换为 RGB 的算法。在我的实现中,我有一个嵌套for
循环,它遍历拜耳通道,从拜耳索引计算 rgb 索引,然后从拜耳通道设置该像素的值。这里要注意的主要事情是每个像素都可以独立于其他像素进行计算(不依赖于先前的计算),因此该算法是并行化的自然候选者。然而,计算确实依赖于所有线程将同时访问但不会改变的一些预设数组。
但是,当我尝试将主要for
与 MS并行化时cuncurrency::parallel_for
,性能并没有得到任何提升。事实上,对于在 4 核 CPU 上运行的大小为 3264X2540 的输入,非并行版本的运行时间约为 34 毫秒,并行版本的运行时间约为 69 毫秒(平均超过 10 次运行)。我确认该操作确实是并行化的(为该任务创建了 3 个新线程)。
使用英特尔的编译器tbb::parallel_for
给出了接近准确的结果。作为比较,我从实现的算法开始,C#
其中我还使用了parallel_for
循环,在那里我遇到了接近 X4 的性能提升(我选择了这个算法,C++
因为C++
即使使用单核,这个特定任务也更快)。
有什么想法阻止我的代码很好地并行化吗?
我的代码:
template<typename T>
void static ConvertBayerToRgbImageAsIs(T* BayerChannel, T* RgbChannel, int Width, int Height, ColorSpace ColorSpace)
{
//Translates index offset in Bayer image to channel offset in RGB image
int offsets[4];
//calculate offsets according to color space
switch (ColorSpace)
{
case ColorSpace::BGGR:
offsets[0] = 2;
offsets[1] = 1;
offsets[2] = 1;
offsets[3] = 0;
break;
...other color spaces
}
memset(RgbChannel, 0, Width * Height * 3 * sizeof(T));
parallel_for(0, Height, [&] (int row)
{
for (auto col = 0, bayerIndex = row * Width; col < Width; col++, bayerIndex++)
{
auto offset = (row%2)*2 + (col%2); //0...3
auto rgbIndex = bayerIndex * 3 + offsets[offset];
RgbChannel[rgbIndex] = BayerChannel[bayerIndex];
}
});
}