并行多核体系结构基础知识

分类

根据Flynn分类法

Flynn分类法根据指令流和数据流的数量定义了并行计算机的分类。

数据流数量
指令流数量 SISD SIMD
MISD MIMD

SISD:单指令流单数据流。上古架构。

SIMD:单指令流多数据流。一般在GPU中,如Intel MMX/SSEAMD 3DNow!等。

MISD:多指令流单数据流。很难应用,如iWarp

MIMD:多指令流多数据流。

MIMD计算机分类

根据处理器数量,将共享式存储器的处理器分为两类:SMP/UMADSM/NUMA

SMP/UMA:共享存储器多处理器,或集中式共享存储器多处理器或一致性存储器访问多处理器(一般核心数量不超过8个)。共享缓存和主存储器。

DSM/NUMA:多处理器采用物理分布式存储器,称为分布式共享存储器,也称为非一致性存储器访问。

并行编程

从根本上来讲,以并行方式执行算法或代码的期望是获得比串行算法或代码更短的执行时间,一种分析并行程序执行时间的有用工具是Amdahl定律

并行编程模型

共享存储和消息传递模型。

共享存储模型:不同线程或进行执行的并行任务能够访问内存的任何位置,它们可以通过写入和读取内存位置实现相互间的隐式通信(类似于同属一个进程的多个线程间共享地址空间)

消息传递模型:线程拥有各自的本地内存,一个线程不能访问另一个线程的内存。当线程间为了交换数据,就需要通过显式的传递包含数据值的消息彼此通信(类似于 多个进程互不共享地址空间)

模型对比

共享存储模型 消息传递模型
通信 隐式 显式消息
同步 显式 隐式消息
硬件支持 通常需要 不需要
编程工作量 较低 较高
调优工作量 较高 较低
通信粒度 较细 较粗

共享存储器一般需要专门的硬件支持,在类似多核处理器上,处理器核间可能已经共享最后一级高速缓存。然而,在多节点情况下。每个节点拥有自己的处理器和内存,节点间互连形成一个共享存储系统,这时需要硬件支持来实现一种映像,即所有节点的内存构成一个可被所有处理器寻址的单一处理器。
当处理器个数很多时,以较低代价实现共享存储抽象将变得很困难。

其他编程模型:

  • 分区化全局地址空间PGAS:允许所有线程透明的共享单一地址空间
  • 数据并行编程模型:类似于SIMD
  • MapReduce:集群
  • 事务内存TM:将一段代码定义为一个事务

共享存储并行模型

OpenMP为例,它是支持共享存储编程的应用编程接口,由一组编译器指令组成,程序员可以使用指令来向支持OpenMP的编译器表达并行。编译器将指令替换为调用库函数的代码或读取影响程序运行时行为的环境变量。

OpenMP官网OpenMP官网链接

设计OpenMP的最初目的是在循环结构中表达DOALL并行,使用fork-join执行模型,其中在串行部分由一个线程(主线程)执行计算机。当遇到并行段时,主线程产生子线程来一起执行,直到并行段结束,子线程合并回主线程。

一般使用

#pragma omp directive-name [clause[[,] clause] ... ] new-line
// when for is the directive-name, what clause? 
// private(variable-list)
// firstprivate(variable-list) 
// lastprivate(variable-list)
// reduction(operator: variable-list)
// ordered
// schedule(kind[, chunk_size])
// nowait

要表示一个并行段#pragma omp parallel

#pragma omp parallel 
{
    
     // begin
	// parallel content
} // end

针对LDS的并行编程

可以使用TM事务内存,在某种程度上可以简化LDS并行编程,使用TM的方法是将每一个LDS操作封装在一个事务中,如

atomic{
    
    Insert(...)}  // insert a factor

atomic{
    
    Delete(...)}  // delete a factor

存储层次结构

存储结构产生的原因:均衡处理器速度和主存的速度

缓存一致性和同步原语

要保证并行程序正确高效的运行,共享存储多处理器系统必须提供对缓存一致性、存储一致性和同步原语的硬件支持。

缓存一致性基础

如图

基于总线的多处理器缓存一致性问题

写直达缓存的一致性协议的缺点:对缓存块的写入会存在时间和空间的局部性。写直达每次写触发总线写从而占用总线带宽,在写回缓存机制下,如果同一缓存块中的一个或多个字或字节被多次写入,只需占用一次总线带宽来失效其他缓存拷贝即可,带宽会很快被耗尽。


