Moc*_*han 2 trigonometry glibc avx perf
我编写了一个简单的代码进行测试prof。
double bar_compute (double d) {
double t = std::abs(d);
t += std::sqrt(d);
t += std::cos(d);
return t;
}
// Do some computation n times
double foo_compute(unsigned n) {
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_real_distribution<double> dist(0.0, 1.0);
double total = 0;
for (int i=0; i<n; i++) {
double d = dist(mt);
total += bar_compute(d);
}
return total;
}
Run Code Online (Sandbox Code Playgroud)
当我运行prof并查看输出时,它是
56.14% runcode libm-2.23.so [.] __cos_avx
27.34% runcode runcode [.] _Z11foo_computej
13.92% runcode runcode [.] _Z11bar_computed
0.86% runcode libm-2.23.so [.] do_cos_slow.isra.1
0.44% runcode runcode [.] cos@plt
0.41% runcode libm-2.23.so [.] sloww1
0.35% runcode libm-2.23.so [.] __dubcos
0.17% runcode ld-2.23.so [.] _dl_lookup_symbol_x
Run Code Online (Sandbox Code Playgroud)
是什么do_cos_slow.isra和sloww1意味着什么?
cos我可以使用更快的版本吗?否则为什么将其称为慢速?
do_cos_slow来自其在glibc / sysdeps / ieee754 / dbl-64 / s_sin.c中的声明。之所以调用它,是do_cos_slow因为它比第164行的do_cos声明上方的注释要精确得多。
这.isra是因为该函数是IPA SRA根据以下堆栈溢出答案进行了优化的版本,GCC函数后缀“ isra”是什么意思?
sloww1 是一个函数,根据上面的注释计算sin(x + dx)。
关于cos的更快版本,我不确定是否有更快的版本,但是如果将提供libm的glibc或libc实现更新为至少glibc 2.28,那么您将获得Wilco Dijkstra删除这些慢路径的结果。 dosincos的功能和重构,可提高速度。
从提交消息
Refactor the sincos implementation - rather than rely on odd partial inlining
of preprocessed portions from sin and cos, explicitly write out the cases.
This makes sincos much easier to maintain and provides an additional 16-20%
speedup between 0 and 2^27. The overall speedup of sincos is 48% over this range.
Between 0 and PI it is 66% faster.
Run Code Online (Sandbox Code Playgroud)
你可以尝试其他的选择是其他的libc或libm中实现,或其他COS实现包括avx_mathfun或avx_mathfun一些修复更新的GCC或supersimd。