现在大多数多核芯片在硬件中支持共享内存,设计和评估一个正确的共享内存系统需要准确理解内存模型。
不同CPU可能采用不同的内存模型,比如:
- ARM和RISC-V的Related模型;
- Intel和AMD的TSO模型;
- IBM的Power模型等等
尽管这些模型千奇百怪,各有优缺点,但我们只要抓住它们的本质,就可以轻松拿捏它们。不要太在意边边角角的点,不然很容易陷进去。本文闲聊的内容框架大致如下,如果有出现专有名词,就不再解释了,请各位自行搜索下,或者翻看我的历史文章。
内存模型
Memory consistency model又称Memory model (内存模型),定义了使用Shared memory(共享内存)执行多线程(Multithread)程序所允许的行为规范。
- 内存模型主要是抓住program order(程序顺序)和global memory order(全局内存顺序);
- 根据这两个order允许的行为,可以把内存模型划分为
- SC(Sequential Consistency)、
- TSO(Total Store Order)
- Relaxed(weaker) model。
SC模型
简单来说,如果global memory order保持每个Core的program order,那么内存模型就是SC模型。SC模型是最直观而且最容易让程序员推理代码的执行结果,但过于死板,限制了硬件的发挥,于是就进一步发展了TSO模型。
TSO模型
不管地址是否相同,TSO模型的older store和younger load的program order在global memory order中可以不保留;
这就允许Core中加入FIFO类型的Store buffer,用于缓存已经在Core pipeline上Commit的Store数据,但还没有写到memory当中,隐藏了store写到memory的latency来提高性能,后续的younger load如果发现可以从Store buffer中获取想要的数据,那么Store buffer可以直接forward过去。
在TSO模型中,对于单个Core来说,程序的执行结果看起来还是符合预期。
但多个Core情况下,会有一些出乎意料的结果,因此引入了FENCE指令,如果想要让older store和younger load的program order一定与global memory order一致,那么需要在它们两个之间插入FENCE指令。
TSO模型一定程序上也限制了硬件的优化,于是就进一步发展了Relaxed模型。
Relaxed模型
Relaxed模型只寻求保留程序员需要的顺序,让一些程序员不关心的指令顺序可以乱序执行,从而允许软硬件更多的优化。
Relaxed模型对于不同地址的load和store,可以让它们乱序执行,对于同地址的load和store,让它们保持TSO模型的规则,也就是older store和younger load可以不遵循global memory order,但load必须可以得到最新store的值。
这就允许Core可以将TSO中FIFO类型的Store buffer升级为非FIFO类型的Store buffer。且允许多笔store数据的merge行为。在Relaxed模型中,对于单个Core来说,程序的执行结果看起来还是符合预期。但多个Core情况下,会出现更多出乎意料的结果,因此也引入了FENCE指令,以便程序员可以指示哪些指令间需要遵循global memory order。
总得来说,这三类模型,对于单Core来说,程序执行结果是确定的,但对于多Core来说,程序执行结果会存在不一致的情况。
- SC模型为同一线程中load和store的所有四种组合(Load->Load, Load->Store, Store->Store, Store->Load)提供global memory order保序。
- TSO模型为同一线程中load和store的三种组合(Load->Load, Load->Store, Store->Store)提供global memory order保序,不对 Store->Load做global memory order保序。
- Relaxed模型对不同地址的memory操作,允许它们乱序执行,但是对相同地址的memory操作,它和TSO的规则一致。