为什么特征向量点比手动循环慢
Why Eigen vector dot is slower than manual for loop
我对特征是个新手。
我测试了本征的矢量点性能,发现它比手动循环慢。
代码如下:
#include <Eigen/Dense>
#include <iostream>
#include <vector>
int main()
{
Eigen::VectorXf neu1 = Eigen::VectorXf::Random(100000000);
std::vector<float> x(100000000);
for(int i = 0; i < 100000000; ++i)
x[i] = neu1[i];
clock_t t1 = clock();
float r = 0.0f;
for(int i = 0; i < 100000000; ++i)
r += x[i]*x[i];
clock_t t2 = clock();
std::cout<<"time: "<<t2-t1<<std::endl;
t1 = clock();
r = neu1.dot(neu1);
t2 = clock();
std::cout<<"time: "<<t2-t1<<std::endl;
}
结果是:
g++ test.cpp -otest -I/usr/local/include/eigen/
time: 1070000
time: 1910000
g++ test.cpp -otest -I/usr/local/include/eigen/ -Ofast -march=native
time: 0
time: 50000
而且,#define EIGEN_NO_DEBUG似乎没有任何效果。
我认为本征应该优化,并没有理由比循环慢。
我做错什么了吗?
或者,如何优化本征性能?
thx
您不会对第一次计算的结果执行任何操作,然后再分配给它。第一次计算完全优化。您可以通过在计算后打印r
的值来解决此问题:
#include <iostream>
#include <vector>
#include <eigen3/Eigen/Core>
#include <time.h>
int main()
{
Eigen::VectorXf neu1 = Eigen::VectorXf::Random(100000000);
std::vector<float> x(100000000);
for(int i = 0; i < 100000000; ++i)
x[i] = neu1[i];
clock_t t1 = clock();
float r = 0.0f;
for(int i = 0; i < 100000000; ++i)
r += x[i]*x[i];
clock_t t2 = clock();
std::cout<<"time: "<<t2-t1<<std::endl;
std::cout << r << std::endl;
t1 = clock();
r = neu1.dot(neu1);
t2 = clock();
std::cout<<"time: "<<t2-t1<<std::endl;
std::cout << r << std::endl;
return 0;
}
以下是运行生成的示例:
/tmp $ g++ -Wall -Wextra -pedantic -O3 -std=c++14 bla.cpp
/tmp $ ./a.out
time: 272958
1.67772e+07
time: 29003
3.29441e+07
或
/tmp $ g++ -Wall -Wextra -pedantic -Ofast -std=c++14 bla.cpp
/tmp $ ./a.out
time: 29953
3.23292e+07
time: 28853
3.29441e+07
这种改变不会让你的基准测试变得更好,但结果不会再出现可怕的错误。
您仍然应该考虑使用不同数据集多次运行的平均值。也不要为每次运行生成不同的测试数据,因为你的结果不会是可复制的。
最后,如下所述,结果的差异可能是由于溢出和/或舍入错误造成的。建议更改为双倍精度或缩短阵列的长度,然后再次运行测试。
您遇到了过度优化:编译器比您更聪明,可以优化循环计算。
我在我的机器上得到了这些时间:
time: 0
time: 23422
如果您需要确保在基准测试中读取/写入某些内容,请使用volatile
:
#include <Eigen/Dense>
#include <iostream>
#include <vector>
int main()
{
Eigen::VectorXf neu1 = Eigen::VectorXf::Random(100000000);
std::vector<float> x(100000000);
for(int i = 0; i < 100000000; ++i)
x[i] = neu1[i];
clock_t t1 = clock();
float temp = 0.0f;
for(int i = 0; i < 100000000; ++i)
temp += x[i]*x[i];
volatile float result = temp;
clock_t t2 = clock();
std::cout<<"time: "<<t2-t1<<std::endl;
t1 = clock();
result = neu1.dot(neu1);
t2 = clock();
std::cout<<"time: "<<t2-t1<<std::endl;
}
然后,我的机器上的时间变成:
time: 79060
time: 21542
相关文章:
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- while循环中while循环的时间复杂度是多少
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 特征获取索引数组,其中向量中的值为真(不需要循环)
- 将函数应用于特征矩阵中的所有元素,而无需循环
- 寻找此循环的更快特征替代方案
- 为什么特征向量点比手动循环慢
- 无循环的特征元素操作
- 对于指数,特征表达式模板比手动循环慢