问题描述
英特尔的编译器有一个pragma,可用于生成非临时存储。例如,我可以写
void square(const double* x,double* y,int n) {
#pragma vector nontemporal
for (int i=0; i<n; ++i) {
y[i] = x[i] * x[i];
}
}
,ICC会生成类似this(编译器-浏览器)的指令
...
vmovntpd %ymm1,(%rsi,%r9,8) #4.5
...
gcc和clang有类似的东西吗? (非内在函数)
非临时存储使代码更快。使用此基准
#include <random>
#include <memory>
#include <benchmark/benchmark.h>
static void generate_random_numbers(double* x,int n) {
std::mt19937 rng{0};
std::uniform_real_distribution<double> dist{-1,1};
for (int i=0; i<n; ++i) {
x[i] = dist(rng);
}
}
static void square(const double* x,int n) {
#ifdef __INTEL_COMPILER
#pragma vector nontemporal
#endif
for (int i=0; i<n; ++i) {
y[i] = x[i] * x[i];
}
}
static void BM_Square(benchmark::State& state) {
const int n = state.range(0);
std::unique_ptr<double[]> xptr{new double[n]};
generate_random_numbers(xptr.get(),n);
for (auto _ : state) {
std::unique_ptr<double[]> yptr{new double[n]};
square(xptr.get(),yptr.get(),n);
benchmark::DoNotOptimize(yptr);
}
}
BENCHMARK(BM_Square)->Arg(1000000);
BENCHMARK_MAIN();
非临时代码在我的计算机上的运行速度几乎快一倍。这是完整的结果:
icc:
> icc -O3 -march=native -std=c++11 benchmark.cpp -lbenchmark -lbenchmark_main
> ./a.out
------------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------------
BM_Square/1000000 430889 ns 430889 ns 1372
c声:
> clang++ -O3 -march=native -std=c++11 benchmark.cpp -lbenchmark -lbenchmark_main
> ./a.out
------------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------------
BM_Square/1000000 781672 ns 781470 ns 820
gcc:
> g++-mp-10 -O3 -march=native -std=c++11 benchmark.cpp -lbenchmark -lbenchmark_main
> ./a.out
------------------------------------------------------------
Benchmark Time CPU Iterations
------------------------------------------------------------
BM_Square/1000000 681684 ns 681533 ns 782
注意:clang有__builtin_nontemporal_store;但是当我尝试时,它不会生成非时间性指令(compiler-explorer)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)