目录
并行编程平台
隐式并行
超标量执行/指令流水线
进入流水线之前先消除指令之间的数据相关
这表明,如果重排指令的顺序,可能提升效率
相关性包括
数据相关
资源相关
分支相关
具有乱序执行能力的 CPU 可以重排指令,更好地实现指令流水线,这种模型称为动态指令发送
超长指令字处理器 VLIW
使用编译器来解决数据相关和资源相关
能够并发执行的指令会编入一个组,作为一个超长指令字发送给处理器,并同时在多个处理器上执行
调度由软件来完成
编译器的并行语句选择空间大
编译器可以用复杂的静态预测策略
但是编译器中没有动态程序状态(如分支历史缓冲器)来对调度进行决策,这降低了动态预测的性能
超标量和 VLIW 都只局限在 4 路或者 8 路的并行上
内存性能系统的局限
从主存取一个块存在两个因素影响
-
延迟
-
带宽
因为延迟一般比计算时间大得多,所以性能会被这个延迟拖累
所以提出了 cache
提高带宽,也可能提升性能
然后还有内存布局的影响
避免内存延迟的方法
-
预取
-
多线程
-
一次提出多个访问,使得延迟分摊到各个访问
预取和多线程提高了对带宽的要求
并行计算平台
控制结构
处理器 SIMD
协处理器 SIMD
MIMD
MIMD 的一个变体 Single Program Multiple Data, SPMD
SIMD 有一个缺点是处理不规则数据的效率较慢
比如对于一个 if else,所有处理器都用相同的这个代码处理不同的数据,假设一半的数据能满足 if,另外一半只能满足 else,那么在执行这段代码的时候,在所有处理器处理 if 的时候,有一半的处理器忙碌而另一半空闲,else 也是一样
通信模型
共享地址空间平台
共享地址空间的内存可以是处理器本地的,或者是对所有处理器全局的
一致内存访问 Uniform Memory Access UMA 对所有内存的访问时间相同
非一致内存访问 NUMA
有 cache 的计算机时 NUMA
NUMA 需要考虑本地性、结构化数据
UMA 不需要考虑本地性,编写并行程序的代码看上去像串行代码,但是访问数据存在互斥,还需要锁
cache 的存在提出了缓存一致性的问题
共享地址空间指的是所有处理器支持一个公共的数据空间
共享内存计算机指的是多个处理器共享同一个内存,相对的是,不同处理器只能访问内存的不同区域
消息传递平台
视为由节点构成
每一个节点具有唯一 ID,用于表明身份。ID 通过 whoami 函数来分配
设置 send 和 receive 函数,发送和接收消息
设置 numprocs 函数,设置参与消息传递的进程数
通过这四个函数,可以完成任意的消息传递程序
对比
在共享地址空间平台上很方便模拟消息传递
只要给每个处理器独占地分配一片共享地址空间就行了,通过把数据传送到这个空间来模拟消息传递
但是在消息传递平台上模拟就比较昂贵了,因为访问其他节点的内存需要传递消息
物理组织
理想并行计算机
由串行计算拓展而来
p 个处理器,一个大小不限的全局内存
所有处理器共享该内存,地址空间相同,共享时钟
但是不同处理器在同一个时钟可以执行不同的指令
Parallel Random Access Machine, PRAM
不同处理器可能对内存并发访问,所以根据对于内存的访问方法,可以分为
-
互斥读互斥写(EREW)PRAM
-
并发读互斥写(CREW)
-
互斥读并发写
-
并发读并发写
并发读不会影响语义
但是并发写会影响
几种仲裁方法:
-
共有:如果所有处理器试图写的值都相同,则允许并发写
-
任意:任一处理器先写
-
优先级
-
求和:所有量的总和被写入
基于求和的模型可以拓展到任意的,由待写入量定义的操作符
并行计算机互联网络
静态 动态
路由
网络拓朴结构
基于总线的网络
可以为每个节点准备缓存

交叉开关网络

开关节点数是 p 2 p^2 p2 元件多,数据传输速度不高
可拓展性不高
多级网络
共享总线:成本上可拓展,性能上不可拓展
交叉开关:成本上不可拓展,性能上可拓展
多级网络:折中

网络级数为 log p \log p logp
单独把每一级网络拿出来,p 个输入对应 p 个输出
一种对应模式称为完全混洗,输入序号 i 输出序号 j,则完全混洗的函数为


