并行计算中的性能优化与预测模型
立即解锁
发布时间: 2025-10-24 00:56:37 阅读量: 20 订阅数: 22 AIGC 

高性能计算前沿探索
### 并行计算中的性能优化与预测模型
在并行计算领域,提升计算性能和准确预测代码性能是两个至关重要的目标。下面将为大家介绍并行多网格求解器的自动调优以及基于多核 CPU 的模板代码预测性能模型。
#### 并行多网格求解器的自动调优
在并行多网格求解器的过程中,使用混合并行编程模型自动选择单线程或多线程是一项关键技术。通过提出的简单经验方法对相关参数进行自动调优(AT),该方法基于运行时调优过程以优化通信,并从简单的离线基准测试中得出多线程关键循环长度的参数。
为了评估该方法的效果,在 T2K/Tokyo、Cray XE6 和 Fujitsu FX10 上使用了多达 8192 个核心进行测试。以下是“小”规模案例(65,536 (=64×32×32) 网格/节点)下,不同配置与原始案例(policy=000)相比的加速比表格:
| 系统 | T2K/Tokyo (512 nodes) | Cray XE6 (128 nodes) | Fujitsu FX10 (128 nodes) |
| --- | --- | --- | --- |
| **HB 4×4/6×4** | | | |
| 原始 | 1.00 | 1.00 | 1.00 |
| AT | 1.08 | 1.49 | 1.06 |
| 估计最佳 | 1.14 | 1.41 | 1.06 |
| **HB 8×2/12×2** | | | |
| 原始 | 0.963 | 0.879 | 1.03 |
| AT | 1.35 | 1.38 | 1.08 |
| 估计最佳 | 1.29 | 1.47 | 1.06 |
| **HB 16×1/24×1** | | | |
| 原始 | 0.572 | 0.652 | 0.866 |
| AT | 1.12 | 1.14 | 0.920 |
| 估计最佳 | 1.08 | 1.06 | 0.932 |
从表格数据可以看出,提出的 AT 方法非常有效。当每个节点的问题规模相对较小时,在 T2K/Tokyo 和 Cray XE6 上,自动调优后的代码性能是原始代码的两倍。该方法在这些架构的强缩放计算中非常有用。然而,在 Fujitsu FX10 上效果不太显著,这是因为由于其硬件屏障,即使对于短循环,多线程也能提供更高的效率。由于原始代码是为 cc - NUMA 架构(如 T2K/Tokyo 和 Cray XE6)优化的,因此对于 Fujitsu FX10 可能需要不同的进一步优化策略。
目前的工作主要集中在单线程或多线程的选择上。一种更复杂的方法,即在每个级别定义最佳线程数,可能会进一步有助于优化。例如,对于 T2K/Tokyo 和 Fujitsu FX10 的 HB 16×1,当前的选择只有 16 线程或单线程,但在多网格的某些级别采用 2、4 或 8 线程的过程可能会进一步提高性能。
#### 基于多核 CPU 的模板代码预测性能模型
许多大型超级计算应用都是模板代码,这些代码通常受带宽限制,即根据屋顶线模型,其计算强度低于 CPU 的内存带宽。随着芯片上核心数量的增加,内存带宽的增长跟不上,这种情况更加严重。更好地利用缓存可以缓解带宽不足的问题,但并非所有代码都能从多线程、缓存优化或向量化中同等受益。
为了解决这些问题,提出了一种分析性能模型,该模型可以估计基于模板的模拟性能。与以前的模型不同,它既不依赖于原型实现,也不仅仅检查计算强度。该模型允许进行内存优化,如缓存分块和非临时存储,同时也涵盖了多线程、循环展开和向量化。
##### 缓存分块技术
缓存分块是缓解 CPU 带宽饥饿问题的常用技术,可分为空间分块和时间分块两种方式:
- **空间分块(平铺)**:将矩阵分割成适合缓存的较小块(或瓷砖)。由于块的边界元素的邻居不可用,这些元素无法更新。例如,如果要更新一个 b³ 单元格的块 x 步,则只有 (b - 2 · x)³ 个单元格可以写回。丢失的元素需要通过重叠块来补偿。选择最佳的块大小和缓存内更新步骤数并非易事,步骤越多,从缓存中读取的数据越多,但丢失的单元格也越多;块越大,这种影响越小,但所需的缓存也越大。
- **时间分块**:以波前的形式从内存连续流式传输数据,并对不同时间步的连续切片进行多次更新。这样做的优点是丢失的边界单元格较少。例如,如果穿过 3D 体积的波前是一个 b × b 单元格大小的瓷砖,并且每次扫描执行 x 次更新,则 (b - 2 · x)² 个单元格被写回到内存。为此,大约需要在内存中保留 2 · x + 1 个瓷砖。
##### 循环模型
为了构建性能模型,将代码序列视为嵌套循环。通过将指令流的不同部分映射到相应的 CPU 管道,并估计其吞吐量来计算性能。对于内存受限的循环,基于 Treibig 等人的模型进行扩展,以涵盖任意数量的数据流。
具体步骤如下:
1. 定义指令集 I 和 CPU 中的功能单元集 F。一个线性、无跳转的指令序列 s 可以描述为一个元组 s = (i1, i2, ..., ins)。调度函数 sched(s, j) 定义了序列 s 中的指令 ij 将映射到哪个功能单元 f ∈ F。
2. 在指令序列中,识别由功能单元 f ∈ F 定义的子序列 sk,即 sk = (ij|f(s, j) = k)。由于流水线的存在,大多数 CPU 每个时钟周期和每个功能单元可以执行一条指令,因此假设子序列 sk 的执行时间 t(sk)(以时钟周期为单位)就是子序列的长度,即 t(sk) = |sk|。
3. 考虑嵌套
0
0
复制全文


