Presentation is loading. Please wait.

Presentation is loading. Please wait.

第十章 依赖于机器的优化 在指令级并行的机器上,程序的运行速度依赖于下面几个因素

Similar presentations


Presentation on theme: "第十章 依赖于机器的优化 在指令级并行的机器上,程序的运行速度依赖于下面几个因素"— Presentation transcript:

1 第十章 依赖于机器的优化 在指令级并行的机器上,程序的运行速度依赖于下面几个因素
第十章 依赖于机器的优化 在指令级并行的机器上,程序的运行速度依赖于下面几个因素 程序中潜在的并行 处理器上可用的并行 从串行程序提取并行的能力 在给定的调度约束下发现最佳并行调度的能力 并行的提取和并行执行的调度都可以静态地在软件中或动态地在硬件中完成

2 第十章 依赖于机器的优化 本章内容 使用指令级并行的基础问题 提取并行的数据相关性分析 代码调度的基本概念
第十章 依赖于机器的优化 本章内容 使用指令级并行的基础问题 提取并行的数据相关性分析 代码调度的基本概念 基本块调度的技术、发现通用程序中的高度数据相关控制流的方法、调度数值程序的软件流水线技术 在多处理器系统上,使用数组的计算密集型程序的并行化和数据局部性优化的概念和方法

3 10.1 处理器体系结构 在考虑指令级并行时,通常想象成一个处理器在单个时钟周期内发射几个操作
10.1 处理器体系结构 在考虑指令级并行时,通常想象成一个处理器在单个时钟周期内发射几个操作 事实上,在每周期内发射一个操作是可能的, 而指令级并行的获得是通过使用流水线技术 本节先解释流水线,然后讨论多指令发射 源码网:

4 10.1 处理器体系结构 10.1.1 指令流水线和分支延迟 i i + 1 i + 2 i + 3 i + 4 1. IF
10.1 处理器体系结构 指令流水线和分支延迟 i i + 1 i + 2 i + 3 i + 4 1. IF 2. ID IF 3. EX ID IF 4. MEM EX ID IF 5. WB MEM EX ID IF 6. WB MEM EX ID WB MEM EX WB MEM WB 5级指令流水线中 的5条连续指令 取指令IF, 译码ID, 执行操作EX, 访问内存MEM, 回写结果WB

5 10.1 处理器体系结构 10.1.1 指令流水线和分支延迟 分支延迟 发现应该执行一个分支而不是直接后继
10.1 处理器体系结构 指令流水线和分支延迟 分支延迟 发现应该执行一个分支而不是直接后继 转向一个分支时会引起取分支目的地址指令的延迟并引起指令流水线“打嗝” 可以通过使用硬件,根据分支的执行历史来预测分支结果并从预测的目的地址预取指令 分支延迟不可避免,因为分支预测会发生偏差

6 10.1 处理器体系结构 10.1.2 流水化的执行 如果不依赖一条指令结果的随后指令在该结 果产生前就被允许执行
10.1 处理器体系结构 流水化的执行 如果不依赖一条指令结果的随后指令在该结 果产生前就被允许执行 有些指令的执行需要几个周期,几个操作同时出现在它们的执行级上可能的 如果最长的执行流水线是n级,n个操作同时进行的可能性是存在的 并非所有的指令都能被完全流水化,例如浮点除 通用处理器大都动态察觉相继指令之间的依赖性 嵌入式系统把数据相关性的检查交给软件

7 10.1 处理器体系结构 10.1.3 多指令发射 每周期发射几个操作,让更多操作同时进行 超长指令字机器 超标量机器
10.1 处理器体系结构 多指令发射 每周期发射几个操作,让更多操作同时进行 超长指令字机器 将若干个操作编码在单周期中发射 编译器需要确定哪些操作可以并行发射 超标量机器 超标量机器有按普通顺序执行语义的正规指令集 硬件自动察觉指令之间的相关性,并且在它们的操作数可用时就发射它们 更复杂的调度器能够“乱序”执行指令

8 10.2 代码调度的约束 代码调度 本节讨论代码调度的约束 优化程序很难调试 用在代码生成器产生的机器代码上的优化技术
10.2 代码调度的约束 代码调度 用在代码生成器产生的机器代码上的优化技术 本节讨论代码调度的约束 控制相关约束 在原程序中执行的所有操作都必须在优化代码中执行 数据相关约束 优化程序中的操作产生的结果必须同原程序对应操作的结果一样 资源约束 调度不能过分占用机器的资源 优化程序很难调试 内存状态可能和顺序执行的任何内存状态不匹配

9 10.2 代码调度的约束 10.2.1 数据相关 数据相关概念可同时用于内存访问和寄存器访问
10.2 代码调度的约束 数据相关 真相关 如果对同一个单元先写后读,那么读依赖于所写的值 反相关 如果对同一个单元先读后写。可以通过把值存在不同的单元来删除反相关 输出相关 如果对同一个单元先后写两次。也可删除 数据相关概念可同时用于内存访问和寄存器访问

10 10.2 代码调度的约束 10.2.2 发现内存访问中的相关性 例 (1) a = 1 (2) p = 2 (3) x = a
10.2 代码调度的约束 发现内存访问中的相关性 (1) a = 1 (2) p = 2 (3) x = a 语句(1)和(2)可能构成输出相关 语句(1)和(3)可能构成真相关 语句(2)和(3)可能构成真相关 除非编译器知道p不可能指向a,否则3个操作必须串行执行

