【问题标题】:MPI: cores or processors?MPI:核心还是处理器?
【发布时间】:2011-08-13 10:44:04
【问题描述】:

您好,我是 MPI 菜鸟,所以请多多包涵。 :)

假设我有一个名为 foo.c 的 MPI 程序,我使用

运行可执行文件

mpirun -np 3 ./foo

现在这意味着程序将使用 3 个处理器并行运行(每个处理器 1 个进程)。但是由于当今大多数处理器都有多个内核,(假设每个处理器有 2 个内核)这是否意味着程序将在 3 个内核或 3 个处理器上运行?

这可能与我对内核和处理器之间的真正区别理解不深有关,所以如果您还可以解释一下,那将有所帮助。

谢谢。

【问题讨论】:

  • 如果你在 Linux 机器上 cat /proc/cpuinfo,你会看到每个超线程都被算作一个处理器,这与 MPI 对“处理器”的使用不谋而合。

标签: mpi


【解决方案1】:

mpirun 将在机器上执行许多“进程”。执行这些进程的 CPU 或核心取决于操作系统。 在 N cpu 机器上,每个 cpu 上有 M 个内核,您有空间让 N*M 个进程全速运行。

但是,通常情况下:

  • 如果您有多个内核,每个进程将在单独的内核上运行
  • 如果你要求的进程多于可用的 core*cpus,一切都会运行,但效率会降低(是的,你可以在单 cpu 单核机器上运行多进程作业...)李>
  • 如果您使用的队列系统或预配置的 MPI 系统存在远程计算机列表,则分配将分布在远程计算机上。

(根据 mpi 实现,可能有一些选项可以强制使用特定的 cpu 或核心,但您不必担心)。

【讨论】:

  • 感谢您的回答,它也帮助了我!
【解决方案2】:

将进程分配给内核和处理器由操作系统和 MPI 实现处理。在桌面上运行的操作系统通常会将每个进程放在不同的核心上,在运行时可能会重新分配进程。在大型系统(例如超级计算机或集群)中,分发由 SLURM 等资源管理器处理。但是,如果发生这种情况,每个内核都会分配一个或多个进程。

关于硬件,一个内核一次只能运行一个进程。超线程等技术允许多个进程共享单个内核的资源。在某些情况下,每个内核有两个或多个进程是最佳的。例如,如果一个进程正在执行大量文件 I/O,则另一个进程可能会在第一个进程挂起读取或写入时代替它进行计算。

简而言之,给 MPI 你想要执行的进程数。这些过程的分配然后对用户透明地处理。您使用的进程数应由应用程序的要求(2 的幂、要读取的文件数)、可用内核数以及应用程序每个内核的最佳进程数来确定。

