假设我有以下代码:
const int n = fun1();
const double x = fun2();
for(int i=0; i < n; i++) {
double y = fun3(i) / std::sqrt(x);
double z = fun4(i) / std::sqrt(x);
// Do something with the values, e.g., assign them to an array outside the loop
}
Run Code Online (Sandbox Code Playgroud)
最近的编译器是否设法将其优化为
const int n = fun1();
const double x = fun2();
const double sqrtx = std::sqrt(x); // only computed once instead of possibly 2*n times
for(int i=0; i < n; i++) {
double y = fun3(i) / sqrtx;
double z = fun4(i) / sqrtx;
// Do something with the values, e.g., assign them to an array outside the loop
}
Run Code Online (Sandbox Code Playgroud)
或者仍然值得手动进行此类优化吗?
(截至撰写本文时)clang 和 gcc 没有进行此优化,但 MSVC 进行了: https: //godbolt.org/z/eKcva1heT。Clang 和 GCC 都调用了sqrt两次,它们判断是否std::sqrt有副作用太复杂,因此无法优化调用。
使用 libc++ clangstd::sqrt使用一条sqrtsd指令实现,但仍使用该指令两次: https: //godbolt.org/z/G5sEPYqEP。
如果它是内联函数,那么编译器可能可以删除重复操作。如果我们将您的示例更改为:
inline double square(double value)
{
return value * value;
}
int main()
{
const int n = fun1();
const double x = fun2();
for(int i=0; i < n; i++) {
double y = fun3(i) / square(x);
double z = fun4(i) / square(x);
std::cout << x << y;
}
}
Run Code Online (Sandbox Code Playgroud)
那么所有三个编译器只做一次平方:https ://godbolt.org/z/Ys6xPcsc1
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |