是否允许编译器优化浮点常量乘法
Are compilers allowed to optimize floating point constant multiplication
有问题的代码如下:
float32_t f = someValueFromSomewhere;
f = f * 4;
编译器会优化这个吗?
根据 C 标准(如果我理解正确的话),第二个操作数必须提升为 float32_t
;
所以乘法必须使用 FPU(或 fp 仿真)来完成。
理论上,只需添加一个立即数(并且可能是溢出检查),就可以在普通的硬件寄存器中完成该操作。
是否允许编译器进行此优化?是否有已知的编译器可以这样做?如果是这样,他们是否也能识别表达式
f = f * 4.0f;
这是避免静态代码检查器关于隐式转换的警告所必需的吗?
一些补充:
我知道从标准的角度来看,两条线是等效的。但显然编译器可以区分它们。所以问题是什么时候允许优化器第一次看到代码(或者更好的内部表示)。
不,它不起作用
仅当原始值不是次正规值(包括公共零)、不是无穷大或 NaN,并且结果不溢出时,将指数加 2 代替乘以 4.0 才有效。一般来说,编译器没有这些信息。当编译器确实有这个信息时,允许做这个转换,这并不意味着它是一个好主意。
在大多数架构上,这不是一个好主意
除非你正在考虑一个特定的执行平台,从它所在的浮点寄存器中获取 f
的值会更便宜,将它移到一个通用寄存器中,添加一个常量,测试特殊情况(见上文),并返回到浮点寄存器,您可以假设所有这些步骤都比浮点乘法昂贵得多。只有当浮点运算被模拟为一系列位和整数运算时,以这种方式“优化”乘以 2 的幂的乘法才有意义。
> [编译器] 也会识别表达式 f = f * 4.0f;
f * 4
等同于 f * (float)4
,因此等同于 f * 4.0f
。编译器可以将这些形式中的任何一种转换成与转换另一种形式相同的代码,并且任何非玩具编译器都知道它们是等价的(例如,作为 constant propagation 优化传递到 (float)4
).
有问题的代码如下:
float32_t f = someValueFromSomewhere;
f = f * 4;
编译器会优化这个吗?
根据 C 标准(如果我理解正确的话),第二个操作数必须提升为 float32_t
;
所以乘法必须使用 FPU(或 fp 仿真)来完成。
理论上,只需添加一个立即数(并且可能是溢出检查),就可以在普通的硬件寄存器中完成该操作。 是否允许编译器进行此优化?是否有已知的编译器可以这样做?如果是这样,他们是否也能识别表达式
f = f * 4.0f;
这是避免静态代码检查器关于隐式转换的警告所必需的吗?
一些补充: 我知道从标准的角度来看,两条线是等效的。但显然编译器可以区分它们。所以问题是什么时候允许优化器第一次看到代码(或者更好的内部表示)。
不,它不起作用
仅当原始值不是次正规值(包括公共零)、不是无穷大或 NaN,并且结果不溢出时,将指数加 2 代替乘以 4.0 才有效。一般来说,编译器没有这些信息。当编译器确实有这个信息时,允许做这个转换,这并不意味着它是一个好主意。
在大多数架构上,这不是一个好主意
除非你正在考虑一个特定的执行平台,从它所在的浮点寄存器中获取 f
的值会更便宜,将它移到一个通用寄存器中,添加一个常量,测试特殊情况(见上文),并返回到浮点寄存器,您可以假设所有这些步骤都比浮点乘法昂贵得多。只有当浮点运算被模拟为一系列位和整数运算时,以这种方式“优化”乘以 2 的幂的乘法才有意义。
> [编译器] 也会识别表达式 f = f * 4.0f;
f * 4
等同于 f * (float)4
,因此等同于 f * 4.0f
。编译器可以将这些形式中的任何一种转换成与转换另一种形式相同的代码,并且任何非玩具编译器都知道它们是等价的(例如,作为 constant propagation 优化传递到 (float)4
).