NVIDIA CUDA核函数编写注意事项之In-place

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”的标识符。
NVIDIA CUDA核函数编写注意事项之In-place_第1张图片例如函数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)

你可能感兴趣的:(CUDA杂记,cuda,nvidia)