CUDA系列文章目录
文章目录
- CUDA系列文章目录
- 前言
- 总结
- 参考资料
前言
CUDA(Compute Unified Device Architecture,统一计算架构)是由NVIDIA所推出的一种集成技术,是其对于GPGPU(A General-Purpose Graphics Processing Unit)的正式名称。通过该技术,开发者可以利用NVIDIA的GeForce 8以后的GPU进行计算。极大加速计算型应用的效率。通常用于游戏开发、视频编解码、图像处理等领域。
在编写CUDA核函数时,或者直接调用CUDA封装好的API时,通常会有需要in-place的需求。也就是输出与输入是同一块内存,直接将输入值通过计算后,在输入值原始内存位置进行值的修改。
需要注意的是大多数复杂的算法可能不支持in-place操作,特别是那些单个值与邻域值有关联的算法。由于CUDA核函数运行时是以线程集束的形式发射的,每一个线程运行速度不一定相同,也就是存在一个线程运行结束另外一个线程还没有运行完的情况,这时如果采用In-plcae,已经结束的线程输出地址值已经被修改,而另一个未结束线程用到了这一个值,则会发生错误。不仅是同一个线程集束会有这种问题,在输入图像特别大的情况下,可能需要分批次处理,这时也会发生上述的问题。
例如在NPP文档中,有对in-place的专门解释,支持in-place的操作均会在后缀中标上“I”的标识符。
例如函数NppStatus nppiAbs_16s_C1IR_Ctx (Npp16s *pSrcDst, int nSrcDstStep, NppiSize oSizeROI, NppStreamContext nppStreamCtx)就支持in-place。
除了直接调用CUDA API时需要注意之外,我们自己编写CUDA核函数时也需要注意这一点,避免现象与预想不一致。
总结
在调用CUDA API或者自己编写CUDA核函数需要注意算法是否支持in-place操作,如果对于不支持in-place的方法,传入的src和dst地址一样,那么可能出现错误的结果。
通常情况下,在图像处理中,不需要额外像素参与计算的算法,例如简单的数值操作、像素值域调整等等是支持in-place的,但是诸如卷积、滤波等操作由于单个像素点的计算需要邻域像素的参与,此时如果实现上没有特别处理,一般都不支持in-place操作。需要额外创建一个dst数组用于接收结果。
关于CUDA图像处理的API,一般都会标明是否支持in-place,可以通过相应的标识符进行判别。
参考资料
[1] NVIDIA CUDA核函数及结合OpenCV的使用入门示例
[2] NVIDIA DEVELOPER HOME BLOG
[3] NVIDIA 2D Image And Signal Performance Primitives (NPP) Version 11.2.0.*
[4] NppStatus nppiAbs_16s_C1IR_Ctx (Npp16s *pSrcDst, int nSrcDstStep, NppiSize oSizeROI, NppStreamContext nppStreamCtx)