每一级网络含有若干个开关节点,每一个开关节点处理两个输入输出
开关有两种

那么每一级网络有 p / 2 p/2 p/2 个开关节点,所有网络总共有 p / 2 log p p/2 \log p p/2logp 个节点,这远远小于交叉开关网络
考虑开关的话,多级网络可以表示为

假设输入的二进制表示是 s
每一级网络的输出的端口的二进制表示是 t
选择开关直通或者跨接的方式是判断 s 和 t 的最高位是否相同
相同则直通,不同则跨接
这种方式不是完美的,可能遇到阻塞

全连接

一定不会阻塞
星形

线性阵列、格网和 k-d 格网
全连接是密集的
线性阵列和格网是稀疏的

格网的拓扑结构适合物理仿真

k-d 格网指的是 d 维,每一维上有 k 个节点
线性阵列是 k-d 格网的一个极端
超立方体是 k-d 格网的另一个极端

超立方体的编号方式有一个特性,就是两个二进制编号之间不同的位数表示了它们之间相隔多少个链路
使用超立方体结构时,这个特性可以导出许多并行算法
基于树的
任意一对节点之间只存在一条通路

传送消息的时候,从下到上先传送到根节点,再传到目标
所以根节点会频繁传送消息,所以可以给上层加粗链路,称为胖树

静态互连网络评价
距离:两节点之间的最短路径
直径:网络中任意两节点之间的距离的最大值
连通性:从一个连通网络中获得两个互不连通的网络所要删除掉的最少弧数量,称为弧连通性
对分宽度:分为两个相等网络所要删除掉的最少链路数量
通道宽度:越过两个节点之间进行通信的位数 = 每个通信链路中物理线路的数目
通道速度:单一物理线路能够传送的峰值速度
通道带宽:两个通信节点之间传送的峰值速度 = 通道速度 * 通道宽度
对分带宽:对分网络任何两半之间允许的最小通信量 = 对分宽度 * 通道宽度
(截面带宽)
成本:用通信链路数量或者对分带宽来评价
动态互连网络
信息经过开关的时候存在开销
那么把开关视为节点
距离、直径的定义相同
连通性:弧连通性和节点连通性
节点连通性这里只考虑开关
考虑对分宽度的时候,只需要保证对分网络中的处理节点的数目相等,而不需要包括开关节点
在所有划分对分网络的方法中,要选择划分穿过的边数最少
成本:=链路成本=开关成本
多处理器中的缓存一致性
多处理器中的缓存一致性比单处理器中的缓存一致性更复杂
因为可能有多个处理器修改副本
修改多个副本的过程必须是串行的
要不就同时修改所有副本,要不就单独修改某一个副本,使得别的副本失效
这称为更新(update)协议和无效(invalid)协议

同一时间只能选用一个协议
一种情况:假共享
假共享指的是不同处理器更新相同缓存行中的不同部分的情况
如果使用无效协议,那么处理器 A 在更新自己的变量的时候,因为 A、B、C 关注同一行的不同位置,所以这会使得别的处理器 B、C 的缓冲中的这一行无效。等到 B、C 想要获取自己的缓存中的这一行的时候,还要去 A 中取。
书中说的”虽然没有对共享变量进行更新,但是系统并不进行检测“应该说的是,假设讨论的处理器有 A、B、C,那么 A 对自己的共享变量进行更新的时候,A 更新的并不是 B、C 的共享变量,所以无法设计一个程序来检测假共享?总之这话听起来挺怪的
假共享导致数据在各个处理器之间像乒乓球一样传来传去
用无效协议维护数据一致性
常用无效协议,之后的讨论都默认使用无效协议
使用无效协议时的三个状态:共享 S、无效 I、脏 D


还可以使用硬件机制来实现一致性
硬件机制包括
-
侦听系统
-
基于目录的系统
-
以上两者的结合
缓存侦听系统
侦听与广播互连网络有关
所有处理器都侦听总线

