c++ - 编译器优化忽略循环中的非无效函数调用
问题描述
我正在对一些代码进行基准测试,但是当我设置优化标志时,编译器bh_b = bh_b + bh_a + bh_a + bh_a + bh_a;
会在循环中忽略我的函数调用()。当我删除优化标志时,代码工作正常。
我使用表达式模板编写了我的 Matrix 类
很抱歉最后一篇文章不可复制。
代码
- 主文件
#include <iostream>
#include <chrono>
#include "matrix.h"
int main(){
int calc_num = 100000;
Matx<double, 3, 3> bh_a(1, 0, 0,
0, 1, 0,
0, 0, 1);
Matx<double, 3, 3> bh_b(0, 0, 0, 0, 0, 0, 0, 0, 0);
auto t_begin = std::chrono::high_resolution_clock::now();
for(int i=0; i<calc_num; ++i)
bh_b = bh_b + bh_a + bh_a + bh_a + bh_a; // this part
auto t_end = std::chrono::high_resolution_clock::now();
std::cout << "Elapsed: " << std::chrono::duration_cast<std::chrono::microseconds>(t_end - t_begin).count() << "us" << std::endl;
for(int i=0; i<bh_b.cols; ++i) {
for (int j = 0; j < bh_b.cols; ++j)
std::cout << bh_b(i * bh_b.cols + j) << ' ';
std::cout << std::endl;
}
return 0;
}
- 矩阵.h
#ifndef UNTITLED3_MATRIX_H
#define UNTITLED3_MATRIX_H
template <typename T, typename E>
class MatExpr{
public:
const T& operator () (int i) const { return static_cast<E const&>(*this)(i); }
};
template<typename T, int m, int n>
class Matx : public MatExpr<T, Matx<T, m, n>> {
public:
enum {
rows = m,
cols = n,
channels = rows*cols,
shortdim = (m < n ? m : n)
};
Matx(T v0, T v1, T v2, T v3, T v4, T v5, T v6, T v7, T v8) : val{v0, v1, v2, v3, v4, v5, v6, v7, v8} {}
template <typename E>
Matx(MatExpr<T, E> const& expr){
for(int i=0; i<channels; ++i) val[i] = expr(i);
}
const T& operator () (int i) const { return val[i]; }
T val[m*n];
};
template <typename T, typename E1, typename E2>
class MatOp : public MatExpr<T, MatOp<T, E1, E2>> {
private:
E1 const& u;
E2 const& v;
public:
MatOp(E1 const& u, E2 const& v) : u(u), v(v) {}
const T& operator () (int i) const { return u(i) + v(i); }
};
template <typename T, typename E1, typename E2>
MatOp<T, E1, E2>
operator + (MatExpr<T, E1> const& u, MatExpr<T, E2> const& v){
return MatOp<T, E1, E2>(*static_cast<const E1*>(&u), *static_cast<const E2*>(&v));
}
#endif //UNTITLED3_MATRIX_H
- CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(untitled3)
set(CMAKE_CXX_STANDARD 14)
add_executable(untitled3 main.cpp)
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2" ) // Compiler optimization flag
输出
- 无优化(正确输出)
Elapsed: 32308us
400000 0 0
0 400000 0
0 0 400000
-O1
Elapsed: 16268us
0 0 0
0 0 0
0 0 0
-O2
,-O3
Elapsed: 1us
0 0 0
0 0 0
0 0 0
编译器
- 在 Mac OS 上使用 CLion
➜ ~ clang --version
Apple clang version 11.0.0 (clang-1100.0.33.17)
Target: x86_64-apple-darwin19.4.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
解决方案
代码包含未定义的行为。
在这条线上
const T& operator () (int i) const { return u(i) + v(i); }
您正在返回一个临时地址(因为operator +
会产生一个临时地址)。
同样在这里
const T& operator () (int i) const { return static_cast<E const&>(*this)(i); }
如果它调用上述方法,也可以产生一个临时的。
一个可能的解决方法是按值返回它(不知道这是否是正确的选择)。
推荐阅读
- excel - 在 Python 中循环遍历 Excel 工作表
- c# - 统一没有收到数据响应 - 获取请求标头问题
- wpf - 信息亭模式下未显示虚拟键盘
- javascript - React - 数组 if-else 过滤器
- elasticsearch - Express-cassandra elassandra 按 geo_point 排序
- aslr - 使用 ASLR(-pie) 编译会导致可执行文件被视为共享库
- html - 如何将大尺寸按钮放在小尺寸按钮旁边?
- php - PHP 检查具有相同输入名称的多个输入的 $_POST
- android - 如何使用 Json 映射器中的列表正常工作并处理异常?
- reactjs - 更改选择后默认选中不起作用