English 中文(简体)
了解移动语义相对于模板元程序化的好处
原标题:Understanding the benefits of move semantics vs template metaprogramming

I 阅读了一些关于C++11中移动语义的说明,我想知道在什么背景下可以使用它。目前,许多 C++ 数学库使用模板元方案来延迟评价。

如果M= A+B+C*D, M、A、B、C和D是矩阵,模板元方案设计可以避免无用的复制。移动语义是否更方便于进行这类事情?

如果没有,在什么背景下使用语义。如果是,那么与模板用于此类目的的元方案相比,有什么差异/限制?

最佳回答

我对这些优化没有专家,但据我了解,通过定义矩阵类型上的算术操作员,您谈论的延迟评价技术是工作,例如,A+B+C*D 不返回矩阵,它返回一个可以转换为矩阵的代理对象。当它被指定到 M 时,就会发生这种情况,转换代码将以最有效的方式计算结果矩阵中的每个单元格,即图书馆设计师可以生成,避免临时矩阵对象。

所以,假设程序包含 M = A + B + C * D;

如果您除了用通常的方式执行 operator@/code> 来执行 operator@/code>之外, 没有其他聪明的动作, 您就会得到类似的东西, 通常情况下, C+/ 03 式的复制除去被踢入 :

Matrix tmp1 = C;
tmp1 *= D;
Matrix tmp2 = A;
tmp2 += B;
tmp2 += tmp1;
M = tmp2;

随着评估的延迟,你可能会得到更像:

for (int i = 0; i < M.rows; ++i) {
    for (int j = 0; j < M.cols; ++j) {
        /* not necessarily the best matrix multiplication, but serves to illustrate */
        c_times_d = 0;
        for (int k = 0; k < C.cols; ++k) {
            c_times_d += C[i][k] * D[k][j];
        }
        M[i][j] = A[i][j] + B[i][j] + c_times_d;
    }
}

而"一无所知"的代码 会做一些不同的 额外的循环 和更多的任务。

据我所知,在此情况下,移动语义没有多大帮助。 您写入的文字中没有任何内容允许我们从 A , B , C D 移动,所以我们最后将使用以下等同的方法:

Matrix tmp1 = C;
tmp1 *= D;
Matrix tmp2 = A;
tmp2 += B;
tmp2 += std::move(tmp1);
M = std::move(tmp2);

移动语义除上一个位数外没有帮助, 在那里操作员的 rvalu 版本可能比普通操作员更好。 如果您写入 < code> std:: move( A) + std:: move( B) + std:: move( C) * std:: move( D) , 因为我们不需要复制 < code> C 或 < code> A < /code >, 但我仍然认为结果不如延迟评价代码好。

移动语义对于延迟评价所提供的优化的某些重要部分毫无帮助:

1)由于评价延迟,中间结果从不需要以完整的矩阵形式实际存在。移动语义无法避免编译者在某个时刻创建完整的内存矩阵 < code> A+B

2) 延迟评价后,我们可以在完成整个表达式计算之前开始修改 M 。移动语义不会帮助编译者重新排序修改:即使汇编者足够聪明,能够发现潜在的机会,但如果存在任何被抛出例外的危险,则非时空 < em> mustt 的修改应保持正确的顺序,因为如果 A+B+C* D < /code> 投出,那么 M < /code> 的任何部分必须保留在启动时。

问题回答

我认为你所谓的“模板元程序设计”更精确的术语是表达式模板

如果您的矩阵动态地分配数据, 移动语义可以帮助将数据从对象转移到表达式中生成的物体( 包括向/ 从温度), 例如 :

M = A + B + C*D

另一方面,表达式模板将完全消除临时安排。

如果您的矩阵不动态地分配数据(例如,如果数据是固定大小和小的),移动语义将完全无助于您的性能。

将表达式模板应用到矩阵库将产生最高性能。 这也是一个非常困难的实施技术。 移动语义比较容易执行, 并且除了表达式模板( 如果有资源, 如内存可以传输) 外, 还可以完成 。

摘要:

移动语义不会消除临时状态, 但会在临时状态之间转移动态分配的内存, 而不是重新分配 。

表达式模板将消除时间节奏 。

它们是两种不同的野兽。 移动语义学是指从即将被摧毁的价值中挪用资源。 当与“大”字眼(需要动态内存分配的)表达模板混在一起时,人们会仅仅适合这样的记忆,而不是复制将要销毁的东西。

移动语义对于本质上非可复制 (类似 fsreams) 对象也很重要,但对于使 move 具有意义的对象来说,这些物体也很重要。

移动语义适用于在物体内管理的资源,并用来避免在创建临时物体时不必要地获取/释放资源(即动态分配的内存是一种资源)。

模板模板元方案设置运行于在堆叠上分配的结构结构(因为它需要汇编对操作软件的时间评价) 。 您可以使用它来避免运行时间的计算, 用于在堆叠时间计算操作 。

移动语义是动态的, 表达式模板不是 。 您不能使用表达式模板, 表达式模板是一个分布在多个语句中的表达式, 有些表达式只有在月亮是蓝色时才被评估, 而移动语义可以 。





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?