[英]Why is std::sin() and std::cos() slower than sin() and cos()?
Test code: 测试代码:
#include <cmath>
#include <cstdio>
const int N = 4096;
const float PI = 3.1415926535897932384626;
float cosine[N][N];
float sine[N][N];
int main() {
printf("a\n");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cosine[i][j] = cos(i*j*2*PI/N);
sine[i][j] = sin(-i*j*2*PI/N);
}
}
printf("b\n");
}
Here is the time: 这是时间:
$ g++ main.cc -o main
$ time ./main
a
b
real 0m1.406s
user 0m1.370s
sys 0m0.030s
After adding using namespace std;
添加
using namespace std;
, the time is: , 现在的时间是:
$ g++ main.cc -o main
$ time ./main
a
b
real 0m8.743s
user 0m8.680s
sys 0m0.030s
Compiler: 编译:
$ g++ --version
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
Assembly: 部件:
Dump of assembler code for function sin@plt:
0x0000000000400500 <+0>: jmpq *0x200b12(%rip) # 0x601018 <_GLOBAL_OFFSET_TABLE_+48>
0x0000000000400506 <+6>: pushq $0x3
0x000000000040050b <+11>: jmpq 0x4004c0
End of assembler dump.
Dump of assembler code for function std::sin(float):
0x0000000000400702 <+0>: push %rbp
0x0000000000400703 <+1>: mov %rsp,%rbp
0x0000000000400706 <+4>: sub $0x10,%rsp
0x000000000040070a <+8>: movss %xmm0,-0x4(%rbp)
0x000000000040070f <+13>: movss -0x4(%rbp),%xmm0
0x0000000000400714 <+18>: callq 0x400500 <sinf@plt>
0x0000000000400719 <+23>: leaveq
0x000000000040071a <+24>: retq
End of assembler dump.
Dump of assembler code for function sinf@plt:
0x0000000000400500 <+0>: jmpq *0x200b12(%rip) # 0x601018 <_GLOBAL_OFFSET_TABLE_+48>
0x0000000000400506 <+6>: pushq $0x3
0x000000000040050b <+11>: jmpq 0x4004c0
End of assembler dump.
You're using a different overload: 你正在使用不同的重载:
Try 尝试
double angle = i*j*2*PI/N;
cosine[i][j] = cos(angle);
sine[i][j] = sin(angle);
it should perform the same with or without using namespace std;
无论是否
using namespace std;
它都应该执行相同的操作using namespace std;
I guess the difference is that there are overloads for std::sin() for float and for double, while sin() only takes double. 我猜不同之处在于,对于float和double,std :: sin()存在重载,而sin()只需要加倍。 Inside std::sin() for floats, there may be a conversion to double, then a call to std::sin() for doubles, and then a conversion of the result back to float, making it slower.
在浮点数的std :: sin()里面,可能有一个转换为double,然后调用std :: sin()为double,然后将结果转换回float,使其变慢。
Use -S flag in compiler command line and check the difference between assembler output. 在编译器命令行中使用-S标志并检查汇编器输出之间的差异。 Maybe
using namespace std;
也许
using namespace std;
gives a lot of unused stuff in executable file. 在可执行文件中提供了大量未使用的东西。
I did some measurements using clang with -O3
optimization, running on an Intel Core i7
. 我使用clang
-O3
优化进行了一些测量,在Intel Core i7
上运行。 I found that: 我找到:
std::sin
on float
has the same cost as sinf
float
std::sin
与sinf
具有相同的成本 std::sin
on double
has the same cost as sin
std::sin
on double
与sin
成本相同 double
are 2.5x slower than on float
(again, running on an Intel Core i7
). double
的sin函数比float
慢2.5倍(再次,在Intel Core i7
上运行)。 Here is the full code to reproduce it: 以下是重现它的完整代码:
#include <chrono>
#include <cmath>
#include <iostream>
template<typename Clock>
struct Timer
{
using rep = typename Clock::rep;
using time_point = typename Clock::time_point;
using resolution = typename Clock::duration;
Timer(rep& duration) :
duration(&duration) {
startTime = Clock::now();
}
~Timer() {
using namespace std::chrono;
*duration = duration_cast<resolution>(Clock::now() - startTime).count();
}
private:
time_point startTime;
rep* duration;
};
template<typename T, typename F>
void testSin(F sin_func) {
using namespace std;
using namespace std::chrono;
high_resolution_clock::rep duration = 0;
T sum {};
{
Timer<high_resolution_clock> t(duration);
for(int i=0; i<100000000; ++i) {
sum += sin_func(static_cast<T>(i));
}
}
cout << duration << endl;
cout << " " << sum << endl;
}
int main() {
testSin<float> ([] (float v) { return std::sin(v); });
testSin<float> ([] (float v) { return sinf(v); });
testSin<double>([] (double v) { return std::sin(v); });
testSin<double>([] (double v) { return sin(v); });
return 0;
}
I'd be interested if people could report, in the comments on the results on their architectures, especially regarding float
vs. double
time. 如果人们可以在关于他们的架构的结果的评论中报告,特别是关于
float
与double
时间,我会感兴趣。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.