7. 加速性能
7.1.基准测试
7.2.测试性能
7.3.通用技巧
7.4.加速器包
LAMMPS 中添加了各种pair_style、fixes、compute 和其他命令的加速版本,其运行速度通常比标准非加速版本更快。有些需要您的系统上存在适当的硬件,例如GPU 或 Intel Xeon Phi 协处理器。
所有这些命令都包含在 LAMMPS 提供的软件包中。软件包页面上提供了包的概述。
以下为当前 LAMMPS 中的加速器包:
GPU Package | 通过 CUDA、OpenCL 或 ROCm HIP 适用于 GPU |
INTEL Package | 适用于 Intel CPU 和 Intel Xeon Phi |
KOKKOS Package | 适用于 NVIDIA GPU、Intel Xeon Phi 和 OpenMP 线程 |
OPENMP Package | 用于 OpenMP 线程和通用 CPU 优化 |
OPT Package | 通用 CPU 优化 |
反过来,LAMMPS 目前通过列出的软件包对三种硬件提供加速支持:
Many-core CPUs | INTEL, KOKKOS, OPENMP, OPT 软件包 |
GPUs | GPU, KOKKOS 软件包 |
Intel Phi/AVX | INTEL, KOKKOS 软件包 |
哪个包对于您的硬件来说速度最快可能取决于您正在运行的大小问题以及输入脚本调用的命令(加速和非加速)。虽然这些文档页面包含性能指南,但尝试适合您的硬件的不同软件包是无可替代的。
任何加速样式都与相应的标准样式具有相同的名称,只是附加了后缀。否则,使用该样式的命令的语法是相同的,它们的功能是相同的,并且它产生的数值结果也应该是相同的,除了精度和舍入效果之外。
例如,所有这些样式都是 Lennard-Jonespair_style lj/cut 的加速变体:
-
pair_style lj/cut/gpu
-
pair_style lj/cut/intel
-
pair_style lj/cut/kk
-
pair_style lj/cut/omp
-
pair_style lj/cut/opt
要查看当前可用于特定样式的加速样式,请在命令样式页面中找到样式名称(fix,compute,pair等),并查看列出的后缀(g、i、k、o、t) 。各个命令的文档页面(例如pair lj/cut 或fix nve)还列出了该样式可用的任何加速变体。
要在 LAMMPS 中使用加速器包及其提供的一种或多种样式,请按照以下常规步骤操作。详细信息因软件包而异,并在上面列出的各个加速器文档页面中进行了解释:
build the accelerator library | only for GPU package 仅适用于 GPU 封装 |
install the accelerator package | make yes-opt, make yes-intel, etc |
add compile/link flags to Makefile.machine in src/MAKE | only for INTEL, KOKKOS, OPENMP, OPT packages |
re-build LAMMPS 重建LAMMPS | make machine 制造机器 |
prepare and test a regular LAMMPS simulation | lmp_machine -in in.script; mpirun -np 32 lmp_machine -in in.script |
enable specific accelerator support via ‘-k on’ command-line switch, | only needed for KOKKOS package |
set any needed options for the package via “-pk” command-line switch or package command, | only if defaults need to be changed |
use accelerated styles in your input via “-sf” command-line switch or suffix command | lmp_machine -in in.script -sf gpu |
请注意,前 4 个步骤可以通过适当的 make 命令调用作为单个命令来完成。这在 Packages 文档页面上进行了讨论,其使用在各个加速器部分中进行了说明。通常,这些步骤只需完成一次,即可创建使用一个或多个加速器包的可执行文件。
最后 4 个步骤都可以在启动 LAMMPS 时从命令行完成,而无需更改输入脚本,如各个加速器部分所示。或者您可以将包和后缀命令添加到输入脚本中。
注:除了少数例外,您可以构建一个安装了所有加速器包的 LAMMPS 可执行文件。但请注意,INTEL 和 KOKKOS 软件包要求您在针对特定平台进行构建时选择其硬件选项之一。 IE。 INTEL 封装的 CPU 或 Phi 选项。或者 KOKKOS 包的 OpenMP、CUDA、HIP、SYCL 或 Phi 选项。或者 GPU 包的 OpenCL、HIP 或 CUDA 选项。
这些都是例外。您不能使用以下命令构建单个可执行文件:
-
INTEL Phi 和 KOKKOS Phi 选项
-
INTEL Phi 或 Kokkos Phi 选项以及 GPU 包
如上所述,LAMMPS 网站的基准页面给出了多个标准 LAMMPS 基准问题的各种加速器包的性能结果,作为不同硬件平台上问题大小和计算节点数量的函数。
以下是各种软件包提供的内容的简要总结。详细信息位于各个加速器部分。
- 带有“gpu”后缀的样式是 GPU 包的一部分,可以在 Intel、NVIDIA 或 AMD GPU 上运行。 GPU 的加速取决于多种因素,这些因素将在加速器部分讨论。
- 带有“intel”后缀的样式是 INTEL 包的一部分。除了全双精度之外,这些样式还支持矢量化单精度和混合精度计算。在极端情况下,这可以使 CPU 加速超过 3.5 倍。该软件包还支持英特尔(R) 至强融核(TM) 协处理器的“卸载”模式加速。根据硬件配置,这可能会导致超过 2 倍的额外加速。
- 带有“kk”后缀的样式是 KOKKOS 包的一部分,可以在多核 CPU、NVIDIA 或 AMD GPU 或 Intel Xeon Phi 上以“本机”模式运行 OpenMP。正如 KOKKOS 加速器页面上所讨论的,加速取决于多种因素。
- 带有“omp”后缀的样式是 OPENMP 包的一部分,允许使用 OpenMP 在多线程模式下运行对样式。当使用比核心更少的 MPI 进程时,这对于具有高核心数量的节点非常有用,例如当使用 PPPM 运行以便 FFT 在较少的 MPI 处理器上运行时,或者当许多 MPI 任务会使通信的可用带宽过载时。
- 带有“opt”后缀的样式是 OPT 包的一部分,通常可以将 CPU 上的模拟成对计算速度加快 5-25%。
各个加速器包文档页面解释了:
- 加速包需要哪些硬件和软件
- 如何使用加速包构建 LAMMPS
- 如何通过命令行开关或修改输入脚本来运行加速包
- 预期的加速
- 最佳性能指南
- 限制
7.4.1. GPU 包
GPU 包是由 Mike Brown 在 SNL 和 ORNL(现为英特尔公司)及其合作者,特别是 Trung Nguyen(现为西北大学)开发的。 HSE 大学的 Vsevolod Nikolskiy 和同事通过 HIP 添加了对 AMD GPU 的支持。
GPU 包提供了许多对样式的 GPU 版本以及用于远程库仑学的 kspace_style pppm 的部分。它具有以下一般特征:
- 它旨在利用常见的 GPU 硬件配置,其中一个或多个 GPU 耦合到一个或多个多核 CPU 的多个核心,例如在并行机的一个节点内。
- 基于原子的数据(例如坐标、力)每个时间步都会在 CPU 和 GPU 之间来回移动。
- 邻居列表可以构建在 CPU 或 GPU 上
- PPPM 的电荷分配和力插值部分可以在 GPU 上运行。 FFT 部分需要处理器之间的 MPI 通信,在 CPU 上运行。
- 不同类型的力计算(pair 与bond/angle/dihedral/improper)可以分别在 GPU 和 CPU 上同时执行。
- 它允许 GPU 计算以单精度或双精度或混合模式精度执行,其中成对力以单精度计算,但累积为双精度力向量。
- LAMMPS 特定的代码位于 GPU 包中。它调用 lib/gpu 目录中的通用 GPU 库。该库提供 Nvidia 支持、AMD 支持或更通用的 OpenCL 支持(适用于 Nvidia GPU、AMD GPU、Intel GPU 和多核 CPU)。以便在各种硬件上支持相同的功能。
所需的硬件/软件:
要在 CUDA 模式下编译和使用此包,目前需要有 NVIDIA GPU 并在系统上安装相应的 NVIDIA CUDA 工具包软件(仅在 Linux 上测试,在 Windows 上不支持):
- 检查您是否有 NVIDIA GPU:cat /proc/driver/nvidia/gpus/*/information
- 前往 https://developer.nvidia.com/cuda-downloads
- 安装适合您系统的驱动程序和工具包(不需要 SDK)
- 运行 lammps/lib/gpu/nvc_get_devices(构建 GPU 库后,见下文)以列出支持的设备和属性
要在 OpenCL 模式下编译和使用此包,您当前需要安装 OpenCL 标头和(供应商中立)OpenCL 库。在 OpenCL 模式下,加速取决于是否安装了 OpenCL 可安装客户端驱动程序 (ICD)。可以同时安装多个相同或不同的硬件(GPU、CPU、加速器)。 OpenCL 将这些称为“平台”。 GPU 库将尝试自动选择最合适的平台,但这可以使用 package 命令的平台选项覆盖。运行 lammps/lib/gpu/ocl_get_devices 以获取具有合适 ICD 的可用平台和设备列表。
要为 Intel GPU 编译和使用此软件包,可以使用 Linux 软件包管理器安装 OpenCL 或 Intel oneAPI HPC 工具包。后者还提供优化的 C++、MPI 和许多其他库和工具。查阅:
-
https://software.intel.com/content/www/us/en/develop/tools/oneapi/hpc-toolkit/download.html
如果您没有安装独立 GPU 卡,此软件包仍然可以在某些包含集成 GPU 的 CPU 上提供显着的加速。此外,对于许多 Mac,OpenCL 已包含在操作系统中,并且 Makefiles 位于 lib/gpu 目录中。
要在 HIP 模式下编译和使用此软件包,您必须安装 AMD ROCm 软件。 AMD 目前已弃用 3.5 之前的 ROCm 版本。
使用 GPU 包构建 LAMMPS:
请参阅构建附加页面以获取说明。
从命令行运行 GPU 包:
mpirun
或 mpiexec
命令设置 LAMMPS 使用的 MPI 任务总数(每个计算节点一个或多个)以及每个节点使用的 MPI 任务数。例如。 MPICH 中的 mpirun
命令通过其 -np
和 -ppn
开关来完成此操作。 OpenMPI 也是如此,通过 -np
和 -npernode
。
使用 GPU 包时,不能将多个 GPU 分配给单个 MPI 任务。然而,多个 MPI 任务可以共享同一个 GPU,并且在许多情况下,以这种方式运行会更高效。同样,使用比可用 CPU 核心数量更少的 MPI 任务/节点可能会更有效。如果您创建的 MPI 任务/节点多于 GPU/模式,则会自动将多个 MPI 任务分配给 GPU。例如。每个节点有 8 个 MPI 任务和 2 个 GPU,每个 GPU 将由 4 个 MPI 任务共享。
GPU 包还对 OpenMP 对 CPU 上运行的例程的多线程和矢量化提供有限的支持。这需要使用标志构建 GPU 库和 LAMMPS 以启用 OpenMP 支持(例如 -fopenmp)。 GPU 包中还提供了一些时间积分样式。它们完全在 CPU 上以全双精度运行,但利用多线程和矢量化来提高性能。
使用“-sf gpu”命令行开关,它会自动将“gpu”附加到支持它的样式中。使用“-pk gpu Ng”命令行开关设置 Ng = 要使用的 GPU/节点数。如果 Ng 为 0,则自动选择该数字作为具有最多计算核心数的匹配 GPU 的数量。
lmp_machine -sf gpu -pk gpu 1 -in in.script # 1 MPI task uses 1 GPU
mpirun -np 12 lmp_machine -sf gpu -pk gpu 2 -in in.script # 12 MPI tasks share 2 GPUs on a single 16-core (or whatever) node
mpirun -np 48 -ppn 12 lmp_machine -sf gpu -pk gpu 2 -in in.script # ditto on 4 16-core nodes
请注意,如果使用“-sf gpu”开关,它还会发出默认的 package gpu 0 命令,这将导致自动选择要使用的 GPU 数量。
使用“-pk”开关明确允许设置要使用的 GPU/节点的数量以及其他选项。其语法与“package gpu”命令相同。有关详细信息,请参阅包命令页面,包括所有选项使用的默认值(如果未指定)。
请注意,package gpu 命令的默认设置是将 Newton 标志设置为“关闭”成对交互。它不会影响键合相互作用的设置(LAMMPS 默认为“打开”)。 GPU 包对样式当前需要成对交互的“关闭”设置。
或者通过编辑输入脚本来运行 GPU 包:
上面针对 mpirun
或 mpiexec
命令、MPI 任务/节点以及多个 MPI 任务/GPU 的使用的讨论是相同的。
使用 suffix gpu 命令,或者您可以显式向输入脚本中的各个样式添加“gpu”后缀,例如
pair_style lj/cut/gpu 2.5
您还必须使用 package gpu 命令来启用 GPU 包,除非使用了“-sf gpu”或“-pk gpu”命令行开关。它指定要使用的 GPU/节点的数量以及其他选项。
预期的加速:
GPU 与多核 CPU 的性能取决于您的硬件、使用的配对类型、原子/GPU 的数量以及 GPU 上使用的精度(双精度、单精度、混合精度)。与在 OPENMP 和 INTEL 包中使用 LAMMPS 的本机线程和矢量化支持相比,在 CPU 上以 OpenCL 模式使用 GPU 包(使用矢量化和多线程)通常会导致性能较差。
请参阅 LAMMPS 网站的基准页面,了解 GPU 包在各种硬件(包括 ORNL 的 Titan HPC 平台)上的性能。
您还应该尝试每个 GPU 使用多少个 MPI 任务,以便为您的问题和机器提供最佳性能。这也是问题大小和所使用的配对风格的函数。同样,您应该尝试 GPU 库的精度设置,看看单精度或混合精度是否会给出准确的结果,因为它们通常会更快。
最佳性能指南:
- 在每个 GPU 上使用多个 MPI 任务通常会提供最佳性能,正如我的大多数多核 CPU/GPU 配置所允许的那样。
- 如果每个 MPI 任务的粒子数量较小(例如 100 个粒子),则即使不使用计算节点上的所有核心,每个 GPU 运行较少的 MPI 任务也会更高效。
- package gpu 命令有多个用于调整性能的选项。邻居列表可以构建在 GPU 或 CPU 上。力计算可以在 CPU 内核和 GPU 之间动态平衡。可以进行特定于 GPU 的设置,这些设置可以针对不同的硬件进行优化。有关详细信息,请参阅包命令页面。
- 正如 package gpu 命令所述,GPU 加速对样式可以与 CPU 计算异步执行计算。 LAMMPS 报告的“配对”时间将是完成 CPU 对式计算所需的时间和完成 GPU 对式计算所需的时间的最大值。用于与键、角度、二面角、不正确和远程计算同时运行的计算的启用 GPU 的配对样式所花费的任何时间都不会包含在“配对”时间中。
- 由于只有部分 pppm kspace 样式是 GPU 加速的,因此仅对具有远程静电的 Pair 样式使用 GPU 加速可能会更快。请参阅 package 命令的“pair/only”关键字,了解执行此操作的快捷方式。 CPU 上的 kspace 和 GPU 上的非键交互之间的工作可以通过调整库仑截止来平衡,而不会损失准确性。
- 当package gpu命令的模式设置为force/neigh时,GPU上邻居列表计算的时间将添加到“Pair”时间中,而不是“Neigh”时间中。 GPU 上各种任务(数据复制、邻居计算、力计算等)所需时间的额外细分仅在每次运行结束时通过 LAMMPS 屏幕输出(不在日志文件中)输出。这些计时表示每个例程在 GPU 上花费的总时间,无论异步 CPU 计算如何。
- 输出部分“GPU Time Info (average)”报告“Max Mem / Proc”。这是单个 MPI 进程在 GPU 上用于数据存储的一次使用的最大内存。
限制:没有。
7.4.2.INTEL 包
INTEL 软件包由英特尔公司的 Mike Brown 维护。它提供了两种加速模拟的方法,具体取决于您拥有的硬件。第一个是通过矢量化以单精度、混合精度或双精度运行来在 Intel CPU 上进行加速。第二个是通过将邻居列表和非键合力计算卸载到 Phi 来加速英特尔至强 Phi 协处理器。两种情况都使用相同的 C++ 代码。当从 CPU 卸载到协处理器时,相同的例程会运行两次,一次在 CPU 上运行,一次带有卸载标志。这使得 LAMMPS 可以同时在 CPU 内核和协处理器内核上运行。
当前可用的 INTEL 样式
-
Angle Styles: charmm, harmonic
-
Bond Styles: fene, fourier, harmonic
-
Dihedral Styles: charmm, fourier, harmonic, opls
-
Fixes: nve, npt, nvt, nvt/sllod, nve/asphere
-
Improper Styles: cvff, harmonic
-
Pair Styles: airebo, airebo/morse, buck/coul/cut, buck/coul/long, buck, dpd, eam, eam/alloy, eam/fs, gayberne, lj/charmm/coul/charmm, lj/charmm/coul/long, lj/cut, lj/cut/coul/long, lj/long/coul/long, rebo, sw, tersoff
-
K-Space Styles: pppm, pppm/disp
注:目前,INTEL 软件包中的所有样式均不支持计算每原子应力。如果您的输入中的任何compute或fix需要它,LAMMPS 将中止并显示错误消息。
预期加速
加速取决于您的模拟、硬件、使用的样式、原子数量和浮点精度模式。与不使用其他加速包的 LAMMPS 相比,性能有所提高,因为这些加速包正在积极开发中(并且可能会发生性能变化)。测量是使用 src/INTEL/TEST 目录中提供的输入文件以及提供的运行脚本来执行的。它们的大小是可扩展的;给出的结果是 512K 粒子(液晶为 524K)。大多数模拟都是标准 LAMMPS 基准测试(由括号中的文件扩展名表示),并对运行长度进行了修改并添加了预热运行(与卸载基准测试一起使用)。
结果是在采用“2017 年 6 月”构建的 LAMMPS 的英特尔至强 E5-2697v4 处理器(代号为 Broadwell)、英特尔至强 Phi 7250 处理器(代号为 Knights Landing)和英特尔至强 Gold 6148 处理器(代号为 Skylake)上获得的加速使用 Intel Parallel Studio 2017 更新 2。结果是每个物理内核有 1 个 MPI 任务。请参阅 src/INTEL/TEST/README 了解原始模拟速率和重现说明。
准确性和运算顺序
在大多数分子动力学软件中,并行化参数(MPI、OpenMP 和矢量化的数量)可能会由于改变有限精度计算的运算顺序而改变结果。 INTEL 包是确定性的。这意味着在使用相同的并行配置以及使用确定性库或库设置(MPI、OpenMP、FFT)时,每次运行的结果应该是可重现的。然而,与没有加速的 LAMMPS 相比,INTEL 封装中存在一些差异,可以改变操作顺序:
- 可以按不同的顺序创建邻居列表
- 用于对原子进行排序的容器可以以不同的方向排列
- PPPM 的默认模板阶数为 7。默认情况下,LAMMPS 将计算其他 PPPM 参数,以符合此阶数所需的精度
- newton设置适用于所有原子,而不仅仅是 MPI 任务之间共享的原子
- 矢量化可以改变成对力相加的顺序
- 在构建时使用 -DLMP_USE_MKL_RNG 定义(所有包含的英特尔优化 makefile 都这样做)时,耗散粒子动力学的随机数生成器(配对样式 dpd/intel)使用英特尔 MKL 库中包含的 Mersenne Twister 生成器(应该更强大)比默认的 Masaglia 随机数生成器)
与 INTEL 包一起使用的精度模式(如下所述)可以改变计算的准确性。对于默认的混合精度选项,原子对或三元组之间的计算以单精度执行,旨在在 MD 模拟的固有误差范围内。所有累加均以双精度进行,以防止误差随着模拟中原子数量的增加而增加。未经适当验证,不应使用单精度模式。
有经验的用户快速入门
LAMMPS 应该在安装了 INTEL 软件包的情况下构建。模拟应使用每个物理核心(而不是硬件线程)1 个 MPI 任务来运行。
- 根据需要编辑 src/MAKE/OPTIONS/Makefile.intel_cpu_intelmpi。
- 设置环境变量KMP_BLOCKTIME=0
- “-pk intel 0 omp $t -sf intel”添加到 LAMMPS 命令行
- 对于 Intel Xeon CPU,$t 应为 2;对于 Intel Xeon Phi,$t 应为 2 或 4
- 对于一些没有远距离静电的简单二体势,通过在输入脚本中添加“牛顿关闭”设置可以提高性能和可扩展性
- 对于更高节点数的模拟,请将“processors * * * grid numa”添加到输入脚本的开头以获得更好的可扩展性
- 如果在输入脚本中使用 kspace_style pppm,请添加“kspace_modify diff ad”以获得更好的性能
对于 Intel Xeon Phi CPU:
- 应使用 MCDRAM 执行运行。
- 对于在支持 AVX-512 的 Intel CPU 上使用 kspace_style pppm 进行模拟:
- 将“kspace_modify diff ad”添加到输入脚本中
- 命令行选项应更改为“-pk intel 0 omp $r lrt yes -sf intel”,其中 $r 是线程数减 1。
- 不使用线程关联(设置 KMP_AFFINITY=none)
- “newton off”设置可以提供更好的可扩展性
对于ntel Xeon Phi co-processors (Offload):
- 根据需要编辑 src/MAKE/OPTIONS/Makefile.intel_co-processor
- “-pk intel N omp 1”添加到命令行,其中 N 是每个节点的协处理器数量。
所需的硬件/软件
使用 Intel 编译器时需要 16.0 或更高版本。
为了使用协处理器卸载,需要Intel Xeon Phi co-processor 和英特尔编译器。
尽管任何编译器都可以与 INTEL 软件包一起使用,但目前,由于缺乏标准支持以及观察到性能下降,在不使用 Intel 编译器时,默认禁用矢量化指令。 OpenMP 标准现在支持矢量化指令,我们计划在大多数编译器可用后将代码转换为该标准。我们希望这能够提高性能并支持其他编译器。
对于Intel Xeon Phi x200系列处理器(代号Knights Landing),硬件有多种配置选项。为了获得最佳性能,我们建议将 MCDRAM 配置为“Flat”模式,并将集群模式设置为“Quadrant”或“SNC4”。也可以使用“缓存”模式,但性能可能会稍低。
关于同时多线程的注意事项
现代 CPU 通常支持同时多线程 (SMT)。在英特尔处理器上,这称为超线程(HT)技术。 SMT 是在单核上高效运行多个线程的硬件支持。硬件线程或逻辑核心通常用来指硬件支持的线程数量。例如,Intel Xeon E5-2697v4 处理器被描述为具有 36 个核心和 72 个线程。这意味着 36 个 MPI 进程或 OpenMP 线程可以在单独的内核上同时运行,但最多 72 个 MPI 进程或 OpenMP 线程可以在 CPU 上运行,而无需昂贵的操作系统上下文切换。
使用 SMT 时,分子动力学模拟通常会运行得更快。如果一个线程停止运行,例如因为它正在等待尚未从内存到达的数据,则另一个线程可以开始运行,以便 CPU 管道仍然得到有效使用。虽然通过为每个硬件线程启动 MPI 任务可以看到好处,但对于多节点模拟,我们建议使用 OpenMP 线程进行 SMT,无论是使用 INTEL 包、OPENMP 包还是 KOKKOS 包。在上面的示例中,通过将所有 36 个物理内核与 LAMMPS 一起使用,可以观察到高达 36 倍的加速。通过使用全部 72 个硬件线程,可以获得额外 10-30% 的性能增益。
许多平台上的 BIOS 允许禁用 SMT,但是,我们不建议在现代处理器上这样做,因为在大多数情况下,任何软件包都没有什么好处。操作系统将每个硬件线程报告为一个单独的核心,从而允许确定可用硬件线程的数量。在 Linux 系统上,通常可以通过以下方式获取此信息:
cat /proc/cpuinfo
使用 INTEL 包构建 LAMMPS
请参阅构建附加页面以获取说明。此处介绍了一些其他详细信息。
对于使用 make 进行构建,LAMMPS 中的 src/MAKE/OPTIONS/ 目录中包含了几个用于使用 Intel 编译器进行构建的示例 Makefile:
Makefile.intel_cpu_intelmpi # Intel Compiler, Intel MPI, No Offload
Makefile.knl # Intel Compiler, Intel MPI, No Offload
Makefile.intel_cpu_mpich # Intel Compiler, MPICH, No Offload
Makefile.intel_cpu_openpmi # Intel Compiler, OpenMPI, No Offload
Makefile.intel_co-processor # Intel Compiler, Intel MPI, Offload
Makefile.knl 与 Makefile.intel_cpu_intelmpi 相同,只是它明确指定矢量化应适用于 Intel Xeon Phi x200 处理器,从而更容易交叉编译。对于最近安装了英特尔 Parallel Studio 的用户,该过程非常简单:
make yes-intel
source /opt/intel/parallel_studio_xe_2016.3.067/psxevars.sh
# or psxevars.csh for C-shell
make intel_cpu_intelmpi
请注意,如果您构建支持 Phi 协处理器,则可以在安装或未安装协处理器的节点上使用相同的二进制文件。但是,如果您的系统上没有协处理器,则在不支持卸载的情况下进行构建将生成较小的二进制文件。
INTEL 包的 Makefile 的一般要求如下。使用 Intel 编译器时,需要“-restrict”,强烈建议对 CCFLAGS 和 LINKFLAGS 使用“-qopenmp”。 CCFLAGS 应包含“-DLMP_INTEL_USELRT”(除非构建环境中不支持 POSIX 线程)和“-DLMP_USE_MKL_RNG”(除非 Intel Math Kernel Library (MKL) 在构建环境中不可用)。对于 Intel 编译器,LIB 应包含“-ltbbmalloc”,或者如果该库不可用,则可以将“-DLMP_INTEL_NO_TBB”添加到 CCFLAGS。对于支持卸载的构建,CCFLAGS 需要“-DLMP_INTEL_OFFLOAD”,LINKFLAGS 需要“-qoffload”。其他推荐的获得最佳性能的 CCFLAG 选项是“-O2 -fno-alias -ansi-alias -qoverride-limits fp-model fast=2 -no-prec-div”。
注:请参阅 src/INTEL/README 文件,了解在代号为“Skylake”的英特尔服务器处理器上获得最佳性能可能需要的其他标志。
注:矢量化和数学功能可能因 CPU 的不同而有所不同。对于英特尔编译器,“-x”标志指定要优化的处理器类型。 “-xHost”指定编译器应针对用于编译的处理器进行构建。对于 Intel Xeon Phi x200 系列处理器,此选项为“-xMIC-AVX512”。对于第四代 Intel Xeon (v4/Broadwell) 处理器,应使用“-xCORE-AVX2”。对于较旧的 Intel Xeon 处理器,“-xAVX”通常对于 LAMMPS 中的不同模拟表现最佳。大多数示例 Makefile 中的默认设置是使用“-xHost”,但是在交叉编译时不应使用此选项。
使用 INTEL 包运行 LAMMPS
使用 INTEL 包运行 LAMMPS 与正常使用类似,但需要注意以下几点:
1) 指定 LAMMPS 应使用 INTEL 包,
2) 指定 OpenMP 线程数,以及
3) 有选择地指定应使用该包的特定 LAMMPS 样式。英特尔封装。
1) 和 2) 可以从命令行或通过编辑输入脚本来执行。 3)需要编辑输入脚本。下面还介绍了高级性能调整选项以获得最佳性能。
在单个节点上运行时(包括使用卸载到协处理器的运行),通常通过每个物理核心使用 1 个 MPI 任务以及具有 SMT 的附加 OpenMP 线程来获得最佳性能。对于 Intel Xeon 处理器,应使用 2 个 OpenMP 线程进行 SMT。对于 Intel Xeon Phi CPU,应使用 2 或 4 个 OpenMP 线程(最佳选择取决于模拟)。如果用户指定使用 LRT 模式(如下所述),则应使用 1 或 3 个 OpenMP 线程。对于多节点运行,每个物理核心使用 1 个 MPI 任务通常会获得最佳性能,但是,根据计算机和规模,用户可能会通过减少 MPI 任务数量并使用更多 OpenMP 线程来获得更好的性能。就性能而言,几乎在所有情况下,MPI 任务和 OpenMP 线程数量的乘积不应超过可用硬件线程的数量。
注:设置核心关联性通常用于将 MPI 任务和 OpenMP 线程固定到一个核心或一组核心,以便内存访问可以统一。除非在构建时禁用,否则当使用卸载到协处理器时,主机 (CPU) 上的 MPI 任务和 OpenMP 线程的关联性将在主机上默认设置。在这种情况下,没有必要使用其他方法来控制亲和性(例如taskset、numactl、I_MPI_PIN_DOMAIN等)。可以使用 package intel 命令的 no_affinity 选项或在构建时禁用该选项(通过将 -DINTEL_OFFLOAD_NOAFFINITY 添加到 Makefile 的 CCFLAGS 行)来禁用此功能。不建议禁用此选项,尤其是在禁用英特尔超线程技术的计算机上运行时。
从命令行运行 INTEL 包
要为输入脚本中使用的所有可用样式启用 INTEL 优化,可以使用“-sf intel”命令行开关,无需编辑输入脚本。此开关会自动将“intel”附加到支持它的样式中。它还调用默认命令:package intel 1。此包命令用于设置 INTEL 包的选项。默认包命令将指定 INTEL 计算以混合精度执行,OpenMP 线程数由 OMP_NUM_THREADS 环境变量指定,并且如果存在协处理器并且二进制文件是使用卸载支持构建的,则 1 个协处理器每个节点的处理器将用于自动平衡 CPU 和协处理器之间的工作。
您可以使用“-pk intel Nphi”命令行开关以及文档中指定的关键字/值对来为 INTEL 包指定不同的选项。此处,Nphi = Xeon Phi 协处理器/节点的数量(在没有卸载支持的情况下被忽略)。 INTEL 包的常见选项包括用于覆盖任何 OMP_NUM_THREADS 设置并指定 OpenMP 线程数量的 omp、用于设置浮点精度模式的 mode 以及用于启用远程线程模式的 lrt,如下所述。有关详细信息,请参阅 package intel 命令,包括所有选项使用的默认值(如果未指定),以及如何通过 OMP_NUM_THREADS 环境变量设置 OpenMP 线程数(如果需要)。
示例(有关启动 MPI 应用程序的差异,请参阅 MPI/机器的文档):
mpirun -np 72 -ppn 36 lmp_machine -sf intel -in in.script # 2 nodes, 36 MPI tasks/node, $OMP_NUM_THREADS OpenMP Threads
mpirun -np 72 -ppn 36 lmp_machine -sf intel -in in.script -pk intel 0 omp 2 mode double # Don't use any co-processors that might be available, use 2 OpenMP threads for each task, use double precision
或者通过编辑输入脚本来运行 INTEL 包
作为添加命令行参数的替代方法,可以编辑输入脚本以启用 INTEL 包。这需要将 package intel 命令添加到输入脚本的顶部。对于上面的第二个例子,这将是:
package intel 0 omp 2 mode double
要仅为个别样式启用 INTEL 包,您可以为个别样式添加“intel”后缀,例如:
pair_style lj/cut/intel 2.5
或者,可以将后缀 intel 命令添加到输入脚本中,以便为输入脚本中后面的命令启用 INTEL 样式。
性能调整
注:使用 PPPM 时,通过修改输入脚本,INTEL 软件包将表现得更好:kspace_modify diff ad 应添加到输入脚本中。
远程线程 (LRT) 模式是 package intel 命令的一个选项,可以在采用 SMT 的处理器上使用 PPPM 进行远程静电时提高性能。它为每个 MPI 任务生成一个额外的 pthread。该线程专用于执行一些 PPPM 计算和 MPI 通信。此功能需要在编译 LAMMPS 时在 makefile 中设置预处理器标志 -DLMP_INTEL_USELRT。它在默认 makefile(Makefile.mpi 和 Makefile.serial)中未设置,但在针对 INTEL 包调整的所有 makefile 中均已设置。在 Intel Xeon Phi x200 系列 CPU 上,LRT 功能可能会提高性能,即使在单个节点上也是如此。在 Intel Xeon 处理器上,使用此模式可能会在使用多个节点时获得更好的性能,具体取决于特定的计算机配置。要启用 LRT 模式,请指定 OpenMP 线程数比通常用于运行的线程数少 1,并将“lrt yes”选项添加到“-pk”命令行后缀或“package intel”命令中。例如,如果运行通常使用“-pk intel 0 omp 4”执行效果最佳,则使用“-pk intel 0 omp 3 lrt yes”。使用 LRT 时,应设置环境变量“KMP_AFFINITY=none”。使用卸载时不支持 LRT 模式。
注:将牛顿设置更改为关闭可以提高简单 2 体势(例如 lj/cut)的性能和/或可扩展性,或者在支持 AVX-512 的处理器上使用 LRT 模式时。
INTEL 软件包并不支持所有样式。您可以将 INTEL 包与 OPT 包或 OPENMP 包中的样式混合。当然,这需要在构建时安装这些软件包。这可以通过使用“-sfhybridintelopt”或“-sfhybridintelomp”命令行选项自动执行。或者,可以在输入脚本中手动添加“opt”和“omp”后缀。对于后者,package omp 命令必须位于输入脚本中,或者必须使用“-pk omp Nt”命令行开关,其中 Nt 是 OpenMP 线程数。对于不同的包,OpenMP 线程数不应设置不同。请注意,后缀混合 intel omp 命令也可以在输入脚本中使用,以便在 INTEL 样式不可用时自动将“omp”后缀附加到样式中。
注:对于更高节点数的模拟,请将处理器 * * * grid numa 添加到输入脚本的开头,以获得更好的可扩展性。
在许多节点上运行时,使用更少的 OpenMP 线程和更多的 MPI 任务时性能可能会更好。这将取决于模拟和机器。使用 verlet/split 运行方式还可以为 PPPM 静电模拟提供更好的性能。请注意,这是轻轨模式的替代方案,两者不能一起使用。
目前,在 Intel Xeon Phi x200 系列 CPU 上使用 Intel MPI 时,对于尚未完全支持 AVX-512 的 Linux 内核,通过设置环境变量“I_MPI_SHM_LMT=shm”可以获得更好的性能。在 Intel Xeon Phi x200 系列处理器上运行时,使用 MCDRAM 始终会表现得更好。请查阅您的系统文档,了解指定在 MCDRAM 中执行 MPI 运行的最佳方法。
调整Offload性能
Offload的默认设置应该会提供良好的性能。
当使用 LAMMPS 并Offload到英特尔协处理器时,通常可以通过在 CPU 和协处理器上执行并发计算来实现最佳性能。这是通过仅将一小部分邻居和对计算卸载到协处理器或使用混合对样式(其中只有一种样式使用“intel”后缀)来实现的。对于远程静电或键、角度、二面角、不正确计算的模拟,到协处理器的计算和数据传输将与主机 CPU 上这些计算的计算和 MPI 通信同时运行。下图展示了在配备 Intel Xeon Phi 7120p 协处理器的 E5-2697v2 处理器上运行的视紫红质蛋白质基准测试。在此图中,垂直访问是时间,同时运行的例程在主机和协处理器上同时运行。
offloaded 工作的比例由 package intel 命令中的balance关键字控制。
平衡为 0 时,所有计算都在 CPU 上运行。
平衡 为1 在协处理器上运行所有支持的计算。
平衡为 0.5 在协处理器上运行一半的计算。
将平衡设置为 -1(默认值)将启用动态负载平衡,从而在整个模拟过程中不断调整卸载工作的比例。由于数据传输无法定时,因此该选项产生的结果通常与最佳固定余额相差 5% 到 10%。
如果使用动态负载平衡运行短期基准测试,则添加短期预热运行(10-20 个步骤)将允许负载平衡器找到接近最佳的设置,该设置将延续到其他运行。
package intel 命令的默认设置是让给定计算节点上的所有 MPI 任务使用单个 Xeon Phi 协处理器。一般来说,在每个节点上运行大量 MPI 任务在offloade时性能最佳。每个 MPI 任务将自动获得与协处理器上可用的硬件线程子集的关联性。例如,如果您的卡有 61 个核心,其中 60 个核心可用于卸载,每个核心有 4 个硬件线程(总共 240 个线程),则每个节点运行 24 个 MPI 任务将导致每个 MPI 任务使用主机上 10 个线程的子集。 -处理器。可以通过 package intel 命令的关键字设置来微调每个 MPI 任务使用的线程数或每个内核使用的线程数。
INTEL 软件包有两种模式来决定协处理器将处理哪些原子。此选择由 package intel 命令的 Ghost 关键字控制。当设置为 0 时,幽灵原子(位于 MPI 任务之间边界的原子)不会offloade到卡上。当牛顿设置为“打开”时,这允许力的 MPI 通信与协处理器上的计算重叠。默认值取决于所使用的样式,但是,通过显式设置此选项可以获得更好的性能。
在禁用 CPU 超线程的情况下使用offloade时,使用比可用内核更少的 MPI 任务和 OpenMP 线程可能有助于提高性能。这是因为内部生成了额外的线程来处理异步offloade任务。
如果配对计算被offloade到英特尔Xeon Phi协处理器,则会在运行的设置阶段将诊断行打印到屏幕(而不是日志文件),指示正在使用offloade模式并指示数量每个 MPI 任务的协处理器线程数。此外,每次运行结束时都会打印offloade时间摘要。卸载时,原子排序的频率更改为 1,以便在每次重建邻居列表时对每个原子数据进行有效排序。每个 Phi 上的所有可用协处理器线程将在 MPI 任务之间划分,除非使用“-pk intel”命令行开关的 tptask 选项来限制每个 MPI 任务的协处理器线程。
限制
当offloade到协处理器时,无法offloade需要邻居构建的跳过列表的混合样式。允许使用混合/叠加。offloade时只能将一种英特尔加速样式与混合样式一起使用。目前offloade不支持 Special_bonds 排除列表,但是,通常可以通过将排除原子类型的截止值设置为 0 来实现相同的效果。INTEL 包中的对样式目前都不支持“内部”、“中间”、“通过 run_style respa 命令进行 rRESPA 集成的“outer”选项;仅支持“pair”选项。
参考文献
-
Brown, W.M., Carrillo, J.-M.Y., Mishra, B., Gavhane, N., Thakkar, F.M., De Kraker, A.R., Yamada, M., Ang, J.A., Plimpton, S.J., “Optimizing Classical Molecular Dynamics in LAMMPS”, in Intel Xeon Phi Processor High Performance Programming: Knights Landing Edition, J. Jeffers, J. Reinders, A. Sodani, Eds. Morgan Kaufmann.
-
Brown, W. M., Semin, A., Hebenstreit, M., Khvostov, S., Raman, K., Plimpton, S.J. Increasing Molecular Dynamics Simulation Rates with an 8-Fold Increase in Electrical Power Efficiency. 2016 High Performance Computing, Networking, Storage and Analysis, SC16: International Conference (pp. 82-95).
-
Brown, W.M., Carrillo, J.-M.Y., Gavhane, N., Thakkar, F.M., Plimpton, S.J. Optimizing Legacy Molecular Dynamics Software with Directive-Based Offload. Computer Physics Communications. 2015. 195: p. 95-101.
7.4.3. KOKKOS 包
Kokkos 是一个模板化 C++ 库,它提供抽象,允许应用程序内核的单一实现(例如成对样式)在不同类型的硬件(例如 GPU、Intel Xeon Phis 或多核 CPU)上高效运行。 Kokkos 将 C++ 内核映射到不同的后端语言,例如 CUDA、OpenMP 或 Pthreads。 Kokkos 库还提供数据抽象来调整(在编译时)2d 和 3d 数组等数据结构的内存布局,以优化不同硬件上的性能。有关 Kokkos 的更多信息,请参阅 Kokkos GitHub 页面。
LAMMPS KOKKOS 包包含pair、fix 和atom 样式的版本,这些样式使用Kokkos 库提供的数据结构和宏,该库包含在/lib/kokkos 中的LAMMPS 中。 KOKKOS 包主要由 Christian Trott (Sandia) 和 Stan Moore (Sandia) 开发,其他人也贡献了各种风格,包括 Sikandar Mashayak (UIUC)、Ray Shan (Sandia) 和 Dan Ibanez (Sandia)。有关使用 Kokkos 抽象进行开发的更多信息,请参阅 Kokkos Wiki。
Kokkos 目前支持 4 种执行模式(每个 MPI 任务)。它们是串行(仅适用于 CPU 和 Intel Phi 的 MPI)、OpenMP(适用于多核 CPU 和 Intel Phi 的线程)、CUDA(适用于 NVIDIA GPU)和 HIP(适用于 AMD GPU)。您可以在构建时选择模式来生成与特定硬件兼容的可执行文件。
注:Kokkos 需要使用支持 c++17 标准的编译器。对于某些编译器,可能需要添加一个标志来启用 c++17 支持。例如,GNU 编译器使用 -std=c++17 标志。有关已使用 Kokkos 库进行测试的编译器的列表,请参阅 Kokkos Wiki 的要求文档。
注:要使用对 NVIDIA GPU 的 Kokkos 支持进行构建,您的系统上必须安装 NVIDIA CUDA 工具包软件版本 11.0 或更高版本。有关如何检查和执行此操作的详细信息,请参阅 GPU 包的讨论。
注:要构建 Kokkos 对 AMD GPU 的支持,您的系统上必须安装 AMD ROCm 工具包软件版本 5.2.0 或更高版本。
注:具有 CUDA 的 Kokkos 目前隐式假设 MPI 库是 GPU 感知的。但情况并非总是如此,尤其是在使用 Linux 发行版提供的预编译 MPI 库时。当仅使用具有单个 MPI 等级的单个 GPU 时,这不是问题。当使用多个 MPI 级别运行时,如果没有 GPU 感知的 MPI 支持,您可能会看到分段错误。通过将标志 -pk kokkos gpu/aware off 添加到 LAMMPS 命令行或在输入文件中使用命令包 kokkos gpu/aware off 可以避免这些问题。
注:要使用 Kokkos 进行构建,需要 AMD ROCm 软件版本 3.5 或更高版本的 HIPCC 编译器。在 LAMMPS 中支持这种 Kokkos 模式的工作仍在进行中。如果遇到问题,请联系 LAMMPS 开发人员。
使用 KOKKOS 包构建 LAMMPS
请参阅构建附加页面以获取说明。
使用 KOKKOS 包运行 LAMMPS
所有 Kokkos 操作都发生在机器的单个节点上运行的单个 MPI 任务的上下文中。 LAMMPS 使用的 MPI 任务总数(每个计算节点一个或多个)通过 mpirun
或 mpiexec
命令以通常的方式设置,并且独立于 Kokkos。例如。 OpenMPI 中的 mpirun 命令通过其 -np
和 -npernode
开关执行此操作。对于 MPICH,通过 -np
和 -ppn
也是如此。
在多核 CPU 上运行
以下是如何使用 KOKKOS 包进行 CPU 加速的快速概述(假设有一个或多个 16 核节点)。
mpirun -np 16 lmp_kokkos_mpi_only -k on -sf kk -in in.lj # 1 node, 16 MPI tasks/node, no multi-threading
mpirun -np 2 -ppn 1 lmp_kokkos_omp -k on t 16 -sf kk -in in.lj # 2 nodes, 1 MPI task/node, 16 threads/task
mpirun -np 2 lmp_kokkos_omp -k on t 8 -sf kk -in in.lj # 1 node, 2 MPI tasks/node, 8 threads/task
mpirun -np 32 -ppn 4 lmp_kokkos_omp -k on t 4 -sf kk -in in.lj # 8 nodes, 4 MPI tasks/node, 4 threads/task
要使用 KOKKOS 软件包运行,请在 mpirun 命令中使用“-k on”、“-sf kk”和“-pk kokkos”命令行开关。您必须使用“-k on”命令行开关来启用 KOKKOS 软件包。它需要额外的参数来设置适合您系统的硬件设置。对于 OpenMP 使用:
-k on t Nt
“t Nt”选项指定每个 MPI 任务与节点一起使用的 OpenMP 线程数。默认值为 Nt = 1,即仅 MPI 模式。请注意,MPI 任务 * OpenMP 线程/任务的乘积不应超过(节点上)的物理核心数量,否则性能将受到影响。如果启用超线程 (HT),则 MPI 任务 * OpenMP 线程/任务的乘积不应超过物理核心数 * 硬件线程数。 “-k on”开关还发出“package kokkos”命令(没有附加参数),该命令将各种 KOKKOS 选项设置为默认值,如包命令文档页面上所述。
“-sf kk”命令行开关会自动将“/kk”后缀附加到支持它的样式中。以这种方式,不需要对输入脚本进行修改。或者,可以通过编辑输入脚本来运行 KOKKOS 包,如下所述。
注:使用单个 OpenMP 线程时,Kokkos 串行后端(即 Makefile.kokkos_mpi_only)将比 OpenMP 后端(即 Makefile.kokkos_omp)提供更好的性能,因为消除了使代码线程安全的一些开销。
注:使用“-pk kokkos”命令行开关更改默认包 kokkos 选项。有关详细信息和默认设置,请参阅其文档页面。尝试其选项可以加快特定计算的速度。例如:
mpirun -np 16 lmp_kokkos_mpi_only -k on -sf kk -pk kokkos newton on neigh half comm no -in in.lj # Newton on, Half neighbor list, non-threaded comm
如果在输入脚本中使用 newton 命令,它还可以覆盖 Newton 标志默认值。
对于半邻居列表和 OpenMP,KOKKOS 包默认使用数据复制(即线程私有数组)来避免强制数组(以及其他必要的数据结构)中的线程级写入冲突。对于少量线程(即 8 个或更少),数据复制通常速度最快,但会增加内存占用,并且无法扩展到大量线程。数据复制的替代方法是使用不需要数据复制的线程级原子操作。可以通过使用“-DLMP_KOKKOS_USE_ATOMICS”预处理器标志编译 LAMMPS 来强制使用原子操作。大多数但并非所有启用 Kokkos 的pair_styles都支持数据复制。或者,完整的邻居列表避免了重复或原子操作的需要,但每个原子需要更多的计算操作。当使用 Kokkos Serial 后端或 OpenMP 后端与单线程时,不使用重复或原子操作。对于 CUDA 和半邻居列表,KOKKOS 包始终使用原子操作。
CPU 内核、插槽和线程亲和性
使用多线程时,将 MPI 任务绑定到物理内核并将线程绑定到物理内核对于性能非常重要,这样它们就不会在模拟过程中迁移。
如果您不确定是否正在绑定 MPI 任务(检查 MPI 安装的默认设置),可以使用以下标志强制绑定:
OpenMPI 1.8: mpirun -np 2 --bind-to socket --map-by socket ./lmp_openmpi ...
Mvapich2 2.0: mpiexec -np 2 --bind-to socket --map-by socket ./lmp_mvapich ...
要将线程与 KOKKOS OpenMP 绑定,请使用线程关联环境变量强制绑定。对于 OpenMP 3.1(gcc 4.7 或更高版本、intel 12 或更高版本),设置环境变量 OMP_PROC_BIND=true
应该足够了。一般来说,为了获得 OpenMP 4.0 或更高版本的最佳性能,请设置 OMP_PROC_BIND=spread
和 OMP_PLACES=threads
。要使用 KOKKOS pthreads 选项绑定线程,请按照额外构建选项页面中的说明启用 hwloc 或 libnuma 支持来编译 LAMMPS。
在 Knight’s Landing (KNL) Intel Xeon Phi 上运行
以下是如何将 KOKKOS 软件包用于 Intel Knight’s Landing (KNL) Xeon Phi 的快速概述:
KNL Intel Phi 芯片有 68 个物理内核。通常为操作系统保留 1 到 4 个核心,仅使用 64 或 66 个核心。每个核心有 4 个超线程,因此实际上有 N = 256 (4*64) 或 N = 264 (4*66) 个核心可供运行。 MPI 任务 * OpenMP 线程/任务的乘积不应超过此限制,否则性能将受到影响。请注意,使用 KOKKOS 包,您不需要指定每个节点有多少个 KNL;每个 KNL 都被简单地视为运行一定数量的 MPI 任务。
下面显示了遵循这些规则的 mpirun 命令示例。
# Running on an Intel KNL node with 68 cores (272 threads/node via 4x hardware threading):
mpirun -np 64 lmp_kokkos_phi -k on t 4 -sf kk -in in.lj # 1 node, 64 MPI tasks/node, 4 threads/task
mpirun -np 66 lmp_kokkos_phi -k on t 4 -sf kk -in in.lj # 1 node, 66 MPI tasks/node, 4 threads/task
mpirun -np 32 lmp_kokkos_phi -k on t 8 -sf kk -in in.lj # 1 node, 32 MPI tasks/node, 8 threads/task
mpirun -np 512 -ppn 64 lmp_kokkos_phi -k on t 4 -sf kk -in in.lj # 8 nodes, 64 MPI tasks/node, 4 threads/task
mpirun 命令的 -np 设置设置 MPI 任务/节点的数量。 “-k on t Nt”命令行开关将线程/任务的数量设置为 Nt。这两个值的乘积应为 N,即 256 或 264。
注:在 KNL 上运行时,package kokkos 命令的默认设置是使用“half”邻居列表,并将 Newton 标志设置为“on”以实现成对和键合交互。这通常最适合多体潜能。对于更简单的成对势,使用牛顿标志为“关闭”的“完整”邻居列表可能会更快。使用“-pk kokkos”命令行开关更改默认包 kokkos 选项。有关详细信息和默认设置,请参阅其文档页面。尝试其选项可以加快特定计算的速度。例如:
mpirun -np 64 lmp_kokkos_phi -k on t 4 -sf kk -pk kokkos comm host -in in.reax # Newton on, half neighbor list, threaded comm
mpirun -np 64 lmp_kokkos_phi -k on t 4 -sf kk -pk kokkos newton off neigh full comm no -in in.lj # Newton off, full neighbor list, non-threaded comm
注:MPI 任务和线程应绑定到内核,如上面针对 CPU 的描述。
注:要构建 Kokkos 对 Intel Xeon Phi 协处理器(例如 Knight’s Corner (KNC))的支持,您的系统必须配置为在“本机”模式下使用它们,而不是像 INTEL 软件包支持的“卸载”模式。
在 GPU 上运行
使用“-k”命令行开关指定每个节点的 GPU 数量。通常,mpirun 命令的 -np 设置应将 MPI 任务/节点的数量设置为等于节点上物理 GPU 的数量。您可以使用 KOKKOS 包将多个 MPI 任务分配给同一个 GPU,但这通常只有在输入脚本的某些部分尚未移植为使用 Kokkos 时才会更快。在这种情况下,主机上的打包/解包通信缓冲区也可以提供加速(请参阅 KOKKOS 包命令)。在这种情况下建议使用 CUDA MPS。
强烈建议使用 GPU 感知的 MPI 库。通过使用 -pk kokkos gpu/aware off 可以避免使用 GPU 感知的 MPI。如上所述,对于多核 CPU(且无 GPU),如果 N 是物理核心/节点的数量,则 MPI 任务/节点的数量不应超过 N。
-k on g Ng
以下是如何使用 GPU 的 KOKKOS 包的示例,假设有一个或多个节点,每个节点都有两个 GPU:
mpirun -np 2 lmp_kokkos_cuda_openmpi -k on g 2 -sf kk -in in.lj # 1 node, 2 MPI tasks/node, 2 GPUs/node
mpirun -np 32 -ppn 2 lmp_kokkos_cuda_openmpi -k on g 2 -sf kk -in in.lj # 16 nodes, 2 MPI tasks/node, 2 GPUs/node (32 GPUs total)
注:在 GPU 上运行时,package kokkos 命令的默认设置是使用“完整”邻居列表,并将 Newton 标志设置为“off”以实现成对和绑定交互以及线程通信。当在 Maxwell 或 Kepler GPU 上运行时,这通常是最好的。对于 Pascal GPU 及更高版本,使用“half”邻居列表并将 Newton 标志设置为“on”可能会更快。对于许多对样式,将邻居 binsize 设置为 CPU 默认值的两倍将提供加速,这是在 GPU 上运行时的默认值。使用“-pk kokkos”命令行开关更改默认包 kokkos 选项。有关详细信息和默认设置,请参阅其文档页面。尝试其选项可以加快特定计算的速度。例如:
GPU 上原子排序的默认 binsize 等于默认 CPU 相邻 binsize(即比默认 GPU 相邻 binsize 小 2 倍)。当在 GPU 上运行 Lennard Jones 等简单的成对势时,使用 2 倍大的 binsize 进行原子排序(等于默认 GPU 邻居 binsize)以及比默认更频繁的排序(例如每 100 个时间步而不是 1000 个时间步进行排序)可能会有所改善表现。
mpirun -np 2 lmp_kokkos_cuda_openmpi -k on g 2 -sf kk -pk kokkos newton on neigh half binsize 2.8 -in in.lj # Newton on, half neighbor list, set binsize = neighbor ghost cutoff
注:使用 GPU 时,如果您的输入脚本不使用尚未启用 Kokkos 的修复或计算样式,您将获得最佳性能。这允许数据在多个时间步长内保留在 GPU 上,而无需复制回主机 CPU。调用非 Kokkos 修复或计算,或者执行热输出或转储输出的 I/O 将导致数据复制回 CPU,从而导致性能损失。
注:要获得对、kspace 等中花费的时间之间的准确时序细分,必须设置环境变量 CUDA_LAUNCH_BLOCKING=1。但是,这会降低性能,不建议用于生产运行。
通过编辑输入脚本来运行 KOKKOS 包
或者,可以通过将包 kokkos 或后缀 kk 命令添加到输入脚本来复制“-sf”或“-pk”开关的效果。
上面关于使用 KOKKOS 包构建 LAMMPS、 mpirun
或 mpiexec
命令以及设置适当的线程属性的讨论是相同的。
您仍然必须使用“-k on”命令行开关来启用 KOKKOS 软件包,并为适合您的系统的硬件选项指定其附加参数,如上所述。
您可以使用 suffix kk 命令,也可以在输入脚本中显式添加“kk”后缀到各个样式,例如
pair_style lj/cut/kk 2.5
如果您希望更改由“-k on”命令行开关设置的任何选项默认值,则只需使用 package kokkos 命令。
一起使用 OpenMP 线程和 CUDA:
通过 KOKKOS 包,OpenMP 多线程和 GPU 都可以在一些特殊情况下一起编译和使用。在传统构建的 makefile 中,KOKKOS_DEVICES 变量必须同时包含“Cuda”和“OpenMP”,就像 /src/MAKE/OPTIONS/Makefile.kokkos_cuda_mpi
的情况一样。
KOKKOS_DEVICES=Cuda,OpenMP
使用 CMake 构建时,您需要启用这两个功能,就像在 kokkos-cuda.cmake
CMake 预设文件中完成的那样。
cmake ../cmake -DKokkos_ENABLE_CUDA=yes -DKokkos_ENABLE_OPENMP=yes
后缀“/kk”相当于“/kk/device”,对于 Kokkos CUDA,在命令行中使用“-sf kk”会在各处提供默认的 CUDA 版本。但是,如果将“/kk/host”后缀添加到输入脚本中的特定样式,则将改用该特定样式的 Kokkos OpenMP (CPU) 版本。将 OpenMP 线程数设置为“t Nt”,GPU 数设置为“g Ng”
-k on t Nt g Ng
例如,使用 1 个 GPU 和 8 个 OpenMP 线程运行的命令为:
mpiexec -np 1 lmp_kokkos_cuda_openmpi -in in.lj -k on g 1 t 8 -sf kk
相反,如果在命令行中使用“-sf kk/host”,然后将“/kk”或“/kk/device”后缀添加到输入脚本中的特定样式,则只有该特定样式才会运行在 GPU 上运行,而其他所有内容都将以 OpenMP 模式在 CPU 上运行。请注意,CPU 和 GPU 风格的执行不会重叠,除非有特殊情况:
在主机 CPU 上运行的 kspace 样式和/或分子拓扑(键、角等)可以与在 GPU 上运行的对样式重叠。首先使用 Kokkos CUDA Makefile 中的 CCFLAGS 添加“–default-stream per-thread”进行编译。然后在输入文件中明确使用“/kk/host”后缀表示kspace和键、角度等,并在命令行上使用“kk”后缀(等于“kk/device”)。另请确保环境变量 CUDA_LAUNCH_BLOCKING 未设置为“1”,以免发生 CPU/GPU 重叠。
预期性能
KOKKOS 在不同模式下运行的性能取决于您的硬件、使用的 KOKKOS 启用样式以及问题的大小。
一般来说,适用以下经验法则:
- 仅在 CPU 上运行时,每个 MPI 任务只有一个线程,KOKKOS 风格的性能介于标准(未加速)风格(仅 MPI 模式)和 OPENMP 包提供的风格之间。然而,这 3 者之间的差异很小(小于 20%)。
- 仅在 CPU 上运行时,每个 MPI 任务有多个线程,KOKKOS 样式的性能比 OPENMP 包稍慢。
- 当每个 GPU 运行大量原子时,当编译为双精度时,KOKKOS 通常比 GPU 包更快。使用 GPU 包的单精度或混合精度的好处在很大程度上取决于所使用的硬件以及模拟系统和配对类型。
- 在 Intel 硬件上运行时,KOKKOS 不如 INTEL 包快,后者针对 x86 硬件(不仅仅是来自 Intel)进行了优化,并使用 Intel 编译器进行编译。 INTEL 软件包还可以通过切换到单精度或混合精度模式来增加向量指令的向量长度。
请参阅 LAMMPS 网站的基准页面,了解 KOKKOS 包在不同硬件上的性能。
高级 Kokkos 选项
使用 KOKKOS 包构建时还有其他允许的选项,可以提高性能或帮助调试或分析。它们在构建附加文档页面的 KOKKOS 部分进行了解释。
限制
目前,KOKKOS 包没有精度选项。所有编译和计算均以双精度执行。
7.4.4. OPENMP 包
OPENMP 软件包由天普大学的 Axel Kohlmeyer 开发。它提供了许多配对样式、几乎所有粘合样式(键、角度、二面角、不正确)、几种 Kspace 样式和一些修复样式的优化和多线程版本。它使用 OpenMP 接口进行多线程,但也可以在没有 OpenMP 支持的情况下进行编译,在这种情况下提供优化的串行样式。
所需的硬件/软件
要启用多线程,您的编译器必须支持 OpenMP 接口。您应该拥有一个或多个多核 CPU,因为多个线程只能由本地节点上的每个 MPI 任务启动(使用共享内存)。
使用 OPENMP 包构建 LAMMPS
请参阅构建附加页面以获取说明。
从命令行运行 OPENMP 包
这些示例假设有一个或多个 16 核节点。
env OMP_NUM_THREADS=16 lmp_omp -sf omp -in in.script # 1 MPI task, 16 threads according to OMP_NUM_THREADS
lmp_mpi -sf omp -in in.script # 1 MPI task, no threads, optimized kernels
mpirun -np 4 lmp_omp -sf omp -pk omp 4 -in in.script # 4 MPI tasks, 4 threads/task
mpirun -np 32 -ppn 4 lmp_omp -sf omp -pk omp 4 -in in.script # 8 nodes, 4 MPI tasks/node, 4 threads/task
mpirun
或 mpiexec
命令设置 LAMMPS 使用的 MPI 任务总数(每个计算节点一个或多个)以及每个节点使用的 MPI 任务数。例如。 MPICH 中的 mpirun 命令通过其 -np 和 -ppn 开关执行此操作。对于 OpenMPI,通过 -np 和 -npernode 也是如此。
您需要选择 OPENMP 包将使用每个 MPI 任务的 OpenMP 线程数。请注意,MPI 任务 * 线程/任务的乘积不应超过(节点上)的物理核心数,否则性能将受到影响。
如上面几行所示,使用“-sf omp”命令行开关,它将自动将“omp”附加到支持它的样式中。 “-sf omp”开关还发出默认包 omp 0 命令,该命令将通过 OMP_NUM_THREADS 环境变量设置每个 MPI 任务的线程数。
您还可以使用“-pk omp Nt”命令行开关,显式设置 Nt = 每个 MPI 任务要使用的 OpenMP 线程数以及其他选项。它的语法与 package omp 命令相同,该命令的页面提供了详细信息,包括未指定时使用的默认值。它还提供了有关如何通过 OMP_NUM_THREADS 环境变量设置线程数的更多详细信息。
或者通过编辑输入脚本来运行 OPENMP 包
上面针对 mpirun
或 mpiexec
命令、MPI 任务/节点和线程/MPI 任务的讨论是相同的。
使用 suffix omp 命令,或者您可以显式向输入脚本中的各个样式添加“omp”后缀,例如
pair_style lj/cut/omp 2.5
您还必须使用 package omp 命令来启用 OPENMP 包。执行此操作时,您还可以指定每个 MPI 任务要使用的线程数。命令页解释了其他选项以及如何通过 OMP_NUM_THREADS 环境变量设置线程数。
预期加速
根据加速的样式,您应该寻找运行结束时打印的“配对时间”、“粘合时间”、“KSpace 时间”和“循环时间”值的减少情况。
当每个 MPI 任务使用单个线程运行 OPENMP 样式(串行或并行)时,与使用其标准非加速样式(串行或全 MPI 1 个任务/核心的并行化)。这是因为许多 OPENMP 样式包含与 OPT 包中使用的类似优化,如 OPT 包文档页面中所述。
对于多个线程/任务,MPI 任务/节点和 OpenMP 线程/任务数量的最佳选择可能会有很大差异,并且应始终通过在特定计算机上运行的特定模拟的基准测试运行进行测试,注意 中讨论的指南下一小节。
这里介绍了 OPENMP 包中使用的多线程策略和一些性能示例。
最佳性能指南
对于当前一代 CPU 上的许多问题,使用单个线程/任务运行 OPENMP 包比使用多个线程/任务运行要快。这是因为 LAMMPS 中的 MPI 并行化通常比 OPENMP 包中实现的多线程更有效。对于不同的 OPENMP 风格,并行效率(在线程意义上)也有所不同。
在以下情况下使用多线程/任务会更有效:
- 单个计算节点具有大量 CPU 核心,但 CPU 本身的内存带宽有限,例如适用于 Intel Xeon 53xx (Clovertown) 和 54xx (Harpertown) 四核处理器。每个 CPU 核心运行一个 MPI 任务将导致性能显着下降,因此每个节点运行 4 个甚至仅 2 个 MPI 任务会更快。在混合 MPI+OpenMP 模式下运行将以同样的方式减少节点间通信带宽争用,但通过利用空闲的 CPU 内核提供额外的加速。
- 用于 MPI 通信的互连无法为每个节点的大量 MPI 任务提供足够的带宽。例如,这适用于在千兆位以太网上或在 Cray XT4 或 XT5 系列超级计算机上运行。与上述情况一样,当使用越来越多的节点时,这种效果会变得更糟。
- 该系统具有空间不均匀的粒子密度,无法很好地映射到 LAMMPS 提供的域分解方案或负载平衡选项。这是因为多线程实现了粒子数量的并行性,而不是通过粒子在空间中的分布。
- 机器正在“能力模式”下使用,即接近 MPI 并行性达到最大值的点。例如,当使用 PPPM 求解器对大量节点上的远程静电进行求解时,可能会发生这种情况。 KSpace 计算的缩放(请参阅 kspace_style 命令)成为性能限制因素。使用多线程可以减少调用的 MPI 任务,并可以加速远程求解器,同时通过 OpenMP 并行化成对和绑定计算来提高整体性能。同样,有时可以通过增加库仑截止的长度来实现额外的加速,从而减少远程求解器所做的工作。使用与 OPENMP 包兼容的 run_style verlet/split 命令是减少分配给 KSpace 计算的 MPI 任务数量的另一种方法。
其他性能提示如下:
- 当每个物理 CPU 芯片(即插槽或芯片)至少有一个 MPI 任务时,通常可以实现 omp 样式的最佳并行效率。
- 将线程限制到单个套接字通常是最有效的,即每个套接字使用一个或多个 MPI 任务。
- 注意:默认情况下,当前的多个 MPI 实现使用处理器关联设置,将每个 MPI 任务限制为单个 CPU 内核。在这种模式下使用多线程将强制所有线程共享一个核心,因此可能会适得其反。相反,将 MPI 任务绑定到(多核)套接字应该可以解决此问题。
限制
没有任何限制。
7.4.5. OPT包
OPT 包由 James Fischer(High Performance Technologies)、David Richie 和 Vincent Natoli(Stone Ridge Technologies)开发。它包含一些pair样式,其compute()方法以C++模板形式重写,以减少由于if测试和其他条件代码而产生的开销。
所需的硬件/软件
任何硬件。任何编译器。
使用 OPT 包构建 LAMMPS
请参阅构建附加页面以获取说明。
从命令行运行 OPT 包
lmp_mpi -sf opt -in in.script # run in serial
mpirun -np 4 lmp_mpi -sf opt -in in.script # run in parallel
使用“-sf opt”命令行开关,它会自动将“opt”附加到支持它的样式中。
或者通过编辑输入脚本来运行 OPT 包
使用 suffix opt 命令,或者您可以显式地将“opt”后缀添加到输入脚本中的各个样式,例如
pair_style lj/cut/opt 2.5
预期加速
您应该会看到运行结束时打印的“配对时间”值减少。在大多数机器上,对于合理的问题大小,这将节省 5% 到 20%。
最佳性能指南
只需尝试 OPT pair style ,看看它的表现如何。
限制
没有任何限制。