【发布时间】:2017-09-04 15:20:01
【问题描述】:
在 C 代码中很常见
a = b*b;
而不是
a = pow(b, 2.0);
用于double 变量。我明白了,因为pow 是一个能够处理非整数指数的通用函数,人们应该天真地认为第一个版本更快。但是,我想知道编译器 (gcc) 是否会将对 pow 的调用转换为带有整数指数的直接乘法,作为任何可选优化的一部分。
假设不进行这种优化,那么手动写出乘法的最大整数指数是多少,例如b*b* ... *b?
我知道我可以在给定的机器上进行性能测试以确定我是否应该关心,但我想更深入地了解什么是“正确的事情”。
【问题讨论】:
-
架构相关。
-
pow()(我假设是您的意思的函数)不仅仅是一个能够处理非整数指数的函数;它是一个接受double类型参数并返回double的函数。这有点微妙,但参数和返回值的类型与它们可能采用的值一样重要。 -
编译器不会进行这种转换,因为
power处理浮点值。写出b*b ... *b来计算整数幂几乎总是更快。 -
这很可能是this question 的副本,除了您明确询问整数,而该问题的大多数答案都假设浮点数。不过答案是一样的:手动写出乘法会更快,因为库函数必须足够通用以处理所有可能的情况。这对于整数和浮点值都是正确的,但对于整数尤其是正确,因为 FP 转换非常慢。
-
有趣的是,x86-64 上的
gcc和clang似乎将pow(b, 2.0)转换为b * b,但b仍被视为双精度值 (godbolt reference)。查看mulsd %xmm0, %xmm0指令。将 2.0 替换为 3.0 时似乎没有发生相同的优化。
标签: c gcc optimization gnu compiler-optimization