为什么 std::inner_product 比简单的实现慢?
Why is std::inner_product slower than the naive implementation?
这是我天真的点积实现:
float simple_dot(int N, float *A, float *B) {
float dot = 0;
for(int i = 0; i < N; ++i) {
dot += A[i] * B[i];
}
return dot;
}
这是使用 C++ 库:
float library_dot(int N, float *A, float *B) {
return std::inner_product(A, A+N, B, 0);
}
我运行一些benchmark(代码在这里https://github.com/ijklr/sse),库版本慢了很多。
我的编译器标志是 -Ofast -march=native
你的两个函数不做同样的事情。该算法使用一个累加器,其类型是 从初始值推导出 ,在您的情况下 (0
) 是 int
。将 float 累加到 int 不仅比累加到 float 花费的时间更长,而且会产生不同的结果。
你的原始循环代码相当于使用初始值0.0f
,或者相当于float{}
。
(请注意,std::accumulate
在这方面非常相似。)
这是我天真的点积实现:
float simple_dot(int N, float *A, float *B) {
float dot = 0;
for(int i = 0; i < N; ++i) {
dot += A[i] * B[i];
}
return dot;
}
这是使用 C++ 库:
float library_dot(int N, float *A, float *B) {
return std::inner_product(A, A+N, B, 0);
}
我运行一些benchmark(代码在这里https://github.com/ijklr/sse),库版本慢了很多。
我的编译器标志是 -Ofast -march=native
你的两个函数不做同样的事情。该算法使用一个累加器,其类型是 从初始值推导出 ,在您的情况下 (0
) 是 int
。将 float 累加到 int 不仅比累加到 float 花费的时间更长,而且会产生不同的结果。
你的原始循环代码相当于使用初始值0.0f
,或者相当于float{}
。
(请注意,std::accumulate
在这方面非常相似。)