8.2_整型支持

8.2 整型支持

SM支持完整的32位整型数运算:

·加上操作数的负数实现减法运算;
·乘法与乘加法;
·整型除法;
·逻辑运算;
·条件代码操作;
·浮点数相互转换;
·其他操作(例如,针对窄整型的SIMD操作、总体计数(population count)和寻找前导零)。

CUDA中的这些功能大多可以用标准C操作符调用。非标准的运算,比如24位乘,可以使用内联PTX汇编或内置函数访问 [1]。

8.2.1 乘法

乘法在特斯拉架构和费米架构的硬件上实现的方法不同。特斯拉实现了一个24位乘法器,而费米实现了一个32位乘法器。因此,完整的32位乘法在SM 1.x的硬件上需要4条指令。对于面向特斯拉架构硬件的性能敏感的代码,使用24位乘法内置函数性能会比较高[1]。表8-4给出了有关乘法的内置函数。

表8-4 乘法内置函数

8.2.2 其他操作(位操作)

CUDA编译器实现了许多“位操作”的内置函数,总结在表8-5中。在SM 2.x及之后的架构中,这些内置函数对应着单条指令。在费米之前的架构中,它们是可用的,但会被编译成多个指令。当我们对此不确定,最好的办法是反汇编并查看微码!64位变量有“11”(代表“long long”)追加在内置函数名之后,如_clz11()、ffsl1()、popcl1()和brev11()。

表8-5 位操作内置函数

8.2.3 漏斗移位(SM 3.5)

GK110增加了一个64位的“漏斗移位”指令来连接2个32位值(高32位和低32位被分成独立的2个输入,但是硬件在对齐的一对寄存器上进行操作),将64位值左移或右移,然后返回最高的(对左移来说)或最低的(对右移来说)32位。

漏斗移位可以通过表8-6中的内置函数访问。这些内置函数被实现成设备的内联函数(使用内联PTX汇编器),定义在sm_35_intrinsics.h中。默认地,最低5位的移位计数被屏蔽,_lc和_rc函数将移位值控制在0~32之间。

漏斗移位的应用包括:

·多字的移位操作。
·在非对齐的缓冲区之间使用对齐的加载和存储指令操作内存。
·旋转。

表8-6 漏斗移位内置函数

为了实现数据的大于64位的右移,重复调用函数

__funnelshift_r(),从低位向高位递进操作。最高的字使用操作符>>计算,根据整数的类别,决定移出的位是补0还是补符号位。为了对数据进行大于64位的左移,重复调用__funnelshift_1()函数,从高位到低位渐次操作。最低的字使用操作符<<计算。如果hi和lo参数相同,漏斗移位构成旋转操作。

[1] 在SM 2.x和之后的硬件上使用__mul24()或__umul24()会有一定程度的性能损失。
[2] 在SM 2.x和之后的硬件上使用__mul24()或__umul24()会有一定程度的性能损失。

8.2_整型支持 - The CUDA Handbook | OpenTech