11 10.2 代码调度的约束 10.2.2 发现内存访问中的相关性 发现数据相关需要不同形式的分析 数组元素间的别名分析
10.2 代码调度的约束 发现内存访问中的相关性 发现数据相关需要不同形式的分析 数组元素间的别名分析 A[i]和A[j]是否互为别名 指针别名分析 若p和q相等,则p和q、p->next和q->next、 p->data和q->data等都分别互为别名 过程间分析 引用调用场合:形参和形参之间、形参和全局变量之间因实参而引起互为别名

12 10.2 代码调度的约束 10.2.3 寄存器使用和并行执行之间的折衷 例:(a + b) + c + (d + e) LD R1, a
10.2 代码调度的约束 寄存器使用和并行执行之间的折衷 例:(a + b) + c + (d + e) LD R1, a LD R2, b ADD R1, R1, R2 LD R2, c LD R2, d LD R3, e ADD R2, R2, R3 若瞄准极小化寄存器的使用个数,则只需使用3个寄存器 + e c a b d

13 10.2 代码调度的约束 10.2.3 寄存器使用和并行执行之间的折衷 例:(a + b) + c + (d + e) LD R1, a
10.2 代码调度的约束 寄存器使用和并行执行之间的折衷 例:(a + b) + c + (d + e) LD R1, a LD R2, b ADD R1, R1, R2 LD R2, c LD R2, d LD R3, e ADD R2, R2, R3 完成整个计算需要7步 + e c a b d

14 10.2 代码调度的约束 10.2.3 寄存器使用和并行执行之间的折衷 例:(a + b) + c + (d + e) + e c a b
10.2 代码调度的约束 寄存器使用和并行执行之间的折衷 例:(a + b) + c + (d + e) + e c a b d 如果对每个中间结果使用不同寄存器,则完成计算只需要4步 R1 = a R6 = R1+R2 R8 = R6+R3 R9 = R8+R7 R2 = b R7 = R4+R5 R3 = c R4 = d R5 = e

15 10.2 代码调度的约束 10.2.4 寄存器分配和代码调度的次序安排 先寄存器分配 先代码调度 结果代码中会有很多存储相关
10.2 代码调度的约束 寄存器分配和代码调度的次序安排 先寄存器分配 结果代码中会有很多存储相关 非数值应用本质上没有多少并行,采用这种方式 先代码调度 导致寄存器溢出,抵消指令级并行的优点 适用于有许多大表达式的数值应用 在假定伪寄存器就是物理寄存器情况下,先调度指令,然后寄存器分配,把处理寄存器溢出的代码附加在必要的地方,并再次进行代码调度

16 10.2 代码调度的约束 10.2.5 控制相关 在非数值计算中,基本块非常小,其中的操作通常高度相关,几乎不能并行
10.2 代码调度的约束 控制相关 在非数值计算中,基本块非常小,其中的操作通常高度相关,几乎不能并行 调查跨基本块的并行是至关重要的 若一条指令很可能被执行且有空闲的资源可“免费”用于完成该指令的操作,则可以投机地执行该指令;若投机成功,则程序运行得快一些 例 if (a > t) b = a  a依赖于比较a > t的结果 b = a  a; 若a  a不会产生副作用,则 d = a + c; a  a可以投机地执行

17 10.2 代码调度的约束 10.2.6 投机执行的支持 内存读取是一类使用频繁,且能从投机执行大大获益的指令
10.2 代码调度的约束 投机执行的支持 内存读取是一类使用频繁,且能从投机执行大大获益的指令 但在 if (p != null) q = p 中,投机地对p脱引用将引起该程序因p等于null而错误地停止 许多高性能处理器提供专门的特性来支持投机地内存访问

18 10.2 代码调度的约束 10.2.6 投机执行的支持 预取指令 在数据使用前将其从内存取到缓存,若该单元无效或访问它会引起缺页,则忽略
10.2 代码调度的约束 投机执行的支持 预取指令 在数据使用前将其从内存取到缓存,若该单元无效或访问它会引起缺页,则忽略 抑制位 允许投机地从内存将数据读取到寄存器堆,若出现非法内存访问或缺页,则设置目标寄存器的抑制位 判定指令 在判定条件为真时才执行的指令 例 if (a == 0) 翻译成 ADD R3, R4, R5 b = c + d; CMOVZ R2, R3, R1 假定a、b、c和d分别被分配了R1、R2、R4和R5 可用来将相邻基本块组合成一个更大基本块

19 10.2 代码调度的约束 10.2.7 一个基本的机器模型 机器模型M = (R, T) T:操作类型集,如读取、存储和算术运算等
10.2 代码调度的约束 一个基本的机器模型 机器模型M = (R, T) T:操作类型集,如读取、存储和算术运算等 R = [r1, r2, …]:硬件资源向量集,如内存访问部件、算术运算部件和浮点功能部件 ri代表第i类资源中可用的部件数 每个操作有一组输入操作数、一组输出操作数和一个资源需求 和每个输入操作数相关的是一个输入延迟 和每个输出操作数相关的是一个输出延迟

