对英特尔 MKL、线程和 MPI 的总体了解

计算科学 并行计算 表现 mpi 英特尔-mkl 多核
2021-11-27 23:27:09

前言

我似乎对 Intels MKL 用户指南给出的在线程应用程序中使用 MKL 的最佳实践建议缺乏基本的了解。那么让我们一起来澄清一下。

措辞和问题

特别是有两种不同的方法来优化数字代码。OpenMP 或消息传递接口 (MPI) - 以及两者的组合。在我看来,MKL 在内部开箱即用地解决了 OpenMP。英特尔建议不要将 OpenMP 并行化与借助 MPI 的手动并行化(例如,更高级别的域分解)相结合(参见此处)。

我现在对在具有许多物理计算单元的多处理器环境(读取集群)中做什么感到困惑。我对这个话题的第一种方法是:

  • 使用 MPI,对问题进行域分解,将小块分配到集群中的所有 CPU,并在MKL without OpenMP那里使用顺序 MKL (= )。

我特别问自己,当仅依赖MKL with OpenMP集群中的多线程 MKL (= ) 时,如何以不同的方式完成:如果矩阵向量积中的一个矩阵太大而无法放入一个计算节点的内存中怎么办?它会被 MKL 自动分布在所有计算节点上吗?

1个回答

没有什么能阻止您自己分解问题并将相关的分区数据按顺序甚至并行输入 MKL。只要您避免数据竞争,它就可以工作,但除非您非常小心如何做到这一点,否则您可能会遇到性能损失。

不鼓励将 OpenMP 代码与 MKL 结合使用的原因是 OpenMP 通常不具备处理嵌套并行性的并行调度挑战的能力(这正在慢慢开始改变)。因此,此限制的开销会导致性能下降。

但是,使用 MPI 执行此操作没有问题,但是您必须非常小心如何设置 MPI 等级中的进程关联性和 OpenMP 中的线程关联性,否则您的性能将再次下降。您应该查看 MPI 文档以及 OpenMP 文档以了解如何正确协调两者。在这里不可能给出一般性的建议,因为还没有标准化的方法来处理这个问题——你必须阅读你的 OpenMP 和 MPI 的文档。

或者,英特尔还发布了一个使用线程构建块 (TBB) 库进行线程化的 MKL 版本。这个库可以非常有效地处理嵌套并行,但是你必须使用 TBB 来实现这一点(虽然可以混合 OpenMP 和 TBB,但不推荐)。这意味着您可以在 TBB 并行化代码中调用 MKL,并且与在 OpenMP 中执行相同操作相比,性能损失更少。

编辑:我应该补充一点,MKL 严格关注单节点性能,因此您以 OpenMP 或 MPI 的形式添加到其中的任何额外并行性都必须自己管理。它不会为您分配矩阵,也不会执行块线性代数。您必须自己阻止矩阵并执行正确的 BLAS 或 LAPACK 调用序列才能获得所需的结果。