在使用CUDA设计radon变换函数的时候,遇到了一个一直没有解决的bug
在本项目中需要对一张360×338的图像,从801个角度(10°到170°,间隔0.2°)进行投影变换,需要的计算量非常大,在CPU上做运算时,处理一张图像所需的时间:debug下约40s,release下约3s
在计算radon变换矩阵时,GPU操作了801个block,每个block中有338个线程,然后在每个线程中循环处理原始图像的360个像素,最后将计算结果存入到801×497的矩阵中(497是图像对角线的像素数目),因为同一个block中的线程thread可以使用共享内存,而且访问共享内存的速度会更快,所以每个block申请了大小为497×4(分别存放一个像素的4个计算结果)的共享内存。一幅图像中360×338的像素的计算结果要存入长度为497的数组中,并发线程下需要互斥访问,使用原子操作可以解决。然而由于我传入的图像数据是double型的,显卡的计算能力只有3.5,没办法使用重载double的atomicAdd函数。于是使用了官方给出的替代方法,编写用atomicCAS实现的用于计算double型的atomicAdd,问题就出在了这里,运行时,程序会报错,返回错误码719,“unspecified launch failure”,查询官方文档之后,
百般调试都没有解决,最后将double型的数据改成float型,使用官方给的float型的atomicAdd函数,问题得到解决,计算结果正确。
个人感觉应该是耗尽了GPU的资源导致出错吧。因为最开始写的方法是创建801×360×338个线程,也出现了同样的问题。可能自己编写的double型的atomicAdd函数也比较费资源,而自带的float型的atomicAdd函数使用了什么机制,消耗资源相对较少。
如果如果一个block里面分配的register超过了multiprocessor的最大极限时,kernel的launch就会fail