54
Institute of Computing Technology, CAS 高高高高高高高 高高高高高高高高 高高高 高高高高高高高高高高高高

高性能计算机的 体系结构与程序优化

  • Upload
    chesmu

  • View
    75

  • Download
    9

Embed Size (px)

DESCRIPTION

高性能计算机的 体系结构与程序优化. 唐志敏 中国科学院计算技术研究所. 提纲. 应用编程与体系结构的关系 高性能计算机体系结构概述 CPU 内的并行结构(指令级并行) 存储器的层次结构 多体交叉的并行存储系统 分布存储系统中的通信优化. 体系结构的位置. 体系结构是硬件和系统软件之间的界面 Enable High Performance Support Ease Programming 编程模型是应用和计算机系统间的界面 理想的模型 : 应用不必了解具体的结构特征. 体系结构的主要研究内容. 如何提高性能 ? 先进的工艺技术--纯粹属于硬件的范围? - PowerPoint PPT Presentation

Citation preview

Page 1: 高性能计算机的 体系结构与程序优化

Institute of Computing Technology, CAS

高性能计算机的体系结构与程序优化高性能计算机的

体系结构与程序优化

唐志敏中国科学院计算技术研究所

Page 2: 高性能计算机的 体系结构与程序优化

提纲提纲• 应用编程与体系结构的关系• 高性能计算机体系结构概述• CPU 内的并行结构(指令级并行)• 存储器的层次结构• 多体交叉的并行存储系统• 分布存储系统中的通信优化

Page 3: 高性能计算机的 体系结构与程序优化

体系结构的位置体系结构的位置

Hardware

System Software

ApplicationsProgrammingModels

Architecture

• 体系结构是硬件和系统软件之间的界面– Enable High Performance– Support Ease Programming

• 编程模型是应用和计算机系统间的界面– 理想的模型 : 应用不必了解具体的结构特征

Page 4: 高性能计算机的 体系结构与程序优化

体系结构的主要研究内容体系结构的主要研究内容• 如何提高性能 ?

– 先进的工艺技术--纯粹属于硬件的范围?• 技术方面的缺点需要通过结构来弥补• DRAM 慢, SRAM 小=》存储器层次结构

– 体系结构方面的革新• 各个级别上并行性的开发

• 如何支持编程 ?– 共享内存– 承担一些软件较难完成的优化工作

• 如动态执行 , 猜测执行 , COMA 等

Page 5: 高性能计算机的 体系结构与程序优化

三种类型的体系结构技术三种类型的体系结构技术• 保守的结构

– 硬件仅提供必需的设施 , 如大量的寄存器– 高性能能否最终达到 , 完全依赖软件

• 折衷的结构– 硬件做一些动态的优化 , 如高速缓存– 软件仍有优化的余地

• 包揽式的结构– 硬件试图做充分的动态优化 , 如 COMA– 认为软件在动态分析和优化方面能力有限

Page 6: 高性能计算机的 体系结构与程序优化

结点内并行:超长指令字结构结点内并行:超长指令字结构• 芯片面积主要用于功能部件和高速缓存

– 完全依赖编译程序开发指令级并行性• 分支预测 , 循环展开 , 软件流水 , 踪迹调度

– 指令系统结构不兼容 • 显式并行指令结构( EPIC )

– Explicitly Parallel Instruction Computer – 128 位的 Group 包括 3 条指令– 设置专门的域指示指令间是否存在依赖关系– 可连接多个 Group 以支持更大范围内的并行

Page 7: 高性能计算机的 体系结构与程序优化

结点内并行:同时多线程结构结点内并行:同时多线程结构• 由硬件提供快速的上下文切换机制

– 引入了更多的指令级和线程级并行性– 容忍远程访问延迟和数据依赖的负面影响

• 多个上下文之间的切换机制– 发生事件时切换 ( 有点象进程的切换 )– 每个时钟周期都切换 : 每次取不同线程的指令

• 多个线程的指令在同一流水线中 ( 无依赖 )

• 第一个多线程系统 (Tera) 已经问世– 多线程同时工作对 cache 干扰很大

Page 8: 高性能计算机的 体系结构与程序优化

结点内并行超标量、动态调度、猜测执行

结点内并行超标量、动态调度、猜测执行

• 硬件动态地分析指令流,同时执行多条指令– 在分析区间内,指令以数据流的方式执行– 弥补编译器在静态分析和调度方面的不足– 换代后目标码不重新编译也能获得较好的性能

• 需要发掘指令级并行性的新来源–精确的动态分支预测,消除分支损耗– 设置大量换名寄存器,消除虚假的数据依赖– 不等分支完成,就开始执行目标指令(猜测)– 同时执行分支的多个目标(多标量)

Page 9: 高性能计算机的 体系结构与程序优化

结点间并行:消息传递系统结点间并行:消息传递系统• Tcomm = Tstartup + Tblock + Ncomm/Bcomm

• 如何实现与处理能力匹配的通信带宽– 通信带宽、通信延迟对应用性能的影响–光互连技术

• 如何减少通信开销– 用户级通信– 硬件支持重试、保证通信的可靠性和顺序

• 如何减少阻塞–自适应路由、优化应用的通信结构

Page 10: 高性能计算机的 体系结构与程序优化

结点间并行:共享存储系统结点间并行:共享存储系统• 共享存储的好处

–易于编程、通用性强– 与 SMP及其应用实现无缝衔接

• 存储一致性模型与实现效率–松 (弱 ) 一致性模型允许多种优化– 对系统软件设计或应用程序设计提出新的要求 ?

• 如何避免、隐藏或容忍远程访问的开销– Origin2000: 185 周期 ; 未来可能达数百万个周期– 缓存、预取、预送、多线程

Page 11: 高性能计算机的 体系结构与程序优化

结点间并行: COMA结点间并行: COMA• CC-NUMA 的主要问题

– 数据静态地分配在 home 结点上– 通过远程访问 cache 存取非本地的数据– 数据分配不当会造成大量的数据传输

• COMA 中没有物理地址 , 数据可动态迁移– 经过“预热” , 数据将被“吸引”到处理结点附近

• 主要问题 : 不命中时如何快速找到所需数据– 全系统的查找需大量时间– ProbOwner 目录 , Approximate Copyset

Page 12: 高性能计算机的 体系结构与程序优化

存储器的供数率跟得上吗?存储器的供数率跟得上吗?• CPU消耗数据的速率远大于存储器供数率

– 时钟频率增长的速度大于访存时间缩短的速度– 同时执行多条指令要求供数率进一步提高– 多线程或芯片内多处理器要求访问多组数据

• 已知的解决方案:存储器层次结构– 片内 cache 的供数率能满足指令级并行的要求 ?– 片内 cache 的命中率足够高 ?– 为多个线程或处理器提供各自的 cache?– 如何通过程序或算法的改进增强访存局部性 ?

Page 13: 高性能计算机的 体系结构与程序优化

性能不仅依赖于结构性能不仅依赖于结构• 性能的提高依赖于体系结构上的革新

– 硬件技术的发展对体系结构提出了新的要求– 各个层次并行性的开发是新体系结构的主要特征

• 实际性能的提高更依赖于体系结构与编译技 术、操作系统、应用算法间的配合与协调– Architectural Support for Programming Languages an

d Operating Systems, Since 1988

• 未来系统中两大问题的解决也是如此–①极长的等待时间;②极大的并行度

Page 14: 高性能计算机的 体系结构与程序优化

充分利用处理器内的并行• 提高单机性能是提高并行机性能的基础• 目前CPU 内部常用的并行结构包括:

– 指令流水线与运算流水线– 多个功能部件并行执行

• 如:定点运算、存 / 取、浮点加、浮点乘、…• 充分流水、并行工作的条件

– 指令间没有相关,即相互独立– 结构相关:两条指令要用同一个部件– 数据相关:一条指令要用另一条指令的结果–控制相关:条件转移指令影响其它指令

Page 15: 高性能计算机的 体系结构与程序优化

发挥 CPU内并行性的主要手段• 编译程序:静态指令调度

– 分析程序中的指令流– 在不影响结果的前提下,对指令重新排序– 缺点:不能获得运行时的动态信息–改进:基于 profile 的指令调度或优化

• 硬件:超标量、动态指令调度– 由专用硬件检查即将执行的一段指令–挑选出源操作数和功能部件都已齐备的指令– 缺点:硬件会变得很复杂、降低时钟频率

Page 16: 高性能计算机的 体系结构与程序优化

假设:取数时间较长,后续指令不能立即使用源程序语句: a = b + c; d = e - f;

a, b, c, d ,e, f 都在存储器中 .

Slow code:

LW Rb,b

LW Rc,c

ADD Ra,Rb,Rc

SW a,Ra

LW Re,e

LW Rf,f

SUB Rd,Re,Rf

SW d,Rd

指令调度的例子

Fast code:

LW Rb,b

LW Rc,c

LW Re,e

ADD Ra,Rb,Rc

LW Rf,f

SW a,Ra

SUB Rd,Re,Rf

SW d,Rd

Page 17: 高性能计算机的 体系结构与程序优化

应用程序员可以做什么?• 仔细地研究编译器的优化功能和选项

– -O2, -O3, -finline-functions, -funroll-loops

• 充分利用已经优化过的库函数– 如 BLAS 等– 如果可能,找或编适合自己需要的高效率库

• 做一些源程序级的优化– 最典型的一种优化:循环展开– 为编译程序的优化提供更多的机会

Page 18: 高性能计算机的 体系结构与程序优化

循环展开的例子• 展开前的代码

DO 10 I = 1, N

10 Y(I) = A*X(I) + Y(I)• 这是一种常见的写法• 循环体里包含的运算量

较小( 1加、 1乘)• 循环控制意味着转移• 如果CPU 一拍能做 4 个浮点运算,这个循环的性能就不高了

• 展开 4 次后的代码DO 10 I = 1 , N , 4

Y(I)=A*X(I)+Y(I)

Y(I+1)=A*X(I+1)+Y(I+1)

Y(I+2)=A*X(I+2)+Y(I+2)

10 Y(I+3)=A*X(I+3)+Y(I+3)• 暴露出了更多的可同时执行的操作

• 不好看,但实用

Page 19: 高性能计算机的 体系结构与程序优化

运算顺序的调整• 通常的算法设计和程序实现中,人们习惯在需要某数据的地方才计算出该数据的值,紧接着使用该数据。

• 这是很自然的思维习惯,但对于流水线则会造成麻烦。

• 两个运算相继进行,但后一个运算需要的操作数还没有被计算出来,只有原地等待,造成了流水线的停滞。

Page 20: 高性能计算机的 体系结构与程序优化

运算顺序的调整• 如下例所示:• b[0]=a[0]*a[0];• c[0]=1/b[0];• b[1]=a[1]*a[1];• c[1]=1/b[1];• b[2]=a[2]*a[2];• c[2]=1/b[2];• ……• 是求一系列数的平方的倒数的操作。虽然因为 c[0]紧接着 b[0] 计算,让计算的内在含义更明显,也更符合通常的思维习惯,但对于流水线来说效率极差。

Page 21: 高性能计算机的 体系结构与程序优化

运算顺序的调整• 现在变动如下: • b[0]=a[0]*a[0];• b[1]=a[1]*a[1];• b[2]=a[2]*a[2];• ……• c[0]=1/b[0];• c[1]=1/b[1];• c[2]=1/b[2];• ……

调整以后,先是整个的把数组 b[] 计算出来,然后再计算数组 c[] ,此时,需要的 b[] 数组中的数据都已经计算出来了,就不会存在流水线停滞的问题。

Page 22: 高性能计算机的 体系结构与程序优化

更一般的形式• 原始循环

DO 10 I = 1, N