写回缓存的MSI协议:与写直达缓存相比,使用写回缓存会大幅降低带宽开销(写回缓存有一个状态:脏,用来标记缓存块中的任意位置在被加载以来是否发生改变)

每一个缓存块都有相关的状态:

  • Modified(M):缓存块有效,并且其数据与主存中的原始数据(可能)不同。
  • Shared(S):缓存块是有效的且有可能被其他处理器共享。它也是干净的,即缓存值与主存中的值相同。该状态与“写直达”缓存一致性协议中的V状态相似。
  • Invalid(I):缓存块无效

缺点:不管一个块是否仅存储在一个缓存块上,MSI协议在读写次序请求时都会触发两个总线事务。这个缺陷会影响诸如顺序执行程序等几乎没有数据共享的程序在执行时的性能。


写回缓存的MESI协议:为了解决MSI的问题,MSEI协议加入了一个状态来区分一个缓存块是干净且唯一的,还是干净但是在多个缓存上拥有拷贝的。

每一个缓存块都有相关的状态:

  • Modified(M)
  • Exclusive(E):缓存块是干净有效且唯一的
  • Shared(S)
  • Invalid(I)

可以通过脏共享来减少主存带宽


写回缓存的MOESI协议:该协议一般允许脏共享,MESI一般用于英特尔至强处理器,MOESI一般用于AMD处理器。

每一个缓存块都有相关的状态:

  • Modified(M)
  • Exclusive(E)
  • Owned(O):缓存块是有效的,可能是脏的,也可能有多份拷贝。但是,当存在多份拷贝时,只能有一个是O状态,其他拷贝都为S状态
  • Shared(S)
  • Invalid(I)

写回缓存基于更新的协议

对同步的硬件支持


锁的实现类型:

  • TS
  • TTSL
  • LL/SC
  • Ticket
  • ABQL
标准 test&set TTSL LL/SC Ticket ABQL
无竞争延迟 最低 较低 较低 较高 较高
单个锁释放操作的最大通信量 O(1)
等待通信量
存储 O(1) O(1) O(1) O(1)
保证公平性?

栅障

栅障的实现类型:

  • 翻转感应集中式栅障
  • 组合树栅障
  • 硬件栅障实现

事务内存

存储一致性模型和缓存一致性解决方案

存储一致性模型

与缓存一致性协议分开,缓存一致性协议仅能解决对单个存储器块地址的访问之间如何排序的问题,而对于不同地址的访问并不是缓存一致性协议所要参考的问题。

高级缓存一致性设计

目录式一致性协议Snooping

作为缓存一致性的最早的主流实现方式,依赖于两个事实:

  • 其一,总线作为广播介质,能够把请求变为全局可见,即所有缓存都能同时看到总线上出现了哪个请求
  • 其二,所有的一级缓存和二级缓存都同时密切地监视(嗅探)总线上出现的请求,各自独立并且正确地改变对应缓存行的状态

当处理器个数的增加,可用的互连网络带宽会很快被广播流量占满

监听式一致性协议Directory

是缓存一致性的另一种常用的实现方式,依赖于二级缓存来记录缓存行在一级缓存中的分享情况。

在以目录方式实现的一致性协议中,任何缓存一致性请求都需要先造访二级缓存中的目录。目录的好处是以点对点的数据传输,取代了嗅探中的全局广播:这一性质在系统的计算核心数量较多时尤为重要.

互连网络体系结构

分布式操作系统

SIMT体系结构

单指令流多线程SMIT Single-Instruction Multiple-Thread体系结构,一般用在图形处理器GPU中,类似于SIMD

SMIDSMIT的区别:

  • 从线程的角度来看:SMID一般是一个线程处理一条指令,这条指令是向量化处理的,一般需要一个cycle,而SIMT一般是创建多个线程,需要多个cycle
  • 从逻辑单元角度来看:SMIT相对于SMID需要4倍的逻辑单元

从硬件体系结构来看,SIMT体系结构一般将标量指令转换为向量化风格的SIMD处理,以获得更高的性能。

参阅文章:

参考书籍:

  • 《计算机体系结构:量化研究方法》
  • 《深入Linux内核架构》
  • 《分布式操作系统》
  • 《Multicore Processors and Systems》

猜你喜欢

转载自blog.csdn.net/qq_48322523/article/details/128010918