在C代码中,通常会写
a = b*b;
而不是
a = pow(b, 2.0);
表示double
个变量。我知道,因为pow
是一个能够处理非整数指数的通用函数,所以应该天真地认为第一个版本更快。我不知道编译器(gcc)是否将带有整数指数的pow
转换为直接乘法,作为任何可选优化的一部分。
假设没有进行这种优化,那么手动写出乘法的最大整数指数是多少,如b*b* ... *b
中那样?
我知道我可以在给定的机器上进行性能测试,以确定我是否应该关心,但我想更深入地了解什么是“正确的事情”。
答案 0 :(得分:2)
您想要的是-ffinite-math-only -ffast-math
,可能是#include <tgmath.h>这与-Ofast
相同而不强制进行-O3
优化。
当启用-ffinite-math-only and -ffast-math
时,它不仅有助于这些优化,类型泛型数学还有助于补偿何时忘记将正确的后缀附加到(非双)数学函数。
例如:
#include <tgmath.h>
float pow4(float f){return pow(f,4.0f);}
//compiles to
pow4:
vmulss xmm0, xmm0, xmm0
vmulss xmm0, xmm0, xmm0
ret
对于clang,这适用于高达32的幂,而gcc为至少2,147,483,647(据我检查的那样)执行此操作,除非启用-Os
(因为{{1} pow函数在技术上更小) - 使用-Os,它只能执行2的幂。
警告jmp
只是其他几种优化的便利别名,其中许多优化都违反了各种标准。如果您只使用最小标记来获得所需的行为,那么您可以使用-ffast-math
答案 1 :(得分:0)
就正确的事情而言 - 考虑你的维护者而不仅仅是表现。我有预感你正在寻找一般规则。如果你正在做一个简单而一致的正方形或数字的立方体,我不会使用pow这些。 pow很可能正在进行某种形式的子程序调用而不是执行寄存器操作(这就是Martin指出架构依赖性的原因)。