B(I) = A(I) * A(I)

10 C(I) = 1 / B(I)

• 优化后的循环DO 10 I = 1, N

10 B(I) = A(I) * A(I)

DO 20 I = 1, N

20 C(I) = 1 / B(I)

• 又称为循环拆分

• 进一步优化DO 10 I = 1, N, 3

B(I) = A(I) * A(I)

B(I+1)=A(I+1)*A(I+1)

B(I+2)=A(I+2)*A(I+2)

C(I) = 1 / B(I)

C(I+1) = 1 / B(I+1)

10 C(I+2) = 1 / B(I+2)

• 先展开,再调整顺序

Page 23: 高性能计算机的 体系结构与程序优化

存储器的层次结构• 弥补 CPU 与主存间的速度差异• 各个层次间的访问速度和容量差别

– 寄存器: 32 个;几乎不需要时间– 一级 cache: 16KB-128KB; 1 个时钟周期–二级 cache: 128KB-4MB;几个时钟周期–本地主存: 64MB-1GB;几十个时期周期– 远程主存: 512MB 以上;成百上千个周期– 硬盘对换区(虚存):成千上万个周期

Page 24: 高性能计算机的 体系结构与程序优化

存储层次发挥作用的基本原理• 程序的访存局部性( locality )

– 时间局部性:最近访问的,将来还要访问–空间局部性:访问了 A ,则要访问 A 的近邻

• 局部性使快速存储区的内容多次被访问–比喻: 80% 的时间花在 20% 的代码上

• 工作集:最近程序集中访问的地址空间– 调整程序结构,使工作集小于 cache 容量

Page 25: 高性能计算机的 体系结构与程序优化

寄存器的使用• 寄存器的使用基本上是可以控制的

– 在汇编子程序里完全可以控制– 在 C语言里用 register说明用得最多的变量

• 需要考虑 CPU 内通用寄存器和浮点寄存器的数量– 编译程序在生成代码前,会进行寄存器分配

• 程序设计与优化时,可考虑寄存器利用– 最内层循环体不宜过长,寄存器会不够用– 循环展开的次数不能太多

Page 26: 高性能计算机的 体系结构与程序优化

寄存器的使用• for ( k=0;k<10;k++)• {• for (j=0;j<1000;j++)• 执行运算过程 B;• }• 运算过程 B 的大小也是我们必须考虑的。如果 B 过大,

CPU 内部寄存器的压力就会很大,如果寄存器的数量不足以保存 B 中出现的所有数据,可能会出现颠簸的现象,刚刚从寄存器中换出的数据也许就是下一个需要的数据,还得重新读入寄存器,这对效率显然是有影响的。解决的办法是将循环体过大的循环拆分成若干循环体较小的循环,这种方法叫做循环分布,循环体拆分的粒度是以寄存器数量的多少为参考的。

Page 27: 高性能计算机的 体系结构与程序优化

寄存器的使用• 根据运算过程 B 的实际情况和并行环境

的特点,可以拆分为以下两种形式中的一种。 形式 A:

• for(k=0;k<10;k++) {

• for(j=0;j<1000;j++)

• 执行运算过程 B1;• for(j=0;j<1000;j++)

• 执行运算过程 B2;• }

Page 28: 高性能计算机的 体系结构与程序优化

寄存器的使用• 形式 B:• for(k=0;k<10;k++){• for(j=0;j<1000;j++)• 执行运算过程 B1;• }• for(k=0;k<10;k++){• for(j=0;j<1000;j++)• 执行运算过程 B2;• }• 形式 A比较符合人们的习惯思维方式,形式 B

对循环的拆分更彻底,更加有利于并行执行。

Page 29: 高性能计算机的 体系结构与程序优化

高速缓冲存储器 (cache)

• 自然地利用局部性,对程序员“透明”– 存放最近最常用的数据和指令

• Cache 的工作规则–基本单位:块 (block)、行 (line)–放置策略:直接映射、组相联、全相联