多个处理器同时读相同的数据会有一致性问题
共享带宽会限制同一时间一致性操作的个数
向所有处理器广播某个处理器的所有内存操作不是一个可拓展的方案
一个解决方法是只将一致性操作传播给那些必须参与操作的处理器
要知道哪些处理器包含这个数据的副本,还有这些数据的状态信息
这些信息存储在一个目录中
基于信息的一致性系统称为基于目录的系统
这句话说的并不是说直接把目录结合到侦听系统,而是接着要介绍一个完全基于目录的
看的时候听着他这么说我还以为是马上要介绍拓展了呢
基于目录的系统

多个处理器同时写入一个数据的时候,产生一致性操作
一致性操作有两种开销
-
传播状态更新
这是通信开销
-
从目录产生状态信息
这会产生资源争用
目录在内存中,单位时间只能进行有限次的读写,所以目录会限制单位时间一致性操作的个数
还有另外一个瓶颈是目录的大小
假设内存块的大小为 m,p 是处理器的数目,那么目录的大小就是 mp
解决方法之一是增大内存块的大小,这样,在内存空间不变的情况下,m 会减小
但是在遇到假共享的时候,开销更大
分布式目录方案
因为目录是争用中心,所以很自然的想到拆分目录
其实拆分目录的本质上就是拆分内存,因为一个目录必须管理一个完整的内存,一个目录不会对应多个内存,也不会有多个目录对应同一个内存,这是一对一的
所以如果存在多个目录的话,那你就是在拆分内存
允许 O ( p ) O(p) O(p) 个同时的一致性操作
更加具有可拓展性
请求块的信息和无效信息通过网络传播,网络延迟和带宽成为主要瓶颈
并行计算机的通信成本
与编程模型语义、网络拓朴结构、数据处理、路由选择以及相关的软件协议有关
消息传递成本
启动时间 t s t_s ts
每站时间 t h t_h th
每字传送时间 t w t_w tw
存储转发路由选择
每个站都要先把消息存储完整之后再开始转发
总时间: t c o m m = t s + ( m t w + t h ) l t_{comm} = t_s + (mt_w + t_h)l tcomm=ts+(mtw+th)l

现在 t h t_h th 一般很小,可以忽略不计,那么总时间计算为 t c o m m = t s + m t w l t_{comm} = t_s + m t_w l tcomm=ts+mtwl
包路由选择
把消息分成包,接收到消息的一半的时候,路由就可以开始转发

也可以分为四份

假设包的大小是 r + s r+s r+s, r r r 是原始消息, s s s 是附加信息
将消息分成包的时间应该与消息的长度成正比,所以可以设为 m t w 1 m t_{w1} mtw1
那么设每字传送时间的记法改为 t w 2 t_{w2} tw2
第一个包送达的时间是 t s + t h l + t w 2 ( r + s ) t_s + t_h l + t_{w2} (r+s) ts+thl+tw2(r+s)
每个包到达的时间间隔是 t w 2 ( r + s ) t_{w2} (r+s) tw2(r+s)
总共有 m / r m/r m/r 个包,第一个到达之后,后续还有 m / r − 1 m/r-1 m/r−1 个包
那么总时间是 t s + t h l + t w 2 ( r + s ) m / r + m t w 1 t_s + t_h l + t_{w2} (r+s) m/r + m t_{w1} ts+thl+tw2(r+s)m/r+mtw1
令 t w = t w 1 + t w 2 ( 1 + 1 / r ) t_w = t_{w_1} + t_{w2}(1+1/r) tw=tw1+tw2(1+1/r)
总时间为 t s + t h l + t w m t_s + t_h l + t_w m ts+thl+twm
现在 m m m 和 l l l 之间分开了,不是相乘了
一开始还不知道这个包和计网中的数据包有什么区别
看完这个时间的计算之后我懂了,计网中的包指的是对于全部的信息来说,把长长的信息分段了
但是分段之后的信息,对于路由怎么传送呢?没有要求
而这里说的包,只是对于路由而言的,对于路由,传送不再是接受完所有信息才能传了,接受了一部分也可以开始传了
直通路由选择
强制所有包选择同样的路劲,可以减少路由选择开销
强制顺序传送,可以减少排序开销
将错误信息与消息层联系而不是与包层相联系,可以减少错误检测与校正的开销(由上层负责检错?)
并行计算网络中的错误率低,可以用便宜的错误检测替代错误校正
这些优化之后的方案,称为直通路由选择
中间节点直接转发,什么都不用存<

最低0.47元/天 解锁文章
1720

被折叠的 条评论
为什么被折叠?



