链接操作符时的编译器优化
Compiler optimization when chaining operators
我重载了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;
}
第二个程序比第一个程序运行得快得多。我确实理解为什么会这样:第一个程序不是只有一个循环,而是进行了两个循环,并分配了一个临时vector。
但这是我希望编译器看到和优化的那种东西。还是我做错了什么?
我不记得在线性代数库(例如Armadillo)中遇到过这个问题。他们如何解决这个问题?这是否涉及一些复杂的模板编程,或者有一些简单的方法来帮助编译器优化它?
有一些非常丑陋的模板元编程解决方案来解决这个问题。但是后来标准委员会发明了右值引用和移动语义的组合。查找这些,并找到许多解决方案的示例,而不需要荒谬的元编程级别。
相关文章:
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 这个C++编译器优化(在自身的实例上调用对象自己的构造函数)的名称是什么,它是如何工作的?
- VS2017调试器:没有地址,可能是由于编译器优化
- 何时允许编译器优化复制构造函数
- 如何使用 GCC 编译器优化创建静态库?
- 为什么 std::chrono 在测量循环和编译器优化的并行 OpenMP 的执行时间时不起作用?
- 是否允许编译器优化掉局部易失性变量
- 删除编译器优化并在发布中启用 pdb 文件
- 静态 constexpr 的编译器优化
- 如何让MSVC编译器优化多步POD初始化?
- 按位不操作的编译器优化
- 模板专用化与编译器优化
- 编译器优化:G 比英特尔慢
- 运算符重载关联性编译器优化
- Intel OpenCL编译器:优化结构使用情况
- C 中编译器优化的影响
- 视觉C++ 2017 错误?编译器优化表达式
- 虚拟功能编译器优化C
- 未定义的行为确实有助于现代编译器优化生成的代码