我是eigen的新手。
我测试了本征的矢量点性能,发现它比手动循环慢。
代码如下:#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似乎没有效果。
我认为应该对eigen进行优化,并且没有理由比循环慢。
我做错了吗?
或者,我如何优化本征绩效?
THX
答案 0 :(得分:4)
您没有对第一次计算的结果做任何事情,之后又分配给它。第一个计算完全优化。您可以通过在计算后打印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
这种变化不会让你的基准更好,但结果不会再是错误了。
您仍应考虑使用不同数据集进行多次运行的平均值。也不要为每次运行生成不同的测试数据,因为您的结果不可重复。
答案 1 :(得分:2)
您正在进行过度优化:编译器比您更智能并优化循环计算。
我在我的机器上得到了这些时间:
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