【讨论】:

    【解决方案3】:

    操作系统调度程序将尝试为多核系统中的并行应用程序进程或多处理器系统中的独立处理器优化分配单独的内核。

    有趣的案例是一个多核多 cpu 系统。同样,您可以让 OS 调度程序为您执行此操作,或者您可以强制(逻辑/物理)核心关联到您的进程以将它们绑定到特定核心。

    【讨论】:

      【解决方案4】:

      mpirun 命令使用主机列表。如果不指定它,它可能会使用“localhost”并在那里运行所有进程。如果你运行 3 个进程并且你有一个 4 核机器,你可能会得到很好的加速,因为操作系统通常会将它们放在不同的核心上。如果你只有两个核心,那么一个核心会得到两个进程。

      前面的说法不完全正确,因为允许操作系统移动进程,所以您可能希望使用numactl 将它们绑定到核心。

      如果您在多节点集群上,那么设置良好的 mpi 将生成一个主机文件,其中每个节点出现的次数与它的核心数一样多。因此,在每个节点有 8 个核心的 4 节点集群上,您可以请求多达 32 个进程并期望接近完美的加速。 (当然,如果您的代码和算法允许。)在该集群上请求 9 个进程可能会将 8 个进程放在一个节点上,而将第 9 个进程放在另一个节点上,这当然不利于性能。您希望您的集群软件附带一个 mpirun,它可以更好地分散进程。

      【讨论】:

        【解决方案5】:

        从 MPI 作业的性能来看,有一些明确的规则: 1)如果您的代码是纯 MPI 代码(BLAS 未使用 openMP 调整),请关闭超线程并将每个节点的任务数设置为节点的核心 2)如果您的代码是MPI + openMP,您可以将PPN(每个节点的进程)设置为节点的核心,并将OMP_NUM_THEADS设置为2(如果每个核心有两个硬件线程) 3)如果您的代码是 MPI+openMP 并且您的集群很大,那么您可以将 PPN(每个节点的进程)设置为 1,将 OMP_NUM_THEADS 设置为逻辑 CPU 编号以节省通信开销

        【讨论】:

          【解决方案6】:

          为了提供一个有用的框架,我会考虑这个层次结构:

          • 主板可以容纳一个或多个芯片/骰子;
            • 一个芯片/裸片可以包含一个或多个内核(独立 CPU);
              • 一个 CPU 可以同时处理一个或多个线程(我所知道的多线程由两个线程组成)

          在早期,您通常拥有一块主板和一块芯片,一个 CPU 运行一个线程。一次只能处理一个进程,而参与的硬件集称为处理器。软件(要运行的任务)和硬件(运行任务的设备)之间存在一对一的映射。

          流程绝对是一个软件的概念。 “线程”很简单,是并行并发计算上下文中的“进程”规范。现在处理器可以指物理设备以及它的扩展处理能力(再次是多线程,这可以肯定是一种技术实现)。例如,您可以让机器在主板上有两个芯片,每个芯片有四个内核/CPU,并且每个内核/CPU 同时运行两个线程。然后,您将能够运行 2x4x2=16 个进程(当然不会超额订阅资源)。

          您引用的 MPI 语法针对 进程(选项 np)或线程(如果您愿意)。 man mpirun 的描述部分甚至将进程称为“插槽”(例如,请参阅主机文件的规范)。

          槽表示一个节点上可能执行的进程数。

          这种用法听起来像是当时标准的硬件单元和软件单元之间密切对应的传统。 “插槽”最初是一种材料/硬件特征,与“插槽”一词不同,它有时会经历类似的语义变化。

          所以我确实对你的困惑感到很同情。如果你是 Linux 用户,可以可视化cat /proc/cpuinfo 的报告。这些行指的是四个处理器中的一个名为“2”的处理器:

          processor   : 2
          ...
          physical id : 0
          siblings    : 4
          core id     : 2
          cpu cores   : 4
          

          他们说在这台机器上我只得到了一个芯片(因为'phyical id'在整个列表中只取一个值,省略了),这个芯片是4个'cpu cores'并且这个芯片是运行四个兄弟姐妹(4 个线程,因此没有多线程)。在这种情况下,有 4 个处理元件和 4 个 cpu 内核。

          在上面的多线程示例中,您会看到 16 个处理器的列表,“物理 id”(芯片)的 2 个值,“cpu cores”等于 4(每个芯片)和 `由于在该芯片上启用了多线程,兄弟姐妹等于 8(每个芯片)。在这种情况下,您的处理器数量是内核的四倍。

          因此,在这个扩展的上下文中,“处理器”表示机器在“进程”上工作的能力,这就是 MPI 和您想要使用的,无论可以启用此功能的内核的数量和功能如何。您只需大致了解这些处理能力的来源。

          另一个有用的 Linux 命令是 lscpu:

          ...
          CPU(s):                4
          On-line CPU(s) list:   0-3
          Thread(s) per core:    1
          Core(s) per socket:    4
          Socket(s):             1
          ...
          

          “插座”确实是主板中插入芯片的物理连接,因此它确实是芯片的别名。这里确实没有多线程。

          感谢https://unix.stackexchange.com/q/146051/132913 其他帖子中的讨论

          【讨论】:

            猜你喜欢
            • 2020-07-05
            • 2012-11-12
            • 2011-04-19
            • 1970-01-01
            • 2011-12-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多