估计运行串行/并行代码的时间

计算科学 线性代数 布拉斯
2021-11-26 16:52:54

假设我正在运行一个迭代方法,我粗略估计了它需要多少次迭代,如何最好地估计它将连续运行的时间?

例如,如果我有共轭梯度(对于 Ax=b),如果我知道矩阵维度,我如何估计它将运行多长时间?

具体来说,我想问:

  1. 可以通过忽略缓存和编译器优化来进行粗略的计算,但有没有办法解释它们?当然,对其中的每一个都进行解释是不可能的,但至少是重要的。我对我的另一个问题上发布的分析很感兴趣,并希望能够找出其他算法的估计值,但有更严格的界限。
  2. 您如何找出优化运营的成本?例如,MatVecs 是O(N2). 在计算 BLASDGEMV时,您假设什么前导常数?

3. 既然我知道它在串行模式下运行的时间,我如何估计并行模式下的时间?我研究了阿姆达尔定律,但我不确定如何将它用于迭代方法。 已回答

PS:在线PDF(或任何参考资料)以了解更多信息会很棒!


更新:为了解决以 DGEMV 为瓶颈的 10000x10000 CG 问题,我执行了以下操作:我将大小从 2k x 2k 到 19k x 19k 的矩阵绘制为时间(对于随机 matvec)与大小^2 的关系图。我将时间乘以 2.13E9(对于 GHz),得出总操作与大小^2 的关系图。然后我逼近这条线的斜率,这给了我 Operations = (slope) * N^2。在我的例子中,常数是 45.45454545 并且图表是笔直的。对于 10k x 10k CG 问题,每次迭代需要 1 个 matvec(无预处理器)和 550 次这样的迭代。总共有 550 个 matvecs550*45.45*N^2 次操作550*45.45*1e8 / 2.13e9 秒1000 秒。

事实证明(我已要求 SO 的版主删除该问题):

  • 我没有考虑每秒(和每个时钟)的指令。因此,我的实际运行时间是 120 秒(对于 10k x 10k CG),而我的计算是 1000 秒!我如何计入 IPS/IPC?

  • 45 对于 MatVecs 来说是一个太大的领先常数。理想情况下,它应该在 2 左右。我在这个计算中哪里出错了?

如何改进我的理论预测?

1个回答
  1. 很难对缓存效果和优化进行有意义的分析,因为从中获得的好处取决于实现。(例如,您是按行还是按列访问内存?这将影响内存局部性和缓存命中率。内部循环是否可以展开?您的平台有哪些内在函数?)
  2. 查找 BLAS 实现的常量是非常特定于平台的,因此您可能应该尝试一些基准测试(尝试一些大小为 N、N^2、N^3 等的数据集)
  3. 在此处找到的论文“多核时代的阿姆达尔定律”是对阿姆达尔定律的一个很好的介绍,并对异构环境进行了一些修改一般来说,为了粗略估计,尽量将操作分为并行操作、通信成本(并不总是适用)和串行操作。然后,您可以使用阿姆达尔定律来查看您可能期望什么样的加速。

虽然先验运行时分析是一个有用的工具,但在我看来,确定常数等最好凭经验完成。在编译和运行科学应用程序时,后台会发生很多微妙的事情。