20 10.2 代码调度的约束 10.2.7 一个基本的机器模型 机器模型M = (R, T)
10.2 代码调度的约束 一个基本的机器模型 机器模型M = (R, T) 对每种操作类型t,资源使用由一张二维资源预留表RTt来建模 条目RTt[i, j]是t类型的一个操作在它被发射i时钟周期后,使用第j种资源的部件数 对任何t、i和j,RTt[i, j]必须小于或等于R[j]

21 10.3 基 本 块 调 度 10.3.1 数据依赖图 基本块由数据依赖图G = (N, E)来表示 G的结点集N和边集E按如下两步构造
10.3 基 本 块 调 度 数据依赖图 基本块由数据依赖图G = (N, E)来表示 结点集合N表示该块的机器指令中的操作集合 有向边集合E表示这些操作之间的数据相关约束 G的结点集N和边集E按如下两步构造 N中的每个操作n有一张资源预留表RTn,其值直接就是n的操作类型的资源预留表 每条边e都标示有延迟de,表示e的目的结点必须在它源结点发射de个时钟周期之后才可以发射

22 10.3 基 本 块 调 度 操作是全流水 的,只需显示 灰色表 在第1行使用 示1 的资源 白色表 示0 数据依赖图 资源预留表
10.3 基 本 块 调 度 数据依赖图 资源预留表 alu men LD R2, 0(R1) ST 4(R1), R2 LD R3, 8(R1) ADD R3, R3, R2 ADD R3, R3, R4 ST 0(R7), R7 ST 12(R1), R3 2 1 i1 i2 i3 i4 i5 i6 i7 操作是全流水 的,只需显示 在第1行使用 的资源 灰色表 示1 白色表 示0

23 10.3 基 本 块 调 度 10.3.2 基本块的表调度 关键路径包括最后5个结点,故第3条指令先调度
10.3 基 本 块 调 度 基本块的表调度 关键路径包括最后5个结点,故第3条指令先调度 再调度第1条指令,因为第4条指令还需等1周期 第4周期调度2条 资源预留表 alu men 调度表 LD R3, 8(R1) ADD R3, R3, R2 ADD R3, R3, R4 ST 0(R7), R7 ST 12(R1), R3 ST 4(R1), R2 LD R2, 0(R1)

24 10.3 基 本 块 调 度 基本块的表调度 根据每个结点同先前已经被调度的各结点之间的数据相关约束,来计算一个结点可以执行的最早时间槽 这个结点所需资源根据一张资源预留表来进行检查,该资源预留表收集了所有到目前为止被占用资源。这个结点的调度按有足够资源的最早时间槽来安排

25 10.4 全局代码调度 对于有适度指令级并行的机器,仅对每个基本块进行紧凑调度会引起许多资源空闲
10.4 全局代码调度 对于有适度指令级并行的机器,仅对每个基本块进行紧凑调度会引起许多资源空闲 全局调度:为了更好地利用机器资源,需要考虑把指令从一个基本块移到另一个基本块的代码生成策略 必须保证 原来程序中所有指令在优化程序中都被执行 当优化程序可以投机地执行额外指令时,这些指令肯定不能有任何多余的副作用

26 10.4 全局代码调度 10.4.1 简单的代码移动 先用例子展示操作在基本块之间移动涉及的问题 (a) 源代码 (b) 局部调度的机器代码
10.4 全局代码调度 简单的代码移动 先用例子展示操作在基本块之间移动涉及的问题 (b) 局部调度的机器代码 LD R6, 0(R1) NOP BEQZ R6, L LD R7, 0(R2) ST 0(R3), R7 LD R8, 0(R4) ADD R8, R8, R8 ST 0(R5), R8 B2 B1 B3 L: L: if (a == 0) goto L c = b e = d + d (a) 源代码

27 10.4 全局代码调度 假定a, b, c, d和e的地址不同,分别保存在R1到R5 由于数据相关,块内的指令必须串行执行,且插入 NOP
10.4 全局代码调度 假定a, b, c, d和e的地址不同,分别保存在R1到R5 由于数据相关,块内的指令必须串行执行,且插入 NOP (b) 局部调度的机器代码 LD R6, 0(R1) NOP BEQZ R6, L LD R7, 0(R2) ST 0(R3), R7 LD R8, 0(R4) ADD R8, R8, R8 ST 0(R5), R8 B2 B1 B3 L: L: if (a == 0) goto L c = b e = d + d (a) 源代码

28 10.4 全局代码调度 假定机器在一个时钟周期执行任意的两个操作 读取操作有2周期的延迟,其他指令1周期的延迟 (a) 源代码
10.4 全局代码调度 假定机器在一个时钟周期执行任意的两个操作 读取操作有2周期的延迟,其他指令1周期的延迟 (b) 局部调度的机器代码 LD R6, 0(R1) NOP BEQZ R6, L LD R7, 0(R2) ST 0(R3), R7 LD R8, 0(R4) ADD R8, R8, R8 ST 0(R5), R8 B2 B1 B3 L: L: if (a == 0) goto L c = b e = d + d (a) 源代码