• 衡量 cache效果的主要指标:命中率–若命中率为 90%, 不命中时需要另花 10 个周期–则平均访存时间为: 1+10%*10 = 2 周期–即存储系统的速度是 cache 速度的 1/2

Page 30: 高性能计算机的 体系结构与程序优化

Cache中块的放置策略 • Block 12 placed in 8 block cache:

– 全相联、直接映射、 2路组相联–组号 = 块号 % 组数

Memory

Cache

8路组相联 1路组相联 2路组相联

只有 1 个组 共有 8 个组 共有 4 个组

Page 31: 高性能计算机的 体系结构与程序优化

Cache不命中的三个原因 (3C)• 首次访问 Compulsory Cache 中没有这个块,

必须从内存取入 – Misses in even an Infinite Cache

• 容量不足 Capacity 换出后又被取入 cache– Misses in Fully Associative Size X Cache

• 冲突 Conflict 组相联或直接映射 cache 中,映射到同一组的内存块数过多,导致某些块换出后又被取入 – Misses in N-way Associative, Size X Cache

Page 32: 高性能计算机的 体系结构与程序优化

调整程序以提高 cache命中率• 代码(指令)

– 重新安排程序中不同过程在内存中的位置– 更适合编译程序,在 profile 的帮助下做

• 数据:程序设计者大有可为– 数组合并 : 利用块长,改善空间局部性– 循环交换 : 改变嵌套循环中访问内存的次序– 循环合并 : 增强数据的可重用性(时间局部性)– 分块 : 集中访问可取入 cache 的块状矩阵,避免全行或全列的读写,以增强时间局部性

Page 33: 高性能计算机的 体系结构与程序优化

数组合并的例子/* Before: 2 sequential arrays */

int val[SIZE]; int key[SIZE];

/* After: 1 array of stuctures */

struct merge {

int val;

int key;

};

struct merge merged_array[SIZE];

Reducing conflicts between val & key; improve spatial locality

Page 34: 高性能计算机的 体系结构与程序优化

循环交换的例子/* Before */

for (k = 0; k < 100; k = k+1)

for (j = 0; j < 100; j = j+1)

for (i = 0; i < 5000; i = i+1)

x[i][j] = 2 * x[i][j];

/* After */

for (k = 0; k < 100; k = k+1)

for (i = 0; i < 5000; i = i+1)

for (j = 0; j < 100; j = j+1)

x[i][j] = 2 * x[i][j];

将步长为 100字的跳跃式访问变为顺序访问,增强了空间局部性

Page 35: 高性能计算机的 体系结构与程序优化

循环合并的例子/* Before */

for (i = 0; i < N; i = i+1)

for (j = 0; j < N; j = j+1)

a[i][j] = 1/b[i][j] * c[i][j];

for (i = 0; i < N; i = i+1)

for (j = 0; j < N; j = j+1)

d[i][j] = a[i][j] + c[i][j];

/* After */

for (i = 0; i < N; i = i+1)

for (j = 0; j < N; j = j+1)

{ a[i][j] = 1/b[i][j] * c[i][j];

d[i][j] = a[i][j] + c[i][j];}

访问 a 和 c 的 2 次不命中降为 1 次

Page 36: 高性能计算机的 体系结构与程序优化

分块的例子/* Before */for (i = 0; i < N; i = i+1)for (j = 0; j < N; j = j+1)

{r = 0; for (k = 0; k < N; k = k+1){

r = r + y[i][k]*z[k][j];}; x[i][j] = r;};

• 两个内层循环中 :–读了 z[ ] 的所有 NxN 个元素– 重复读 y[ ] 的某一行 N 次,写 x[ ] 的某一行 1 次

• 不命中次数是 N及 cache 大小的函数–当 3 NxNx4 小于 cache 容量时,没有不命中

• 分块的思想:计算 cache 中放得下的 BxB子矩阵

Page 37: 高性能计算机的 体系结构与程序优化

