我已经在每个方向上创建了一个带有(N,N)单元格的网格,我想检查哪些点对应哪个单元格,这很容易,但是,有些点可以超出网格而我想要它然后放入一个单元格。
这一切都是在GPU中完成的,所以我的问题与将这些点映射到有效单元格的最佳操作有关?
使用max(0,min(N,cell.x))的第一个选项,我相信它会在内核中引入分歧。使用模数(cell.x%N)的第二个选项,我认为这是在GPU中进行的非常昂贵的操作。
我如何决定使用哪一个?
答案 0 :(得分:2)
GPU具有整数min()
和max()
的硬件指令。如果您使用cuobjdump --dump-sass
从使用nvcc编译的可执行文件转储机器代码,您可以识别这些说明,例如它们被称为IMNMX
或VMNMX
(“mnmx”代表“最小值”或最大“,两个操作之间的选择是谓词。”
对于编译时常量幂为2的N
,模运算应映射到单个LOP.AND
指令。对于N
的其他编译时常量值,发出一个小指令序列,通常涉及整数乘法和移位。对于变量N
,即在运行时确定,模运算基本上需要一个完整的整数除法,至少为15左右的指令。
除了编译时常量N
是2的幂的情况之外,从性能角度看,使用min()
和max()
进行钳位似乎优于基于模数的解决方案。但是,除非您的代码经常执行此操作并且受到计算吞吐量的限制,否则内核级性能差异很小或可能不存在(例如,如果代码的内存带宽有限)。