保证检测临时>命名点
Guaranteed Detection of Temporary->Named Points
假设您编写了一个矩阵类,其中包含一些操作:
class matrix
{
public:
double operator()(size_t i, size_t j) const;
...
};
matrix operator*(const matrix &lhs, const matrix &rhs);
...
延迟一些矩阵表达式的求值是有意义的:m0 * m1 * m2 * m3 * m4(这是一系列四个operator*
调用)可以受益于使用动态规划矩阵链乘法算法;非常常见的m0 * m1t具有非常有效的dgemm
实现,等等。
class matrix
{
private:
/*
* Pointer to an abstract base class - either an actual matrix,
* or an expression tree. */
std::shared_ptr<matrix_imp> m_imp;
public:
// Forces compaction -
double operator()(size_t i, size_t j) const;
...
};
/* Lazy; creates a matrix with an expression tree using the
* internals of lhs and rhs. */
matrix operator*(const matrix &lhs, const matrix &rhs);
...
每个矩阵都有一个指向基类对象的指针,基类对象可以是一个实矩阵,也可以是一个复杂的表达式树。每个操作都试图使用对内部实现最惰性的更改来形成一个矩阵。有些操作别无选择,只能实际求值,压缩表达式树,并将内部实现设置为实际的矩阵。
问题是,在实践中,这在非常常见的情况下会导致巨大的内存开销。假设您从文件中读取一个长而窄的矩阵x = xp x q, p>> q,将xt x存储在一个变量中,并丢弃x。对于惰性求值,内存为pq>> qq。在循环中加载这些,这是一个严重的问题。(当然,客户端代码调用operator()
可以在每次加载后强制压缩,但是在没有算法证明的情况下要求压缩是丑陋的,并且容易出错。)
最初,我认为move函数对于自动压缩来说是一个很好的点——它正是临时对象变成命名对象的地方,而命名对象会导致内存消耗增加,所以
matrix(matrix &&other); // <- Force compaction only here
似乎可以解决所有问题,例如
auto res = // <- temp becoming named
a * // temp
b * // temp
c + // temp
2 * // temp
d;
但是可以指望吗?例如,考虑
matrix load_xtx(const string &f_name)
{
matrix x = ...
return x.t() * x;
}
auto xtx = load_xtx("foo.hdf5"); // (*)
是禁止编译器在(*)
中做类似于它对NRVO所做的事情,即只是在适当的地方构造它?即使没有,编译器可能会在其他情况下优化掉一些东西吗?
由于"内部指针"方法不能提供延迟求值所需的所有灵活性,因此c++数值库使用的典型解决方案是定义实现延迟求值机制的专用类。c++中的惰性求值问题及其最佳答案展示了这种设计的基础知识和一些示例代码。
虽然我不是专家,但我认为这种体系结构的好例子是数字库Eigen(这里有一些关于其实现的细节)和Blitz++,它们严重依赖于模板(我没有在网上找到说明其内部结构的更新文档,但本文描述了其引擎的一部分,并提供了对"表达式模板"技术的更广泛的概述)。
- 使用CMake检测支持的C++标准
- 当套接字连接断开时检测C/C++Unix
- C/C++预处理器是否可以检测一些编译器选项
- WMI检测进程创建事件-c++
- 基于树莓pi的tensorflow lite量化ssd目标检测
- 下面是我为检测链接列表中的循环而制作的代码
- 落砂模拟碰撞检测C++和SFML
- EASTL矢量<向量<int>>连续的
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 为什么C++编译器没有检测到正确声明的类?
- 检测win32服务创建和删除的最佳方法
- 正在LLVM中检测整数比较条件
- 如何在鼠标挂钩过程中检测拖动
- 位移操作和位掩码未检测到重复字符
- 检测 COFF 对象文件中C++内联符号
- qmake:检测目标位宽(32 位或 64 位)
- 增强精神解析器规则以检测语句中的特殊结尾
- 用于C++的静态二进制检测或二进制重写工具和框架
- Tensorflow对象检测在Python和C++(OpenCV)之间有不同的结果
- C++中的张量流对象检测