【发布时间】:2020-12-17 09:07:47
【问题描述】:
我正在做一个动态编程问题,其中每一行都依赖于前一行,即ith 行依赖于i-1th 行,从第 1 行开始(0 索引)。
我正在使用numba 的cuda.jit 来加速这个过程。我的方法是让一维线程块等于我的矩阵的宽度(w)(其中矩阵是灰度图像,即尺寸为h x w 的二维图像)。 因此每个线程只负责一个列。
如何正确循环每一行?在下面的代码中,我沿着行大步前进,因为每个线程处理一列。
@cuda.jit
def forward_energy(im, energy, m):
row, col = cuda.grid(2)
xstride, _ = cuda.gridsize(2)
height, width = im.shape[0], im.shape[1]
if row >= height or col >= width: return
for i in range(row, im.shape[0], xstride):
# example code below is dependent on the previous row of `im`
energy[i, col] = min(im[i - 1, col], im[i - 1, col - 1])
im[i, col] = # update current row
这是对的吗?据我所知,每个线程都是异步执行的,因此线程 1(处理第 1 列)可能位于第 5 行,而线程 2(位于第 2 列)可能仍位于第 3 行。如何确保每一行在继续之前完成,如果用 cuda 可能的话?
【问题讨论】:
-
通过对已知解决方案执行严格的验证测试,唯一能判断代码是否正确的人就是您。但我非常怀疑需要严格执行顺序以确保正确性的计算将直接移植到 CUDA
-
很公平@talonmies。我阅读了一篇关于在每一行之后同步的类似问题的论文。你能否指出我正确的方向,如果我在每一行之后进行同步,实现会是什么样子?
-
除非您将计算大大减少到单个块,否则您无法进行这种同步。 Numba 不支持现代 CUDA 和硬件中任何更高级的任意同步功能
-
另一种选择是让您的 numba
@cuda.jit函数为单行执行计算,然后在循环中为每一行调用该函数。如果您有足够多的列,那么以这种方式使用 GPU 可能仍然是明智的。 -
谢谢罗伯特。是的,这就是我现在采用的方法。