内存模型的详解

最近所看的论文有涉及到内存模型的部分,去网上查阅发现涉及的文章并不多,且有些文章细节上漏洞百出,以下是我在看过Shared Memory Consistency Models:A Tutorial.的论文后,对其的总结

1. 为啥有内存模型

因为硬件和软件的优化/架构问题

1. 编译器和cpu都会对没有依赖关系的数据进行重排序,注意没有依赖关系指when they are to the same location or when one controls the execution of the other

2. 写操作(无论是写到缓存还是内存),总是花费数个时钟周期,cpu不可能一直等下去,而是把写操作分为两部分(写到storebuffer,再有storebuffer同步回内存或cache中),cpu只执行第一步,剩下的部分往往和其他操作并行,也就是说写入的数据何时同步回内存/cache中的时间不确定

2. 单核内存模型:

only Sequential Consistency
单核内存模型只有Sequential Consistency

这里给出Sequential Consistency的定义:

A multiprocessor system is sequentially consistent if the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program.

以下是论文中对他的描述,很形象:

(1)maintaining program order among operations from individual processors

//同一cpu指令不允许重排序

(2)maintaining a single sequential order among operations from all processors.

//多个cpu之间类似于单刀多置开关一样,对于同一内存操作必须等待上一个操作执行完成才能执行,如果是单核就没有这一点

想一想单核是如何执行多线程程序的?是通过不断的切换上下文,达到所谓的多线程效果,这时我们发现一个线程写,其他线程立刻就知道了,而且这个写操作是原子的(只有执行完成之后才能切到另一个进程中)

实际上,SC模型也是从单核执行逻辑中抽取得到的

3.多核内存模型:

最简单直接单性能最差的模型SC模型

如上图所解释的SC模型

这里再解释一下SC模型的两点要求

第一点要求是(指令重拍列)针对不同地址的操作,也是针对同一cpu中的指令

第二点要求(写的原子性①)针对的是同一地址的操作,关注的是不同cpu的操作(一个cpu的写操作,其他cpu是否可见)

        ①注.为啥是写的原子性嘞?

这里我们引入一个相对的写操作概念,对于一个处理器内核,从一个写操作开始写,到改写操作被该处理器看到为止(何为看到?就是此时假如对该内存地址进行读操作,能够读到你所写的值,再通俗的讲,就是你写的数据同步到了内存或共用cache),这一段过程称为一个完整的相对的写操作过程

那么全局写操作就是,从一个写操作开始,到所有的处理器都看到为止的过程

所谓写的原子性也就是在这个全局的写操作过程中是否存在中间情况:(是否有的内核看到了该写操作,有的没有看到)

而SC模型的第二条要求写操作不仅是执行了,还要让所有其他的内核"可见",也就是同步操作完成后,才允许切换为下一个内核执行操作

而对于RR操作其实没有那么严苛,交换顺序也无伤大雅(注意是相同地址的读)

在SC模型中多核cpu,同一时间只有一核工作,就很扯淡,因此针对SC的以上两点要求分别进行了放松操作,这些放松操作实际上是有交集的

允许WR重拍列的内存模型:

典型的架构:IBM 370 model, the SPARC V8 total store ordering model (TSO), and
the processor consistency model (PC)

TSO的出现是由于storebuffer,storebuffer是帮助cpu异步的处理写操作而诞生的,原本storebuffer被设计只能被写,不能被读,但人们发现对于在同一线程下有依赖关系的W-R操作,R只能被迫等待W写完(同步到全局内存中),才能执行,这就挺扯淡了.

为了优化这一点,工程师要求处理器

  1. 读取时优先从本地的storebuffer中读取
  2. 向storebuff中写数据分为两步骤,①写入storebuffer②storebuffer同步到主存
  3. 有依赖数据的写中的①操作要执行完才能执行读操作

可此时storebuffer中的数据是否同步完成了呢?鬼知道.

于是对于下面的执行过程:

 第一个图是方便我们理解的,第二个图才是绝大多数(不包括P0,P1处理器)处理器看到的实际执行顺序,也是我们普遍认为的global的执行顺序(实际上我们并不关心某个事件的开始时间),R和W1之间的顺序可以发生调换

 这样的执行过程确实很滑稽,但采用TSO内存模型的架构承认了这一缺点(摆烂了),并利用这一点(既然确定不了这样的执行顺序,就干脆放宽了所有的同一内核的WR执行完成时间(无依赖的采用重排序),这大大增强了cpu性能)

对于上面的几个架构:

他们都允许针对没有依赖关系的WR序列进行重排列

这几个不同点在于他们对于写的原子性上的保证

 IBM 370与SC要求相同,即写操作必须同步完成后,读操作才承认写的完成,才会从中读取

TSO对此放松了一部分,即同一内核的读操作可以直接从storebuffer中读取,无需等待写操作同步完成,而对于不同内核的WR对,就必须严苛的按照SC的要求了①

PC,就纯纯放飞自我了,这两种情况下读操作都可以直接从写的操作中读取,而无需等待同步完成

允许WR+WW重拍列的模型:

典型架构:SPARC V8 partial store ordering model (PSO)

PSO与TSO相同点在于都支持①部分

不同之处在于TSO再写如storebuffer时是按顺序写入,且同步时也是按顺序的,而PSO就没有这样的保证(对同一地址的写)

Relaxing All Program Orders,放飞自我的模型:

weak ordering (WO) model, RCsc/RCpc, the Digital Alpha, SPARC V9 relaxed memory order (RMO), and IBM PowerPC models

其中除了Alpha之外,所有内存模型都支持RR的重拍列

这些模型在放弃诸多约束后换来了性能的提升:

In hardware, this flexibility provides the possibility of hiding the latency of read operations by implementing true non-blocking reads in the context of either static (in-order) or dynamic (out-of-order) scheduling processors, supported by techniques such as non-blocking (lockup-free) caches and speculative execution 

在硬件中,这种灵活性通过在静态(有序)或动态(无序)调度处理器的环境中实现真正的非阻塞读取,提供了隐藏读取操作延迟的可能性,并得到了非阻塞(无锁定)缓存和推测性执行等技术的支持

 在写原子性上:

所有的模型都允许直接读取本内核的写操作

RCpc and PowerPC允许你直接读取其他内核未同步的写操作


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值