29 10.4 全局代码调度 B3肯定要执行,因而可以和B1并行执行 B2的读取操作在执行B1时投机地完成 B2的存储操作放到B3的 一份拷贝中
10.4 全局代码调度 B3肯定要执行,因而可以和B1并行执行 B2的读取操作在执行B1时投机地完成 B2的存储操作放到B3的 一份拷贝中 (b) 局部调度的机器代码 LD R6, 0(R1) NOP BEQZ R6, L LD R7, 0(R2) ST 0(R3), R7 LD R8, 0(R4) ADD R8, R8, R8 ST 0(R5), R8 B2 B1 B3 L: L: if (a == 0) goto L c = b e = d + d (a) 源代码

30 10.4 全局代码调度 全局调度前后的流图 (a) 源代码 (b) 局部调度的机器代码 (c) 全局调度的机器代码 L:
10.4 全局代码调度 L: 全局调度前后的流图 if (a == 0) goto L c = b e = d + d (a) 源代码 ST 0(R5), R8 (b) 局部调度的机器代码 LD R6, 0(R1), LD R8, 0(R4) LD R7, 0(R2) ADD R8, R8, R8, BEQZ R6, L ST 0(R5), R8, ST 0(R3), R7 (c) 全局调度的机器代码 B1 B3 B3 LD R6, 0(R1) NOP BEQZ R6, L ST 0(R3), R7 LD R8, 0(R4) ADD R8, R8, R8 B2

31 10.4 全局代码调度 基本块之间的支配关系 指令在基本块之间的移动因支配关系不同而不同 B1和B3控制等价:B1支配B3, B3后支配B1
10.4 全局代码调度 基本块之间的支配关系 指令在基本块之间的移动因支配关系不同而不同 B1和B3控制等价:B1支配B3, B3后支配B1 B1支配B2, 但是B2并非后支配B1 B2不支配B3, 但是B3后支配B2 LD R6, 0(R1) NOP BEQZ R6, L LD R7, 0(R2) ST 0(R3), R7 LD R8, 0(R4) ADD R8, R8, R8 ST 0(R5), R8 B2 B1 B3 L:

32 10.4 全局代码调度 10.4.2 向上的代码移动 从块src向上移动到块dst,假定移动未违反数据相
10.4 全局代码调度 向上的代码移动 从块src向上移动到块dst,假定移动未违反数据相 关,并使得通过dst到src的路径运行得较快 若dst和src等价,则被移动操作应该被执行时,它正好仅被执行一次 dst src

33 10.4 全局代码调度 10.4.2 向上的代码移动 从块src向上移动到块dst,假定移动未违反数据相
10.4 全局代码调度 向上的代码移动 从块src向上移动到块dst,假定移动未违反数据相 关,并使得通过dst到src的路径运行得较快 若dst和src等价,则被移动操作应该被执行时,它正好仅被执行一次 若src未后支配dst,被移动操作可利用空闲资源免费执行,在控制流到达src时获益 dst src

34 10.4 全局代码调度 10.4.2 向上的代码移动 从块src向上移动到块dst,假定移动未违反数据相
10.4 全局代码调度 向上的代码移动 从块src向上移动到块dst,假定移动未违反数据相 关,并使得通过dst到src的路径运行得较快 若dst和src等价,则被移动操作应该被执行时,它正好仅被执行一次 若src未后支配dst,被移动操作可利用空闲资源免费执行,在控制流到达src时获益 若dst不支配src, 需要插入被移动操作的拷贝 dst src

35 10.4 全局代码调度 10.4.3 向下的代码移动 从块src向下移动到块dst,假定移动未违反数据相
10.4 全局代码调度 向下的代码移动 从块src向下移动到块dst,假定移动未违反数据相 关,并使得通过dst到src的路径运行得较快 若dst和src等价,则被移动操作应该被执行时,它正好仅被执行一次 src dst

36 10.4 全局代码调度 10.4.3 向下的代码移动 从块src向下移动到块dst,假定移动未违反数据相
10.4 全局代码调度 向下的代码移动 从块src向下移动到块dst,假定移动未违反数据相 关,并使得通过dst到src的路径运行得较快 若dst和src等价,则被移动操作应该被执行时,它正好仅被执行一次 src未后支配dst, 向下移动的代码经常是存储操作, 复制从src到dst路径上的各块,并把 被移动操作仅放置在dst的新拷贝中 src dst

37 10.4 全局代码调度 9.5节的例子可作为参考 B1 B2 B3 B4 t = b + c a = t B4 B5 d = t
10.4 全局代码调度 9.5节的例子可作为参考 B1 B2 B3 B4 t = b + c a = t B4 B5 d = t d = b + c B6 B6 B7 B1 B2 B3 B4 a = b + c B5 B6 B7 d = b + c

38 10.4 全局代码调度 10.4.3 向下的代码移动 从块src向下移动到块dst,假定移动未违反数据相
10.4 全局代码调度 向下的代码移动 从块src向下移动到块dst,假定移动未违反数据相 关,并使得通过dst到src的路径运行得较快 若dst和src等价,则被移动操作应该被执行时,它正好仅被执行一次 src未后支配dst, 向下移动的代码经常是存储操作, 复制从src到dst路径上的各块,并把 被移动操作仅放置在dst的新拷贝中 dst没有后支配src,插入补偿代码以 保证被移动操作在不经dst路径上也执行 src dst

