2014-11-21 57 views
0

我在每个方向创建了一个网格(N,N)单元,我想检查哪些点对应哪个单元,这很容易,但是,有一些点可以离开网格,我希望它把它放到一个单元格中。哪种操作对性能,最小/最大或模数的影响最小?

这些都是在GPU中完成的,所以我的问题是关于什么才是映射点到有效单元格的最佳操作?

使用max(0,min(N,cell.x))的第一个选项我相信会引入内核的分歧。第二种选择是使用模数(cell.x%N),我认为这是GPU中非常昂贵的操作。

我怎样才能决定使用哪一个?

+0

你知道N吗?例如,用两个幂的modtros很便宜。 – Jez 2014-11-21 14:42:49

+0

我在想这个,但我想在某些情况下,这意味着增加所需的内存是正确的?但是,呃...网格不应该那么大,所以它可能是一个选择。 – BRabbit27 2014-11-21 14:49:30

+1

'使用max(0,min(N,cell.x))的第一个选项,我相信它会在内核中引入分歧“为什么你认为这会引入分歧?这些函数应该映射到非常高效的无分支程序集,例如'min.s32'和'max.s32'。那里没有分歧。 – 2014-11-21 15:04:07

回答

2

GPU具有整数min()max()的硬件指令。如果使用cuobjdump --dump-sass从nvcc编译的可执行文件中转储机器代码,则可以识别这些指令,例如,它们被称为IMNMXVMNMX(“mnmx”代表“最小值或最大值”,两个操作之间的选择是通过谓词)。

对于N这是一个编译时常量幂的两倍,模运算应该映射到一个单指令LOP.AND。对于其他编译时常量值N,发出一个小指令序列,通常涉及整数乘法和移位。对于变量N,即在运行时确定,模运算将基本上需要至少15条左右指令的全整数除法。

因此,除了编译时常量N是2的幂的情况之外,从性能角度看,使用min()max()进行的钳位似乎优于基于模的解决方案。但是,除非您的代码频繁执行此操作并受计算吞吐量限制,否则内核级别的性能差异可能很小或可能不存在(例如,如果代码是内存带宽受限的)。