GPU上的图像计算和值返回

时间:2018-03-02 09:54:25

标签: image-processing parallel-processing opencl gpu cloo

我有一个C#项目,其中我从相机中检索灰度图像并使用图像数据进行一些计算。计算非常耗时,因为我需要多次遍历整个图像,而且我在CPU上完成所有操作。

现在我想尝试在GPU上运行评估,但我在实现这一目标方面付出了很多努力,因为我之前从未做过任何GPU计算。

该软件应该能够在具有不同硬件的几台计算机上运行,​​因此CUDA对我来说不是一个解决方案,因为代码也应该在只有板载图形的笔记本电脑上运行。经过一些研究后,我来到了Cloo(found it on this project),这似乎是一个非常合理的选择。

到目前为止,我已将Cloo集成到我的项目中,并尝试运行this hello world示例。我想它正在运行,因为我没有任何异常,但我不知道在哪里可以看到打印输出。

对于我的计算,我需要将图像传递给GPU,我还需要在计算过程中使用x-y坐标。所以,在C#中,计算看起来像这样:

int a = 0;
for (int y = 0; y < img_height; y++){
    for (int x = 0; x < img_width; x++){
        a += image[x,y] * x * y;
    }
}

int b = 0;
for (int y = 0; y < img_height; y++){
    for (int x = 0; x < img_width; x++){
        b += image[x,y] * (x-a) * y;
    }
}

现在我想让这些计算在GPU上运行,我希望并行y - 循环,以便在每个任务中运行一个x循环。然后我可以获取所有结果值并在第二个循环块开始之前添加它们。

之后我想将值ab返回到我的C#代码并在那里使用它们。

所以,结束我的问题:

  1. Cloo是否可以作为此任务的推荐选择?
  2. 将图像数据(16位,短阵列)和尺寸(img_widthimg_height)传递给GPU的最佳方法是什么?
  3. 如何从GPU返回值?据我所知,内核总是用作kernel void...
  4. 实现循环的最佳方法是什么?
  5. 我希望我的问题很清楚,我提供了足够的信息来理解我的挣扎。任何帮助表示赞赏。提前谢谢。

1 个答案:

答案 0 :(得分:0)

让我们对问题进行逆向工程。理解image[][], image_height, image_width, a, b

的“依赖链”的有效处理

Ad 4)相同for - 环的串联性能较差

给定定义的代码,可能只有一个循环,因此可以降低开销成本,最好还可以最大化缓存对齐的矢量化代码。

Cache-Naive重新制定:

int a = 0;
int c = 1;

for (     int  y = 0; y < img_height; y++ ){
    for ( int  x = 0; x < img_width;  x++ ){
          int      intermediate = image[x,y] * y; // .SET   PROD(i[x,y],y) 
          a += x * intermediate;                  // .REUSE 1st
          c -=     intermediate;                  // .REUSE 2nd
    }
}
int b = a * c; // was my fault upon being in a hurry leaving for weekend :o)

将代码移动到拆分串联循环只会增加这些开销,并在代码性能调整中破坏任何可能的缓存友好技巧。

Ad 3 + 2)内核调用签名+ CPU端方法允许这个

OpenCL和Cloo记录了这些细节,因此这里不需要任何神奇的方法。

然而,每个此类主机端与设备端+设备端到主机端传输都存在延迟成本。鉴于你声称16bit-1920x1200图像数据要在循环中重新处理 ~10次,这些延迟有可能不需要花费在每个这样的循环传递上。 / p>

最差的性能杀手是非常浅的内核数学密度。问题是,在内核中确实没有多少计算,因此任何有效的SIMD / GPU并行技巧的可能性确实很低。

从这个意义上讲,CPU端的智能矢量化代码将比(H2D + D2H) - 开销 - 远程延迟 - 恶意计算 - 浅层GPU内核处理做得更好。

Ad 1)鉴于上面的2 + 3和4,1可能很容易失去感觉

作为原型并提供额外的缓存友好的矢量化技巧,in-ram + in-cache矢量化代码将有机会击败所有OpenCL和混合GPU / CPU自动ad-hoc内核编译生成的设备代码及其计算工作