我在std::vector
上重载了算术/赋值运算符,以便能够执行一些基本的线性代数运算。但是,在链接这些操作时遇到一些性能问题。
这是我的main.h
的内容:
#include <vector>
#include <stdlib.h>
using namespace std;
typedef vector<float> vec;
inline vec& operator+=(vec& lhs, const vec& rhs) {
for (size_t i = 0; i < lhs.size(); ++i) {
lhs[i] += rhs[i];
}
return lhs;
}
inline vec operator*(float lhs, vec rhs) {
for (size_t i = 0; i < rhs.size(); ++i) {
rhs[i] *= lhs;
}
return rhs;
}
main1.cpp
的内容:#include "main.h"
// gcc 4.9.2 (-O3): 0m5.965s
int main(int, char**) {
float x = rand();
vec v1(1000);
vec v2(1000);
for (size_t i = 0; i < v1.size(); ++i) {
v1[i] = rand();
v2[i] = rand();
}
for (int i = 0; i < 10000000; ++i) {
v1 += x * v2;
// same as:
//vec y = x * v2;
//v1 += y;
}
return 0;
}
main2.cpp
的内容:#include "main.h"
// gcc 4.9.2 (-O3): 0m2.400s
int main(int, char**) {
// same stuff
for (int i = 0; i < 10000000; ++i) {
for (size_t j = 0; j < v1.size(); ++j) {
v1[j] += x * v2[j];
}
}
return 0;
}
第二个程序的运行速度比第一个程序快得多。我确实理解为什么会这样:第一个程序执行两个循环,而不仅仅是一个循环,它分配了一个临时向量。
但是,我希望编译器能够看到并优化这种东西。还是我做错了什么?
我不记得线性代数库(例如Armadillo)遇到这个问题。他们如何解决这个问题?这是否涉及一些复杂的模板编程,还是有一些简单的方法来帮助编译器对此进行优化?
最佳答案
对于这个问题,有一些超级丑陋的模板元编程解决方案。但是随后,标准委员会发明了右值引用和移动语义的结合。查找这些内容,找到许多解决方案的示例,而没有元编程的荒谬水平。
关于c++ - 链接运算符时的编译器优化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33154161/