下面的节目..。
int main() {
float t = 0;
for (int i = 0; i < 1'000'000'000; i++) {
const float x = i;
t += x*x*x;
}
return t;
}...takes大约900毫秒在我的机器上完成。但是..。
#include <cmath>
int main() {
float t = 0;
for (int i = 0; i < 1'000'000'000; i++) {
const float x = i;
t += std::pow(x,3.0f);
}
return t;
}...takes大约6600毫秒完成。
我被告知,优化器没有内联std::pow函数,因此这两个程序产生相同的代码并具有相同的性能。
有什么见解吗?你如何解释5倍的性能差异?
作为参考,我在Linux x86上使用gcc x86
更新:(C版)
int main() {
float t = 0;
for (int i = 0; i < 1000000000; i++) {
const float x = i;
t += x*x*x;
}
return t;
}...takes大约900毫秒在我的机器上完成。但是..。
#include <math.h>
int main() {
float t = 0;
for (int i = 0; i < 1000000000; i++) {
const float x = i;
t += powf(x,3.0f);
}
return t;
}...takes大约6600毫秒完成。
更新2
以下节目:
#include <math.h>
int main() {
float t = 0;
for (int i = 0; i < 1000000000; i++) {
const float x = i;
t += __builtin_powif(x,3.0f);
}
return t;
}运行900毫秒,就像第一个程序。
为什么pow不与__builtin_powif内联?
更新3:
对于-ffast-math,下面的程序如下:
#include <math.h>
#include <iostream>
int main() {
float t = 0;
for (int i = 0; i < 1'000'000'000; i++) {
const float x = i;
t += powf(x, 3.0f);
}
std::cout << t;
}在227 as中运行(与x*x*x版本一样)。这是每次迭代200皮克秒。使用-fopt-info,它表示optimized: loop vectorized using 16 byte vectors和optimized: loop with 2 iterations completely unrolled,所以我猜这意味着它对SSE执行4次迭代,一次执行2次迭代(一次总共执行8次迭代),或者类似的事情?
发布于 2021-02-11 08:06:49
关于gcc建筑的文档页面是显式的(强调我的):
内置功能: double __builtin_powi (double,int) 将第一个参数返回到第二个参数的威力。与pow函数不同,没有保证精度和四舍五入的。内置函数: float __builtin_powif (float,int) 类似于__builtin_powi,除了参数和返回类型是浮动的。
由于__builtin_powif具有与单纯的产品相同的性能,这意味着为了保证精度和舍入,pow所要求的控件需要额外的时间。
https://stackoverflow.com/questions/66150593
复制相似问题