39 10.4 全局代码调度 10.4.4 更新数据相关 代码移动会改变操作之间的数据相关关系
10.4 全局代码调度 更新数据相关 代码移动会改变操作之间的数据相关关系 两个对x的赋值之一可以移动到最上面的基本块,该变换能维持原来程序中的所有相关性 一旦一个对x的赋值被上移,另一个就不能移动了 移动使得x在最上面块的出口 由不活跃变成活跃 一个变量在某个程序点 活跃,则就不能把对它的投机 定值移到该点的上面 x = 1 x = 2

40 10.4 全局代码调度 10.4.5 全局调度的其他问题 程序调度应该使经常执行的路径运行得快一些, 不经常执行的路径可能会因调度变得慢一些
10.4 全局代码调度 全局调度的其他问题 程序调度应该使经常执行的路径运行得快一些, 不经常执行的路径可能会因调度变得慢一些 编译器可用来估计执行频率的技术有若干种 (1) 内循环比外循环执行得更频繁 (2) 分支指令往回跳转比不跳转要更经常 (3)看守程序出口或异常处理例程的分支语句很少被执行 最好的频率估计来自动态剖析,程序被静态插桩以用来运行时记录条件分支每次的走向

41 10.4 全局代码调度 10.4.5 全局调度的其他问题  最简单的全局调度算法也相当复杂,不介绍
10.4 全局代码调度 全局调度的其他问题  最简单的全局调度算法也相当复杂,不介绍  在一些全局调度算法中,循环迭代的边界是代码移动的一种屏障,需循环展开 for(i = 0; i < N; i ++) { for ( i = 0; i + 4 < N; i += 4) { S(i); S(i); S(i +1); } S(i +2); S(i +3); } for ( ; i < N; i ++) { S(i);

42 10.4 全局代码调度 10.4.6 静态调度器和动态调度器的相互影响 动态调度器的优点是可以根据运行时的情况建立新
10.4 全局代码调度 静态调度器和动态调度器的相互影响 动态调度器的优点是可以根据运行时的情况建立新 的调度表,无需事先编码所有可能的调度表

43 10.4 全局代码调度 10.4.6 静态调度器和动态调度器的相互影响 存在动态调度情况下,静态调度器的作用
10.4 全局代码调度 静态调度器和动态调度器的相互影响 存在动态调度情况下,静态调度器的作用 保证尽早地取高延迟的指令,使得动态调度器能够尽早发射它们 尽早安排预取指令,使数据到要用时已经在缓存, 或尽早安排可能不命中缓存的操作 只需要给数据相关的操作安排正确的次序,无需通过极小化延迟来分离每一对数据相关的操作 给分支预测指令较高优先级,以减少预测错误的代价

44 10.5 软 件 流 水 10.5.1 引言 软件流水是一种调度算法,它每次调度一个 完整的循环,以充分利用穿越迭代的并行性
10.5 软 件 流 水 引言 软件流水是一种调度算法,它每次调度一个 完整的循环,以充分利用穿越迭代的并行性 单次迭代的操作中几乎没有什么并行性 软件流水技术不断地重叠一些相继迭代,直到所有迭代都填入流水线为止 能产生高效和紧凑的代码 以一周期内可以同时发射一个读取、一个存储、 一个算术运算(全流水)和一个分支操作的机器 来举例

45 10.5 软 件 流 水 每次调度一个迭代的结果见右边 for (i = 0; i < n; i ++) // R1, R2, R3 = &A, &B, &D D[i] = A[i]  B[i] + c; // R4 = c // R10 = n 1 L: LD R5, 0(R1++) LD R6, 0(R2++) MUL R7, R5, R6 NOP ADD R8, R7, R4 ST 0(R3++),R8, BL R10, L 该计算大部分是 串行的,它需要 7周期,只有循 环回跳指令和迭 代中最后一条指 令重叠

46 10.5 软 件 流 水 循环展开4次迭代的调度结果见右边 忽略了寄存器 分配的细节 展开后每次迭 代的执行用13 周期,或者说
10.5 软 件 流 水 循环展开4次迭代的调度结果见右边 for (i = 0; i < n; i ++) L: LD D[i] = A[i]  B[i] + c; LD LD MUL LD ADD LD ST MUL LD ST MUL ADD ST ST BL(L) 忽略了寄存器 分配的细节 展开后每次迭 代的执行用13 周期,或者说 原来的每次迭 代仅需要3.25 周期

47 10.5 软 件 流 水 10.5.2 循环的 软件流水  右边是展开5 次的迭代 不考虑寄存器  调度满足所有 分配 的资源和数据
10.5 软 件 流 水 循环的 软件流水  右边是展开5 次的迭代  调度满足所有 的资源和数据 相关约束  第7和8周期执 行的操作同第9 和10周期执行 的是一样的 周期 j = 1 j = 2 j = 3 j = 4 j = 5 (1) LD (2) LD (3) MUL LD (4) LD (5) MUL LD (6) ADD LD (7) MUL LD (8) ST ADD LD (9) MUL LD (10) ST ADD LD (11) MUL (12) ST ADD (13) (14) ST ADD (15) (16) ST 不考虑寄存器 分配

48 10.5 软 件 流 水 10.5.2 循环的 软件流水  每行对应到一  第7和第8两行  右边是经软件 流水化的代码 条机器指令
10.5 软 件 流 水 循环的 软件流水  右边是经软件 流水化的代码  每行对应到一 条机器指令  第7和第8两行 构成一个2时钟 的循环,重复 执行n 3次 (1) LD (2) LD (3) MUL LD (4) LD (5) MUL LD (6) ADD LD (7) L: MUL LD (8) ST ADD LD BL(L) (9) MUL (10) ST ADD (11) (12) ST ADD (13) (14) ST 不考虑寄存器 分配

49 10.5 软 件 流 水 10.5.2 循环的 软件流水  当一个老的迭  当所有迭代都  右边是经软件 流水化的代码 代在该流水线
10.5 软 件 流 水 循环的 软件流水  右边是经软件 流水化的代码  当一个老的迭 代在该流水线 上撤出,一个 新的迭代填入  当所有迭代都 填完,该流水 线排空 (1) LD (2) LD (3) MUL LD (4) LD (5) MUL LD (6) ADD LD (7) L: MUL LD (8) ST ADD LD BL(L) (9) MUL (10) ST ADD (11) (12) ST ADD (13) (14) ST 不考虑寄存器 分配

50 10.5 软 件 流 水 10.5.2 循环的 软件流水  第1到6行的指  第7和8行叫做 第9到14行指  右边是经软件
10.5 软 件 流 水 循环的 软件流水  右边是经软件 流水化的代码  第1到6行的指 令序列叫序曲  第7和8行叫做 稳定状态 第9到14行指 令序列叫做 尾声 (1) LD (2) LD (3) MUL LD (4) LD (5) MUL LD (6) ADD LD (7) L: MUL LD (8) ST ADD LD BL(L) (9) MUL (10) ST ADD (11) (12) ST ADD (13) (14) ST 不考虑寄存器 分配

51 10.5 软 件 流 水 10.5.3 寄存器 分配和代码生 成  第2次迭代结  结果必须保存  第1次迭代乘 运算的结果在
10.5 软 件 流 水 寄存器 分配和代码生  第1次迭代乘 运算的结果在 第3周期产生, 在第6周期使用  第2次迭代结 果在第5周期产 生,第8周期用  结果必须保存 在不同寄存器 周期 j = 1 j = 2 j = 3 j = 4 j = 5 (1) LD (2) LD (3) MUL LD (4) LD (5) MUL LD (6) ADD LD (7) MUL LD (8) ST ADD LD (9) MUL LD (10) ST ADD LD (11) MUL (12) ST ADD (13) (14) ST ADD (15) (16) ST

52 10.5 软 件 流 水 10.5.3 寄存器分配和代码生成 奇数次迭代和偶数次迭代的代码不完全一样,所
10.5 软 件 流 水 寄存器分配和代码生成 奇数次迭代和偶数次迭代的代码不完全一样,所 以进入稳定状态后的循环由2周期加倍成4周期 用源代码解释,相当于下面的循环 if (N >= 5) N2 =  ((N  1) / 2); else N2 = 0; for (i = 0; i < N2; i ++) // 该循环被流水化 D[i] = A[i]  B[i] + c; for (i = N2; i < N; i ++) // 不需要优化

53 10.5 软 件 流 水 Do-Across循环 软件流水也可以用到迭代之间存在数据相关的循环,这样的循环叫做do-across循环 for (i = 0; i < n; i ++) { sum = sum + A[i]; B[i] = A[i]  b; } 该循环的执行不可能快于每2周期1次迭代 即使有更多的加法器或乘法器,也不可能更快 吞吐能力受到穿越迭代的数据相关链的限制

54 10.5 软 件 流 水 10.5.5 软件流水的目标和约束 目标 达到目标的体现 实现策略 基本目标是极大化耗时较长的循环的吞吐能力
10.5 软 件 流 水 软件流水的目标和约束 目标 基本目标是极大化耗时较长的循环的吞吐能力 次要目标是保持所产生代码的规模较小 达到目标的体现 软件流水化的循环应该有较小的流水线稳定状态 实现策略 让每次迭代的相对调度都相同,并且这些迭代以同样的时间间隔逐步启动

55 10.5 软 件 流 水 软件流水的目标和约束 资源约束 令机器资源由R = [r1, r2, ...]表示,其中ri是第i类资源可用部件数 若循环的一次迭代需要第i类资源ni个部件 流水化循环的平均启动间隔至少是maxi(ni/ri)周期 如果maxi(ni/ri)小于1,则将源代码展开几次是有用的

56 10.5 软 件 流 水 软件流水的目标和约束 数据相关 一个操作可能依赖于前一次迭代中同样操作的结果,不同于到目前为止碰到的数据相关 仅用延迟来标记边不够用,需要区别不同迭代中同一操作的实例,例如: for (i = 2; i < n; i ++) A[i] = B[i] + A[i 2] 写A[i]和读A[i 2]的依赖边上标记的迭代次数差是2

57 10.6 并行性和数据局部性优化概述 并行编程模型 本节内容围绕任务并行和数据并行 任务并行 数据并行 数据流并行(前面几节涉及较多)
10.6 并行性和数据局部性优化概述 并行编程模型 任务并行 数据并行 数据流并行(前面几节涉及较多) 本节内容围绕任务并行和数据并行 介绍并行计算机系统结构的概况 给出并行化的基本概念,程序循环的变换,还有对并行化有用的概念 类似的考虑怎样用于优化数据局部性 以矩阵乘算法的优化为例

58 10.6 并行性和数据局部性优化概述 10.6.1 多处理器 对称多处理器的体系结构 多个高性 能处理器 集成在一 块芯片上 处理器 一级
10.6 并行性和数据局部性优化概述 多处理器 对称多处理器的体系结构 二级 缓存 内存 总线 一级 处理器 多个高性 能处理器 集成在一 块芯片上

59 10.6 并行性和数据局部性优化概述 10.6.1 多处理器 对称多处理器的体系结构 必须在处理器的缓存中 找到它操作的大部分数
10.6 并行性和数据局部性优化概述 必须在处理器的缓存中 找到它操作的大部分数 据,以保证性能 多处理器 对称多处理器的体系结构 二级 缓存 内存 总线 一级 处理器 多个高性 能处理器 集成在一 块芯片上 通过共 享内存来 进行通信

60 10.6 并行性和数据局部性优化概述 10.6.1 多处理器 分布式内存机器 在内存分 层中又引 入一层 处理器能 迅速访问 自己的局
10.6 并行性和数据局部性优化概述 多处理器 分布式内存机器 总线或其它互连 二级 缓存 一级 处理器 局部 内存 在内存分 层中又引 入一层 处理器能 迅速访问 自己的局 部内存

61 10.6 并行性和数据局部性优化概述 10.6.1 多处理器 分布式内存机器 非均匀内存访问的机器和消息传 递的机器;为获得良好的性能
10.6 并行性和数据局部性优化概述 非均匀内存访问的机器和消息传 递的机器;为获得良好的性能 软件都必须有很好局部性 多处理器 分布式内存机器 总线或其它互连 二级 缓存 一级 处理器 局部 内存 在内存分 层中又引 入一层 处理器能 迅速访问 自己的局 部内存

62 10.6 并行性和数据局部性优化概述 10.6.2 应用中的并行性 并行应用性能衡量的两种标准 并行覆盖:整个计算中并行运行部分的百分比
10.6 并行性和数据局部性优化概述 应用中的并行性 并行应用性能衡量的两种标准 并行覆盖:整个计算中并行运行部分的百分比 并行粒度:处理器上无需和其它处理器同步或通信的计算量 循环对并行化来说特别有吸引力,循环可以有许 多次迭代计算,如果这些计算相互独立,则它们是 并行计算的主要来源 许多控制结构简单、数据量大并且耗时长的科学 和工程应用,很容易以较细粒度被并行化

63 10.6 并行性和数据局部性优化概述 10.6.3 循环级并行 耗时的应用一般都使用大数组,导致程序中出现
10.6 并行性和数据局部性优化概述 循环级并行 耗时的应用一般都使用大数组,导致程序中出现 有许多次迭代的循环,这些迭代经常相互独立,可 以把这类循环的大量迭代分到各处理器上

64 10.6 并行性和数据局部性优化概述 10.6.3 循环级并行 for (i = 0; i < n; i++) {
10.6 并行性和数据局部性优化概述 循环级并行 for (i = 0; i < n; i++) { Z[i] = X[i]  Y[i]; Z[i] = Z[i]  Z[i]; } // 变换成如下代码 b = ceil (n/M); // M个处理器, p = 0, 1, …, M 1 for (i = bp; i < min(n, b(p+1)); i++) { } // 数据并行的例子

65 10.6 并行性和数据局部性优化概述 10.6.3 循环级并行 对并行化来说,任务级不像循环级那样有吸引力
10.6 并行性和数据局部性优化概述 循环级并行 对并行化来说,任务级不像循环级那样有吸引力 对一个程序而言,独立的任务数是一个常数,它不像典型的循环那样,独立的计算单元随迭代次数增加而增加 任务通常不是等规模的,因此很难保证所有的处理器在所有时间都处于忙碌

66 10.6 并行性和数据局部性优化概述 10.6.4 数据局部性 程序局部性 时间局部性 空间局部性
10.6 并行性和数据局部性优化概述 数据局部性 程序局部性 大多数程序的大部分时间在执行一小部分代码,并且仅涉及一小部分数据 时间局部性 程序访问的内存单元在很短的时间内可能再次被程序访问 空间局部性 毗邻被访问单元的内存单元在很短的时间内可能被访问

67 10.6 并行性和数据局部性优化概述 10.6.4 数据局部性 同一个缓存行上的元素一起被使用的情况是空间局部性的一种重要形式
10.6 并行性和数据局部性优化概述 数据局部性 同一个缓存行上的元素一起被使用的情况是空间局部性的一种重要形式 这种空间局部性将缓存未命中降到最低,因此使得程度获得明显的加速

68 10.6 并行性和数据局部性优化概述 数据局部性 for (i = 0; i < n; i++) { // 该程序段对向量机来 Z[i] = X[i]  Y[i]; // 说是一种优化形式 } for (i = 0; i < n; i++) { Z[i] = Z[i]  Z[i]; for (i = 0; i < n; i++) { // 有较好的数据局部性 Z[i] = X[i]  Y[i];

69 10.6 并行性和数据局部性优化概述 10.6.4 数据局部性 对行为主的数组Z,根据空间局部性,显然更愿意逐行地给该数组元素置零
10.6 并行性和数据局部性优化概述 数据局部性 对行为主的数组Z,根据空间局部性,显然更愿意逐行地给该数组元素置零 for (j = 0; j < n; j++) for (i = 0; i < n; i++) for (i = 0; i < n; i++) for (j = 0; j < n; j++) Z[i, j] = 0; Z[i, j] = 0; 为了获得最好的性能,应该并行化外循环 b = ceil (n/M); for (i = bp; i < min(n, b(p+1)); i++) for (j = 0; j < n; j++) Z[i, j] = 0;

70 10.6 并行性和数据局部性优化概述 10.6.4 数据局部性 操作在数组上的数值应用的几个重要特征 数组代码经常有许多可以并行化的循环
10.6 并行性和数据局部性优化概述 数据局部性 操作在数组上的数值应用的几个重要特征 数组代码经常有许多可以并行化的循环 当循环有并行性时,它们的迭代可按任意次序执行,因而可重新安排计算次序以彻底改进数据局部性 在创建相互独立的并行计算大单元时,串行执行这些单元往往会产生较好的数据局部性

71 10.6 并行性和数据局部性优化概述 10.6.5 矩阵乘法算法 该算法是计算密集型的,原则上内存访问不应该构成瓶颈 假定矩阵的布局是行为主
10.6 并行性和数据局部性优化概述 矩阵乘法算法 该算法是计算密集型的,原则上内存访问不应该构成瓶颈 假定矩阵的布局是行为主 假定正好c个数组 元素能够放满一个 缓存行,X的一行仅 散布在n/c个缓存行上 假定缓存足以放下X所 有的缓存行,读入X出 现n2/c次缓存未命中 for (i = 0; i < n; i++) for (j = 0; j < n; j++) { Z[i, j] = 0.0; for (k = 0; k < n; k++) Z[i, j] = Z[i, j] + X[i, k]  Y[k, j]; }

72 10.6 并行性和数据局部性优化概述 10.6.5 矩阵乘法算法 先考虑在单处理器上顺序执行 完成Z一行元 素的计算, 取Y出现的缓
10.6 并行性和数据局部性优化概述 矩阵乘法算法 先考虑在单处理器上顺序执行 完成Z一行元 素的计算, 取Y出现的缓 存未命中次数 在n2/c和n2之间 完成整个Z, Y未命中次数 在n2/c和n3之间 j = … n 1 i = 0 X Y

73 10.6 并行性和数据局部性优化概述 10.6.5 矩阵乘法算法 再考虑在p个处理器上并行计算
10.6 并行性和数据局部性优化概述 矩阵乘法算法 再考虑在p个处理器上并行计算 把Z不同行的计算指派到不同处理器,每个处理器计算Z的连续n/p行 每个处理器访问矩阵X和Z的n/p行以及整个Y,用n3/p次乘加运算来完成对Z的n2/p个元素的计算 虽然计算时间与p成比例减少,但通信代价却与p成比例增加,因为交付给p个处理器之缓存的总缓存行是n2/c + pn2/c p逼近n时,计算时间为O(n2),通信代价为O(n3)

74 10.6 并行性和数据局部性优化概述 10.6.6 矩阵乘法算法的优化 复用在缓存的数据才代表数据局部性好
10.6 并行性和数据局部性优化概述 矩阵乘法算法的优化 复用在缓存的数据才代表数据局部性好 复用应该很快发生,数据才可能还在缓存 在上述算法中,n2个乘加操作隔开了矩阵Y中同一个数据的复用,n个乘加操作隔开了Y中同一个缓存行的复用 分块是重排循环中迭代次序的一种方法,它能够极大地改进程序的局部性

75 10.6 并行性和数据局部性优化概述 10.6.6 矩阵乘法算法的优化
10.6 并行性和数据局部性优化概述 矩阵乘法算法的优化 从第4到7行的程序计算左上角为X[ii, kk]和Y[kk, jj]的两块对左上角为Z[ii, jj]的块的贡献 for (ii = 0; ii < n; ii = ii + b) for (jj = 0; jj < n; jj = jj + b) for (kk = 0; kk < n; kk = kk + b) for (i = ii; i < ii + b; i++) for (j = jj; j < jj + b; j++) for (k = kk; k < kk + b; k++) Z[i, j] = Z[i, j] + X[i, k]  Y[k, j]; b n

76 10.6 并行性和数据局部性优化概述 10.6.6 矩阵乘法算法的优化 适当选择b,使3个矩阵都有一个块可以装到缓存
10.6 并行性和数据局部性优化概述 矩阵乘法算法的优化 适当选择b,使3个矩阵都有一个块可以装到缓存 把X或Y一块取到缓存,会出现b2/c次缓存未命中 对于X和Y的一对块,第4到7行的程序完成b3次乘加计算 由于整个矩阵乘法需要n3次乘加计算,则取一对块到缓存的总次数是n3/b3 对于X和Y的一对块会有2b2/c次缓存未命中,因此缓存未命中的总次数是2n3/bc 和10.6.5节的O(n3/c),甚至O(n3)次缓存未命中相比,在b较大时,2n3/bc能体现出分开方法的好处

77 习 题 第一次:10.1, 10.3 第二次:10.5, 10.6


Download ppt "第十章 依赖于机器的优化 在指令级并行的机器上,程序的运行速度依赖于下面几个因素"

Similar presentations


Ads by Google