【问题标题】:Performance question: Inverting an array of pointers in-place vs array of values性能问题:就地反转指针数组与值数组
【发布时间】:2011-01-11 10:29:03
【问题描述】:

问这个问题的背景是我正在求解一个线性方程组(Ax=b),其中 A 是一个矩阵(通常尺寸小于 100x100),x 和 b 是向量。我使用的是直接方法,这意味着我首先反转 A,然后通过 x=A^(-1)b 找到解决方案。这一步在一个迭代过程中重复,直到收敛。

我现在使用矩阵库 (MTL4) 的方式:
对于每次迭代,我将 A(值)的所有系数复制到矩阵对象中,然后反转。这是最简单、最安全的选择。

改用指针数组:
对于我的特殊情况, A 的系数恰好在每次迭代之间更新。这些系数存储在不同的变量中(有些是数组,有些不是)。如果我将 A 设置为包含指向这些系数变量的指针的数组,然后就地反转 A,是否有可能提高性能?

最后一个选项的好处是,一旦我在第一次迭代之前在 A 中设置了指针,我就不需要在连续迭代之间复制任何值。在 A 中指向的值将在迭代之间自动更新。

所以在我看来,性能问题归结为:
- 矩阵求逆过程所用的时间大致相同,假设取消引用指针并不昂贵。
- 指针数组不需要用于包含值的矩阵 A 的额外内存。
- 指针数组选项不必在每次迭代之间复制 A 的所有 NxN 值。
- 指向指针数组选项的值通常不在内存中排序。希望所有值在内存中都相对接近,但 *A[0][1] 通常不在 *A[0][0] 等旁边。

对此有什么意见吗?最后一句话是否会对性能产生负面影响,从而权衡积极的性能影响?

【问题讨论】:

    标签: c++ performance pointers matrix inversion


    【解决方案1】:

    测试,测试,测试。

    尤其是在数值线性代数领域。有许多效果在起作用,这就是为什么有许多优化的库可以为您解决这个负担。

    需要考虑的一些影响:

    • 内存局部性和缓存效果
    • 多线程效果(一些在单核运行时最佳的算法,在使用多个内核时会导致内存冲突/缓存驱逐)。

    没有什么可以替代测试。

    【讨论】:

    • 是的,谢谢,我同意。实际上,我已经为测试做好了一切准备,只是我需要做一些更改才能使其正常工作。它并不像第一篇文章中所说的那么简单。这就是我想问的原因;如果它有很大的潜力,是否值得投入大量测试的努力。
    • +1 用于测试和缓存效果。根据定义,指针将使用大约两倍的内存,这会损害缓存性能。
    • 我已经看到,在幼稚的缓存不感知实现和关注内存访问顺序的实现之间,性能差异约为 80 倍。 Linux 上有两个很好的工具可以使用它,一个叫做 kcachegrind(它是 valgrind 的前端,一个很棒的全能内存分析器和调试器引擎),另一个是 OProfile - 有很多 CPU 性能计数器可供观察和观察了解缓存未命中和数字电子设备如何影响您的表现。
    【解决方案2】:

    这里有一些cmets:

    • 用于求逆的函数是否能够处理指针矩阵而不是值?如果它没有意识到它必须做一个间接的,各种奇怪的效果可能会发生。
    • 进行就地矩阵求逆时(意味着求逆矩阵覆盖输入矩阵),所有输入系数将被新值覆盖,因为矩阵求逆不能通过重新排序来完成矩阵的元素。
    • 在反演过程中,任何输入系数都不能被外部过程更改。所有此类更新都必须在迭代之间执行。

    因此,当您选择指针解决方案时,您会得到以下权衡:

    • 构成矩阵 A 的系数不能再与矩阵求逆异步计算。
    • 必须为每次迭代重新计算所有系数(当您使用就地求逆时,意味着反矩阵使用与输入矩阵相同的内存),或者您仍然必须使用矩阵N x N 个值来保存反转的结果。

    【讨论】:

    • 感谢您的 cmets。是的,我已经更改了一个 LU 反转函数来处理指针矩阵。而且,由于线性化方程系统用牛顿法表示非线性系统,系数的更新必须在迭代之间发生。 IE。即使我们想要,矩阵系数也不能异步更新。此外,每次迭代都会重新计算所有系数(通过第三方软件)。因此,您的 cmets 被考虑在内,但是当 SAME 系数应该在矩阵中的多个位置时,我看到了一些挑战。然后我需要额外的内存来存储这些......
    【解决方案3】:

    您在这里得到了很好的答案。我唯一要补充的是一些关于性能的一般经验。

    您正在考虑先验性能。这是合理的,但真正的回报是后验的。换句话说,在运行代码告诉您之前,您无法确定真正的优化机会在哪里。

    您不知道大部分时间是否会花在矩阵求逆、乘法、复制矩阵、取消引用或其他方面。人们可以猜测。如果我不得不猜测,那将是矩阵求逆,因为它是 100x100。 但是,我无法猜测的其他事情可能更大。 Guessing 的记录很差,尤其是当您可以找出时。

    Here's an example of what I mean.

    【讨论】:

      猜你喜欢
      • 2013-10-12
      • 2012-03-20
      • 1970-01-01
      • 2015-01-12
      • 2010-10-07
      • 2017-08-26
      • 1970-01-01
      • 2016-03-19
      • 2019-04-03
      相关资源
      最近更新 更多