高性能计算优化与平台架构概述
立即解锁
发布时间: 2025-08-21 02:07:51 阅读量: 1 订阅数: 4 


高性能计算系统优化与应用设计
### 高性能计算优化与平台架构概述
#### 1. 快速优化技巧
在面临压力时,有一些快速且经过验证的优化技巧可以尝试,可能会立即带来显著的性能提升。以下是在时间紧迫时可遵循的步骤:
- **使用 Intel MPI 库**:Intel MPI 库为带宽受限的应用程序提供了出色的开箱即用性能。如果应用程序属于此类,切换后能立即感受到差异。
- 若应用程序是为与 Intel MPI 兼容的发行版(如 MPICH、MVAPICH2 或 IBM POE 等)构建的,无需重新编译应用程序,可在运行时动态链接 Intel MPI 5.0 库:
```bash
$ source /opt/intel/impi_latest/bin64/mpivars.sh
$ mpirun -np 16 -ppn 2 xhpl
```
- 若使用其他 MPI 且能访问应用程序源代码,可使用 Intel MPI 编译器脚本重建应用程序:
- 若目标是 GNU 编译器,使用 `mpicc`(用于 C)、`mpicxx`(用于 C++)和 `mpifc/mpif77/mpif90`(用于 Fortran)。
- 若目标是 Intel Composer XE,使用 `mpiicc`、`mpiicpc` 和 `mpiifort`。
- **使用 Intel Composer XE**:Intel Composer XE 的调用与广泛使用的 GNU 编译器集合(GCC)基本兼容,包括常用的命令行选项以及对 C/C++ 和 Fortran 的语言支持。对于许多应用程序,可简单地将 `gcc` 替换为 `icc`,`g++` 替换为 `icpc`,`gfortran` 替换为 `ifort`。但需注意,Intel Fortran Composer 生成的二进制代码与 GCC 构建的可执行代码不兼容。
```bash
$ source /opt/intel/composerxe/bin/compilervars.sh intel64
$ icc -O3 -xHost -qopenmp -c example.o example.c
```
切换编译器后,需重新审视之前使用的编译器标志,可能需要移除一些标志,并确保使用能为应用程序带来最佳性能的标志。以下是部分 Intel Composer XE 优化标志的对比:
| GCC | ICC | 效果 |
| --- | --- | --- |
| -O0 | -O0 | 禁用(几乎所有)优化,不适合追求性能时使用 |
| -O1 | -O1 | 优化速度(ICC 不增加代码大小) |
| -O2 | -O2 | 优化速度并启用向量化 |
| -O3 | -O3 | 开启高级优化 |
| -ftlo | -ipo | 启用过程间优化 |
| -ftree-vectorize | -vec | 启用自动向量化(-O2 和 -O3 自动启用) |
| -fprofile-generate | -prof-gen | 生成用于优化的运行时配置文件 |
| -fprofile-use | -prof-use | 使用运行时配置文件进行优化 |
| -parallel | | 启用自动并行化 |
| -fopenmp | -qopenmp | 启用 OpenMP |
| -g | -g | 生成调试符号 |
| -qopt-report | | 生成优化报告 |
| -vec-report | | 生成向量化报告 |
| -ansi-alias | | 为 C/C++ 启用 ANSI 别名规则 |
| -msse4.1 | -xSSE4.1 | 为具有 SSE 4.1 指令的 Intel 处理器生成代码 |
| -mavx | -xAVX | 为具有 AVX 指令的 Intel 处理器生成代码 |
| -mavx2 | -xCORE - AVX2 | 为具有 AVX2 指令的 Intel 处理器生成代码 |
| -mcpu = native | -xHost | 为当前用于编译的机器生成代码 |
对于大多数应用程序,默认的优化级别 -O2 就足够了,它运行速度快且能提供合理的性能。若想尝试更激进的优化,可使用 -O3,但这会增加编译时间。
#### 2. 调整 Intel MPI 库
若有更多时间,可在不更改应用程序源代码的情况下调整 Intel MPI 参数。
- **收集内置统计数据**:Intel MPI 自带内置的统计数据收集机制,运行时开销可忽略不计,并以流行的 IPM 格式报告关键性能指标。
```bash
$ export I_MPI_STATS=ipm
$ mpirun -np 16 xhpl
```
默认情况下,会生成一个名为 `stats.ipm` 的文件。通过分析该文件中的数据,可了解 MPI 通信在总运行时间中所占的比例,以及各 MPI 操作(如 MPI_Send、MPI_Recv 和 MPI_Wait)在总 MPI 时间中所占的比例,从而找出潜在的负载不平衡问题,并针对性地优化性能。
- **优化进程放置**:Intel MPI 库会在有可用核心的情况下,将相邻的 MPI 进程放在一个集群节点上。可使用 `-ppn` 命令行参数控制进程在集群节点间的放置。
```bash
$ mpirun -np 16 -ppn 2 xhpl
```
Intel MPI 支持进程固定,以将 MPI 进程限制在系统的特定部分,优化进程布局,例如避免 NUMA 效应或减少到 InfiniBand 适配器的延迟。若想仅在物理处理器核心上运行纯 MPI 程序,可执行以下命令:
```bash
$ export I_MPI_PIN_PROCESSOR_LIST=allcores
$ mpirun -np 2 your_MPI_app
```
若想运行混合 MPI/OpenMP 程序,可保持 Intel MPI 的默认设置。若要分析 Intel MPI 进程布局和固定情况,可设置以下环境变量:
```bash
$ export I_MPI_DEBUG=4
```
- **优化线程放置**:若应用程序使用 OpenMP 进行多线程处理,除了进程放置外,还可控制线程放置。有两种可能的策略:
```bash
$ export KMP_AFFINITY=granularity=thread,compact
$ export KMP_AFFINITY=granularity=thread,scatter
```
第一种设置将线程紧密放置在一起,以改善线程间通信;第二种设置将线程分布在系统中,以最大化内存带宽。使用 OpenMP API 版本 4.0 的程序可使用等效的 OpenMP 亲和性设置替代 `KMP_AFFINITY` 环境变量:
```bash
$ export OMP_PROC_BIND=close
$ export OMP_PROC_BIND=spread
```
若使用 `I_MPI_PIN_DOMAIN`,MPI 会将 MPI 进程的 OpenMP 线程限制在单个套接字上,可使用以下设置避免线程在套接字的逻辑核心之间移动:
```bash
$ export KMP_AFFINITY=granularity=thread
```
#### 3. 调整 Intel Composer XE
若能访问应用程序的源代码,可通过选择合适的编译器开关并重新编译源代码来进行优化。
- **分析优化和向量化报告**:添加编译器标志 `-qopt-report` 和/或 `-vec-report` 可查看编译器对源代码所做的操作,报告所有应用于代码的转换,并突出显示阻止成功优化的代码模式。以下是一个示例优化报告的部分内容:
```bash
$ ifort -O3 -qopenmp -qopt-report -qopt-report-file=stdout -c example.F90
```
```plaintext
Report from: Interprocedural optimizations [ipo]
...
OpenMP Construct at example.F90(8,7)
remark #15059: OpenMP DEFINED LOOP WAS PARALLELIZED
OpenMP Construct at example.F90(25,7)
remark #15059: OpenMP DEFINED LOOP WAS PARALLELIZED
...
```
向量化报告包含与优化报告相同的向量化信息。
- **使用过程间优化**:添加编译器标志 `-ipo` 可开启过程间优化,让编译器对程序有更全面的了解,为整个程序提供更多优化机会,但会增加整体编译时间。运行时配置文件也可增加编译器生成更好代码的机会,基于配置文件的优化需要三个阶段:
1. 使用编译器标志 `-prof-gen` 编译应用程序,为应用程序插入配置文件代码。
2. 使用典型数据集运行插入配置文件代码的应用程序,生成有意义的配置文件。
3. 将配置文件提供给编译器(`-prof-use`),让其优化代码。
#### 4. 性能指标概述
为了优化软件,需要了解硬件。在高性能计算中,常见的性能指标包括延迟、吞吐量、能量和功率。
- **延迟**:完成一个动作所需的总时间是典型的延迟指标,如应用程序的运行时间、网络中数据包从源到目的地的传输时间、处理器中指令从进入执行单元到结果可用的时间等。延迟指标具有可加性,若应用程序有三个依次执行的子任务,分别耗时 T1、T2 和 T3,则总运行时间为 Tapp = T1 + T2 + T3。
- **吞吐量**:描述系统在单位时间或单位其他消耗资源内可完成的工作量,如处理器每秒执行的指令数(IPS)、每秒浮点运算次数(FLOPS)、内存带宽和网络互连吞吐量等。功率(瓦)也是一种吞吐量指标,定义为单位时间内的能量流,等于 1 焦耳/秒。
吞吐量有时可描述为延迟的倒数,但仅当两个指标描述的是对相同工作量应用的相同过程时才成立。例如,一个应用程序或内核在一秒内完成 10^9 次浮点算术运算,其吞吐量为 1 GFLOPS。但在计算机网络中,延迟通常指数据包开始传输到第一个数据到达目的地的时间,此时延迟不等于吞吐量的倒数。
- **能量**:完成工作所需的电量称为解决问题的能量,单位为焦耳,日常生活中常用瓦时。能量消耗决定了电费,是高性能计算设施运营费用中的重要一项,因此除了传统的减少运行时间、提高并行效率等努力外,还需要对解决问题的能量进行优化。
- **并发度**:系统或过程的另一个重要概念是并发度或并行度,定义为可同时执行的工作项数量。例如,在一个有三条赛道的赛车场中,可同时有三辆赛车比赛,并发度为 3。在计算中,多核处理器同时执行多个结构不同的应用程序“线程”就是并发的例子。现代高性能系统都具有并发的特性,集群中不同机器上运行的进程共同构成一个系统,可同时在多台机器上执行应用程序代码。
通过合理运用上述优化技巧和理解性能指标,可在高性能计算中提升应用程序的性能。
### 高性能计算优化与平台架构概述
#### 5. 延迟与吞吐量的关系及特点
延迟和吞吐量是高性能计算中两个重要的性能指标,它们之间的关系和特点对于理解系统性能至关重要。
在某些情况下,高吞吐量的系统可能具有较低的延迟,但两者之间并没有必然的因果联系。例如,比较 GDDR5(图形双倍数据速率,版本 5)和 DDR3(双倍数据速率,类型 3)的内存带宽和延迟,具有 GDDR5 内存的系统(如 Intel Xeon Phi 协处理器)带宽是 DDR3 系统的三到五倍,而在空闲环境下访问数据的延迟是 DDR3 系统的五到六倍。
延迟和吞吐量随负载变化的图形特征也有很大差异。内存访问延迟会随着负载的增加呈指数级上升,而吞吐量在开始时几乎呈线性上升,当传输介质的物理容量达到饱和时,吞吐量会趋于平稳。通过观察测试结果的图形,结合这些特征,就可以判断是延迟图还是吞吐量图。
以下是一个简单的 mermaid 流程图,展示了延迟和吞吐量随负载变化的大致趋势:
```mermaid
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A([开始]):::startend --> B(负载增加):::process
B --> C{类型}:::process
C -->|延迟| D(指数级上升):::process
C -->|吞吐量| E(线性上升):::process
E --> F(达到饱和):::process
F --> G(趋于平稳):::process
```
#### 6. 优化操作总结
为了方便大家在实际操作中进行优化,这里对前面提到的优化操作进行总结:
##### 6.1 使用 Intel 相关工具的操作步骤
| 操作 | 适用情况 | 操作步骤 |
| --- | --- | --- |
| 使用 Intel MPI 库 | 带宽受限应用或兼容 MPI 发行版的应用 | 1. 若应用为兼容发行版构建,运行时动态链接:<br>```bash<br>$ source /opt/intel/impi_latest/bin64/mpivars.sh<br>$ mpirun -np 16 -ppn 2 xhpl<br>```<br>2. 若使用其他 MPI 且有源码,使用编译器脚本重建:<br> - 目标为 GNU 编译器:使用 `mpicc`、`mpicxx`、`mpifc/mpif77/mpif90`<br> - 目标为 Intel Composer XE:使用 `mpiicc`、`mpiicpc`、`mpiifort` |
| 使用 Intel Composer XE | 替换 GCC 编译器 | 1. 替换编译器命令:`gcc` 换为 `icc`,`g++` 换为 `icpc`,`gfortran` 换为 `ifort`<br>2. 重新审视编译器标志:<br>```bash<br>$ source /opt/intel/composerxe/bin/compilervars.sh intel64<br>$ icc -O3 -xHost -qopenmp -c example.o example.c<br>``` |
##### 6.2 调整 Intel MPI 库的操作步骤
| 操作 | 目的 | 操作步骤 |
| --- | --- | --- |
| 收集内置统计数据 | 了解 MPI 性能指标 | ```bash<br>$ export I_MPI_STATS=ipm<br>$ mpirun -np 16 xhpl<br>``` |
| 优化进程放置 | 控制进程在集群节点的分布 | 1. 使用 `-ppn` 参数:<br>```bash<br>$ mpirun -np 16 -ppn 2 xhpl<br>```<br>2. 仅在物理核心运行纯 MPI 程序:<br>```bash<br>$ export I_MPI_PIN_PROCESSOR_LIST=allcores<br>$ mpirun -np 2 your_MPI_app<br>```<br>3. 分析进程布局和固定情况:<br>```bash<br>$ export I_MPI_DEBUG=4<br>``` |
| 优化线程放置 | 控制 OpenMP 线程放置 | 1. 两种策略:<br>```bash<br>$ export KMP_AFFINITY=granularity=thread,compact<br>$ export KMP_AFFINITY=granularity=thread,scatter<br>```<br>2. OpenMP API 4.0 等效设置:<br>```bash<br>$ export OMP_PROC_BIND=close<br>$ export OMP_PROC_BIND=spread<br>```<br>3. 避免线程在套接字逻辑核心移动:<br>```bash<br>$ export KMP_AFFINITY=granularity=thread<br>``` |
##### 6.3 调整 Intel Composer XE 的操作步骤
| 操作 | 目的 | 操作步骤 |
| --- | --- | --- |
| 分析优化和向量化报告 | 查看编译器对代码的操作 | ```bash<br>$ ifort -O3 -qopenmp -qopt-report -qopt-report-file=stdout -c example.F90<br>``` |
| 使用过程间优化 | 让编译器全面优化程序 | 1. 开启过程间优化:添加 `-ipo` 标志<br>2. 基于配置文件的优化:<br> 1. 使用 `-prof-gen` 编译应用程序<br> 2. 运行插入配置文件代码的应用程序生成配置文件<br> 3. 使用 `-prof-use` 让编译器优化代码 |
通过以上这些优化操作和对性能指标的理解,我们可以在高性能计算中更好地提升应用程序的性能,满足不同场景下的需求。在实际应用中,需要根据具体的硬件平台和应用特点,灵活选择和组合这些优化方法,以达到最佳的性能表现。
0
0
复制全文
相关推荐










