我想使用CUDA并行化GPU上的图像操作,对图像的每个像素(或像素组)使用一个线程。操作非常简单:每个像素被乘以一个值。
但是,如果我正确理解它,为了将图像放到GPU上并并行处理,我必须将它复制到统一内存或其他GPU可访问的内存中,这基本上是一个双for循环,就像在CPU上处理图像的那样。我想知道是否有一种更有效的方法在GPU上复制图像(例如,1D或2D数组),它没有开销,因此并行化是无用的。
发布于 2021-05-26 21:15:49
但是,如果我正确理解了
,为了将图像放到GPU上并并行处理,我必须将其复制到统一内存或其他GPU访问内存中。
你理解得对。
,我想知道是否有一种更有效的方法在GPU上复制没有开销的图像(即1D或2D数组)
没有。主机系统内存中的数据必须通过PCIE总线才能到达GPU内存。这是受PCIE总线带宽( PCIE Gen3的~12 to /s)所限制的,并且还有一些“固定开销”,至少在每传输几微秒的范围内是这样,因此从性能(字节/s)角度看,非常小的传输似乎更糟糕。
,因此并行化是无用的。
如果您要执行的唯一操作是拍摄一幅图像并将每个像素乘以一个值,而且由于某种原因,GPU上的图像已经不在GPU上,那么没有人会为此使用GPU(可能是为了学习目的)。在性能开始变得有趣之前,您需要为GPU找到更多涉及到的工作。
操作非常简单
这通常不是从GPU加速中获得性能好处的好指标。
发布于 2021-05-27 15:27:47
当您说“它基本上是一个双for循环,就像在CPU上处理图像的循环一样”时,我希望您不要在每一行和每列上逐点复制像素。您可以使用memcpy复制整个图像。然而,正如其他人所说,在CPU和GPU之间移动数据仍然有相当大的开销,除非您在GPU上的计算足够复杂,足以证明开销是合理的。
发布于 2021-05-27 20:32:35
您可以隐藏一些复制延迟。在复制图像输入补丁时,可以从GPU上的先前计算中同时复制结果修补程序。在双向副本重叠的基础上,第三个补丁的计算可以运行。这既可以缩短单个图像处理的总延迟时间,也可以缩短多个图像处理的延迟时间(但这次可以隐藏整个图像处理的延迟)。
对于非常简单的处理,只有读写才能隐藏对方。简单的计算没有任何有意义的延迟来隐藏任何其他内容。因此,通过管道,您可以将性能提高100% (假设输入了1幅图像,输出了1幅相同大小的图像,pcie/driver对两个方向执行相同的操作)。
如果每个像素只是乘以一个值,那么它是令人尴尬的并行,您可以通过流水线与任意大小的块隐藏延迟。例如,
vram
您可以使用每个飞行中的N-扫描线一个流(以执行read+compute+write),并让驱动程序选择最佳的扫描线计算重叠,或者在每个操作类型中有一个流(所有写入1条,所有读取1条,所有计算1条),并使用事件显式地维护重叠行为。
如果你每像素做更多的计算,比如复制的延迟,那么流水线将给你3x的性能(隐藏在1后面的其他两个操作)。
https://stackoverflow.com/questions/67682423
复制相似问题