c++ - 使用临时变量将单行拆分为多行是否会影响性能,即通过抑制某些优化?

标签 c++

这是一个非常笼统的c++问题。考虑以下两个 block (它们做同样的事情):

v_od=((x-wOut*svd.matrixV().topLeftCorner(p,Q).adjoint()).cwiseAbs2().rowwise().sum()).array().sqrt(); 

MatrixXd wtemp=(x-wOut*svd.matrixV().topLeftCorner(p,Q).adjoint());
v_od=(wtemp.cwiseAbs2().rowwise().sum()).array().sqrt(); 

现在第一个结构感觉更有效率。但这是真的吗, 或者 c++ 编译器会将它们编译成相同的东西(我假设编译器是一个好的编译器并且打开了所有安全优化标志。为了论证 wtemp 的大小适中,比如包含 100k 个元素的矩阵)?

我知道对此的一般答案是“对其进行基准测试然后返回给我们” 但我想要一个笼统的答案。

最佳答案

在两种情况下,您的第二个表达式的效率可能根本低于第一个。

第一种情况是 MatrixXd 类的编写者对 cwiseAbs2() 上的重载做了右值引用。在第一个代码中,我们调用方法的值是一个临时值,在第二个代码中它不是。我们可以通过简单地将第二个表达式更改为来解决此问题:

v_od=(std::move(wtemp).cwiseAbs2().rowwise().sum()).array().sqrt();

wtemp 转换为右值引用,并基本上告诉 cwiseAbs2() 它所调用的矩阵可以作为暂存空间重复使用。只有如果 MatrixXd 类的编写者实现了这一特定功能,这才有意义。

如果 MatrixXd 类的编写者对几乎所有列出的操作都使用表达式模板,则它可能从根本上变慢的第二种可能方式。这种技术构建了操作的解析树,并且只有在最后将结果分配给一个值时才最终确定所有这些操作。

一些表达式模板被编写来处理能够存储在这样的中间对象中:

auto&& wtemp=(x-wOut*svd.matrixV().topLeftCorner(p,Q).adjoint());
v_od=(std::move(wtemp).cwiseAbs2().rowwise().sum()).array().sqrt(); 

第一行存储表达式模板 wtemp 而不是将其计算为矩阵,第二行使用第一个中间结果。如果您尝试执行上述操作,其他表达式模板实现会严重崩溃。

表达式模板也是矩阵类编写者必须专门实现的东西。这又是一种有点晦涩的技术——它主要用于通过看似廉价的操作(如字符串追加)来扩展缓冲区的情况。

除非这两种情况,否则性能上的任何差异都将纯粹是“噪音”——没有理由先验地期望编译器或多或少地被其中一种情况混淆。

而且这两者都是相对先进/现代的技术。

它们都不会在库作者明确完成的情况下“由编译器”实现。

关于c++ - 使用临时变量将单行拆分为多行是否会影响性能,即通过抑制某些优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26631281/

相关文章:

c++ - 隐式转换为 std::vector

c++ - C++:为什么我必须以这种方式将声明声明为double?

C++、Googlemock - 测试本地对象

c++ - 为什么 std::move 不在默认 move 构造函数中将源变量更改为默认值?

c++ - Pytorch C++ 运行时错误 : Expected object of device type cuda but got device type cpu for argument #1 'self' in call to _th_index_select

c++ - 给定的 float 位于哪个段?

C++为什么vector初始化会调用copy constructor

c++ - 是否可以对 dll 进行更改,同时保持与预编译的可执行文件的兼容性?

c++ - 奇怪的fstream问题

c++ - 如何在 Linux 中查找软盘\CD 扇区大小?