用小整数常数实现浮点乘法的最快方法

时间:2018-08-10 00:56:03

标签: performance floating-point opencl

假设您正在尝试将浮点数k与一个小的整数常量n(小我的意思是-20 <= n <= 20)相乘。天真的方法是将n转换为浮点数(出于本问题的目的,这不计入运行时)并执行浮点乘法。但是,对于n = 2,看来k + k是一种更快的计算方法。在什么情况下,n的乘积指令变得比重复加法的速度更快(如果n < 0则在末尾加上一个反转)?

请注意,我在这里并不特别关注准确性;我愿意允许不合理的优化,只要它们能给出大致正确的答案即可(即:最多1024个ULP错误可能就可以了)。

我正在编写OpenCL代码,因此我对许多计算环境(x86-64,x86-64 + AVX256,GPU)中该问题的答案很感兴趣。

我可以对此进行基准测试,但是由于我没有特定的体系结构,因此我宁愿从理论上证明选择的合理性。

1 个答案:

答案 0 :(得分:2)

根据AMD's OpenCL optimisation guide for GPUs,第3.8.1节“指令带宽”,对于单精度浮点操作数,加,乘和'MAD'(乘加)在GCN上每个周期的吞吐量均为5基于GPU。 24位整数也是如此。只有当您移至32位整数时,乘法的开销才更为昂贵(1 /周期)。从浮点数到浮点数的转换也相对较慢(1 /周期),并且除非您具有具有双精度浮点功能的模型(大多数是nvidia的FirePro / Radeon Pro系列或Quadro / Tesla),否则双精度运算非常慢(<1 /周期)。求反在GPU上通常是“免费的”-例如,GCN在指令操作数上具有符号标志,因此<Border Grid.Row="4" Grid.Column="2" Margin="10,0,10,0" BorderBrush="Gray" BorderThickness="1"> <Grid> <TextBox BorderBrush="LightGray" BorderThickness="1" Text="{Binding WaybillNumber}" /> <Button Content="*" HorizontalAlignment="Right" Margin="2" Width="15" BorderThickness="1"/> </Grid> </Border> 在转换为-(a + b)之后会编译为一条指令。

在整数运算中,英伟达GPU的趋向往往会稍慢一些,但对于浮点数,这与AMD的故事类似:乘法的速度与加法一样快,如果将它们组合成MAD运算,则吞吐量可以提高一倍。英特尔的GPU在其他方面有很大的不同,但是它们在FP乘法和加法方面又非常快。

基本上,要在浮点乘法上击败GPU真的很困难,因为这实际上是他们针对其进行优化的一件事。

在CPU上通常更为复杂-Agner Fog's optimisation resources and instruction tables是获取详细信息的地方。请注意,尽管在许多CPU上,由于ALU和FPU通常是分开的,所以将浮点数据解释为整数然后返回会付出一定的代价。 (例如,如果您想通过对它们的指数进行整数加法来优化乘以2的乘数来浮点运算。在x86上,您可以通过先使用先浮点指令,再使用整数指令对SSE或AVX寄存器进行操作来轻松实现此目的,但是通常对性能不好。)