【发布时间】:2015-03-21 22:43:50
【问题描述】:
我有一个 CUDA 代码,我想对其进行优化。我的内核正在使用dim3 grid=(35,48) 和dim3 threads=(18,18)。首先,每个块执行独立的290个向量计算,其中每个线程执行1个向量计算(即1024个加法-乘法)。
但是,此计算的前 17*17=289 的输入数据存储在共享数组 im1 中,最后的数据存储在 im2 中(输出数组也不同)。之后,我使用所有获得的数据进行进一步的计算。
我是这样实现的:
if ((threadIdx.x < 17) && (threadIdx.y < 17)){
**instructions for 289s vector calculations**
}
else if ((threadIdx.x == 17) && (threadIdx.y == 17)){
**instruction for 290 vector calculation**
}
__syncthreads();
***further calculations***
所以,如果我理解正确,我的第一个 289 跟随 1 个分支,线程 #324 跟随另一个。只要第一组线程在 warp #0,1,..,10 中,并且线程 #324 在 warp #11 中,就没有分歧分支。但是,我读到,通常最好避免在此类内核中使用任何 if 语句,并将它们替换为跨步索引或类似的东西。那么,我可以以某种方式改进这段代码吗?
我的 GPU 是 GTX 980 和 cc 5.2,我使用 VS2013 进行编码。
谢谢,米哈伊尔
【问题讨论】:
-
您是否分析了您的代码以测量经纱发散的实际数量?
-
你是说NSight?不,由于某种原因,我不能强迫它工作,但这是另一回事。
-
如果你想提高你的代码的性能,你应该首先衡量你的代码的性能,确定瓶颈,如果确实是瓶颈,才考虑发散。
-
根据你的问题,
18 x 18线程块,else if语句将永远不会被执行。这段代码没有分歧。 -
共享内存访问对访问哪些银行非常敏感。最好是每个命令的每个扭曲只访问每个银行一次。 (除非它是相同的内存位置)。但是如果不知道向量计算的内存位置是如何安排的,就无法说出更多。