分块的例子/* After */for (jj = 0; jj < N; jj = jj+B)for (kk = 0; kk < N; kk = kk+B)for (i = 0; i < N; i = i+1) for (j = jj; j < min(jj+B-1,N); j = j+1)

{r = 0; for (k = kk; k < min(kk+B-1,N); k = k+1) {

r = r + y[i][k]*z[k][j];}; x[i][j] = x[i][j] + r;};

B称为分块因子Blocking Factor• 不命中数从 2N3 + N2 降到 2N3/B +N2

• 但还存在因冲突导致的不命中

Page 38: 高性能计算机的 体系结构与程序优化

减少因分块导致的冲突不命中

• 需要对分块后形成的子矩阵进行重新布置

Blocking Factor

Mis

s R

ate

0

0.05

0.1

0 50 100 150

Fully Associative Cache

Direct Mapped Cache

Page 39: 高性能计算机的 体系结构与程序优化

分块的性能提高

• 矩阵乘法: N=500

• 在 i860 上– 分块前,运行时间为 77.00秒– 分块后,运行时间为 22.41秒,加速比 3.44

• 在 Pentium 166MMX 上– 分块前,运行时间为 28.52秒– 分块后,运行时间为 6.67秒,加速比 4.22

Page 40: 高性能计算机的 体系结构与程序优化

多体交叉并行存储系统• 提高主存带宽的重要途径

– 多个独立的存储体,统一编址,同时工作– 访问均匀地分布在所有体内时,带宽线性提高

• 地址分配方式: word interleave

000000 000001 000002 000003

000004 000005 000006 000007

FFFFFFFFFFFEFFFFFDFFFFFC

M0 M1 M2 M3

Page 41: 高性能计算机的 体系结构与程序优化

并行存储器中的访问冲突• 基本条件:体数不小于访存所需要的时钟周期数,以保证顺序访问时

不会有体冲突• 体数增大时,冲突的机会会少一些,但成本增加了• 体数正好等于访存周期数时,有下面的结论• 考虑固定步长的访问序列A, A+S, A+2S, A+3S, ...• 若一共有 N 个存储模块,则该访问序列集中在

• 若GCD(N, S) = 1, 则冲突访问的概率最小• 因为 N 一般是 2 的幂次,所以 S 最好不是 2 的幂次

N

GCD(N, S)个体内

Page 42: 高性能计算机的 体系结构与程序优化

对数组元素的冲突访问• 在 C语言中,数组元素按行存放,按列访

问时会产生冲突• 在 FORTRAN 中,按列存放,按行访问时会产生冲突

• 其它导致冲突的情形–矩阵中的一个长方形块– FFT 算法中存取步长依次为 2i, i = 0, 1, 2, …

• 减少冲突的方法(与 cache 优化类似)– 循环交换、数组加边

Page 43: 高性能计算机的 体系结构与程序优化

并行处理概述• 利用多个部件完成同一个任务• 并行处理的好处

– 提高性能:缩短解题时间,扩大解题规模–降低成本:与同样性能的单机相比– 容错:更高的可用性

• 并行处理的层次–处理机内:指令级并行,多功能部件–处理机间:多处理机,多计算机

Page 44: 高性能计算机的 体系结构与程序优化

多机并行的基本形式• 按指令流与数据流的数量来划分

–单指令流多数据流( SIMD )– 多指令流多数据流( MIMD )

• 按机间的互连方式来划分–总线结构、交叉开关、网格结构、超立方体–树型结构、星型结构

• 按存储器的组织方式来划分–集中式存储,通常是为多个处理机共享– 分布式存储,通常是各个处理机私有的

Page 45: 高性能计算机的 体系结构与程序优化

两种基本的结构

互连网络(总线、开关等)

P1 Pn

M1 Mn

分布存储的结构

适合任务间并行

互连网络(总线、开关等)

P1 Pn

M1 Mn

共享存储的结构

适合任务间、任务内并行

Page 46: 高性能计算机的 体系结构与程序优化

并行处理的过程:矩阵乘法

• A B = C 的过程可分为四个独立的部分:Ai B = Ci , i = 1, 2, 3, 4

