我刚问自己是否使用例如复杂的指数计算threadIdx.x对性能有影响。一旦内核上传到设备,这些变量是否会变为常量?
我想导航到一个巨大的数组,索引依赖于threadIdx.x,threadIdx.y和threadIdx.z。我需要例如像
这样的模运算array[threadIdx.y % 2 + ...]
答案 0 :(得分:3)
您的索引计算中有一个加法和一个模数。
来自CUDA编程指南:operator+
的吞吐量非常高(3.5计算能力GPU为160)。
operator%
需要数十次操作,吞吐量类似于operator+
。
在你的情况下,你使用operator%
和一个文字常量,编译器很可能会优化它。你的常量也是两个数字(2)的幂,所以编译器会用按位operator&
(与operator+
相同的吞吐量)替换它。
对应用程序进行概要分析以避免浪费时间优化算术运算而不获得任何性能非常重要。 通常,内存加载和存储操作会完全隐藏算术运算,在这种情况下,您需要专注于优化内存吞吐量。
答案 1 :(得分:2)
我认为
array[threadIdx.y % 2 + ...]
只是一个例子。
一般来说,%
操作可能很慢。加速索引计算的一个有用技巧是注意到
foo%n==foo&(n-1) if n is a power of 2
所以,也许对于上面的例子,编译器会为你做这个优化,但是如果你有foo%n
,上面的诀窍值得使用。
答案 2 :(得分:0)
如果有人感兴趣,我已经评估了相应的PTX代码。
(1)复杂的线程ID计算会对性能产生影响。 “threadIdx.x”等不是常量。
(2)“threadIdx.y%2”有效实现,对应于“threadIdx.y& 0x00000001”(Cuda Toolkit 5.5)。