指令优化:
对指令执行方式的了解通常允许进行低级别的优化,尤其是在频繁运行的代码(程序中所谓的热点)中尤其有用。 最佳实践表明,在完成所有更高级别的优化之后执行此优化。
算术指令:
单精度浮点数提供了最佳的性能,并且极大地鼓励了它们的使用。单个算术运算的吞吐量详见CUDA C编程指南。
划分模数:
低优先级:使用移位操作来避免代价大的除法和模数计算。
整数除法和模运算特别昂贵,应尽可能地避免或用位操作替换:如果是2的幂,(i/n)相当于($i>>log_{2}(n)$)和($i%n$)相当于($i&(n-1)$)
如果n是文字,编译器将执行这些转换。 (有关更多信息,请参阅CUDA C编程指南中的性能指南)。
Reciprocal Square Root:
倒数平方根应该总是以单精度的rsqrtf()和双精度的rsqrt()显式调用。 只有在不违反IEEE-754语义时,编译器才会将1.0f / sqrtf(x)优化为rsqrtf()。
其他算术指令:
低优先级:避免将双打自动转换为浮动。
编译器必须偶尔插入转换指令,引入额外的执行周期。 这是:
- 在char或short上运行的函数通常需要将其操作数转换为int
- 双精度浮点常量(定义为不带任何类型后缀)用作单精度浮点计算的输入
后一种情况可以通过使用单精度浮点常量来避免,这些常量用f后缀定义,例如3.141592653589793f,1.0f,0.5f。 除了其对性能的影响之外,该后缀还具有准确性含义。 对精度的影响在促使双精度和截断浮点运算中讨论。 请注意,这种区别对计算能力2.x的设备的性能特别重要。
对于单精度代码,强烈建议使用浮点类型和单精度数学函数。 编译不具备双精度支持的设备(例如计算能力为1.2或更低版本的设备)时,每个双精度浮点变量将转换为单精度浮点格式(但保留64位大小) 精度算术降级为单精度算术。
还应该注意的是,CUDA数学库的补充错误函数erfcf()在全单精度精度下特别快速。
用小分数参数求幂:
对于一些分数指数,与通过使用平方根,立方根和它们的倒数使用pow()相比,可以显着加速取幂指数。 对于指数不能完全表示为浮点数(如1/3)的指数,由于使用pow()会放大初始表示误差,因此这可以提供更准确的结果。