• 每部分包含的运算可由一台处理机单独完成• 在集中存储的系统中,同时访问 B会导致冲突• 在分布存储的系统中, B 的分散存储会导致通信

A B C

X =

A1

A2

A3

A4

C1

C2

C3

C4

Page 47: 高性能计算机的 体系结构与程序优化

并行处理的性能

• 加速比:串行计算时间除以并行计算时间• 加速比小于处理单元数目的原因:

– 存在不可并行成分: Speedup < 1/s– 负载不均衡:有些处理机没事做– 通信开销:包括传递消息、访存冲突等– 同步开销:为了步调一致,必须相互等待

• 极端的情况:并行后的性能比单机还差• 也可能出现超线性的加速比

Page 48: 高性能计算机的 体系结构与程序优化

并行粒度:在哪个级别上并行?

• 子任务级的并行(粗粒度)–例如:方位 FFT、距离 FFT、距离 IFFT、方位 I

FFT 各由一个处理机完成,形成宏观流水–子任务的运算量差别较大时,不易实现负载的平衡

• 数据级的并行(中等粒度或细粒度)– 对问题相关的数据场进行划分,每个处理器负责整

个数据场的一小部分– 各部分间耦合较多时,对存储器及互连网络的性能

要求较高

Page 49: 高性能计算机的 体系结构与程序优化

并行算法设计• 并行算法设计的目标

– 开发问题求解过程中的并行性–寻求并行算法与并行结构的最佳匹配–合理地组织并行任务,减少额外的开销

• 并行化的主要方法:分而治之–根据问题的求解过程,把任务分成若干子任务–根据处理数据的方式,形成多个相对独立的数据区,

由不同的处理器分别处理–将一个循环分成多个循环并行地执行

Page 50: 高性能计算机的 体系结构与程序优化

并行计算机设计程序的三种方式• 串行程序的自动并行化

– 用户提供常规的串行程序,编译器完成并行化– 由于编译器能力有限,只对部分应用有效

• 使用全新的并行语言:函数型、数据流等– 已有应用程序需要全部改写– 新语言的实现效率有待进一步提高

• 串行语言 + 并行化扩充–增加支持并行性开发与通信同步的库调用–增加新的语言成分,如数组运算、并行循环等– SPMD (Single Program Multiple Data) 编程模式

Page 51: 高性能计算机的 体系结构与程序优化

例子:矩阵乘法(串行)

double a[N][N],b[N][N],c[N][N];

for (i=0; i<N; i++)

for (j=0; j<N; j++)

for (k=0; k<N; k++)

c[i][j]+=a[i][k]*b[k][j];

Page 52: 高性能计算机的 体系结构与程序优化

例子:矩阵乘法(并行 1)一开始就有 P个并行进程

• myid 的值为 0,1,...,P-1

begin=N*myid/P;

end=N*(myid+1)/P;

for (i=begin; i<end; i++)

for (j=0; j<N; j++)

for (k=0; k<N; k++)

c[i][j]+=a[i][k]*b[k][j];

Page 53: 高性能计算机的 体系结构与程序优化

例子:矩阵乘法(并行 2)一开始只有一个进程在运行

• 在 main函数内:for (i=0; i<P; i++)

fork(subp,N*i/P,N*(i+1)/P)• 在 subp(int begin, int end)函数内:for (i=begin; i<end; i++)

for (j=0; j<N; j++)

for (k=0; k<N; k++)

c[i][j]+=a[i][k]*b[k][j];

Page 54: 高性能计算机的 体系结构与程序优化

例子:矩阵乘法(并行 3)一开始只有一个进程在运行

• forall 循环中的所有迭代均可并行执行forall (i=0; i<N; i++)

for (j=0; j<N; j++)

for (k=0; k<N; k++)

c[i][j]+=a[i][k]*b[k][j];• 程序首先由单个进程运行,遇 forall 时自

动进入多进程运行,出 forall 后恢复单进程运行。处理机数不显式地给出。