内存一致性模型

文章目录

  • 硬件及软件技术的变化
    • 技术变化引入的一些概念
    • 概念详解
    • 概念 : 内存一致性
        • 内存一致性模型种类
        • 内存一致性在代码中的体现
        • 内存一致性实例 : RISCV的内存一致性
          • 缓存一致性
          • 原子性
          • memory order & 屏障指令
        • 内存一致性实例 : ARM的内存一致性
          • 缓存一致性
          • 原子性
          • memory order & 屏障指令
        • 参考资料

硬件及软件技术的变化

1.流水线
	// 8级别
2.多道流水线
	// 2道
	多发射 : 有多个译码单元
	一般有几个多发射,就是有几个流水线
	但是对于intel 来说, 一个流水线中会有多发射的概念
3.执行乱序-流水线满载技术
	
4.cache技术
	// icache
	// dcache
5.多核心

6.memory order

A.编译乱序

技术变化引入的一些概念

缓存一致性问题
	cache引入导致了问题,解决该问题的方案为MESI(缓存一致性协议)
原子性问题
	硬件多核心,软件多线程 引入

访存顺序
	为了使指令更快的运行
	上一条指令结果还没产生就开始运行下一条指令

在单核和多核上,缓存一致性问题 ,原子性问题,访存顺序问题,都需要解决

缓存一致性,原子性问题,访存顺序问题,三种问题的组合,就是内存一致性问题
	缓存一致性 关注的是数据的一致									从而保证正确性 // 硬件上直接解决了一些问题 . 解决不了的,暴漏了一些cache维护指令,让软件调用了来解决
	原子性     关注的是对同一个内存地址访存的不可打断 				从而保证正确性 // 暴漏了原子指令,让软件调用来解决
	访存顺序   关注的 上一个指令结果和下一个指令执行 两者的同步	从而保证正确性 // 暴漏了屏障指令,让软件调用来解决

内存一致性 关注的是正确性

概念详解

  • 原子性
原子性:对同一位置的读写,是原子的,从而保证了内存一致性

不会存在高32bit是上一笔写入的值,低32bit是下一笔写入的值
  • 访存顺序(memory order)
// 各种架构的访存顺序 : https://zh.wikipedia.org/wiki/%E5%86%85%E5%AD%98%E6%8E%92%E5%BA%8F
内存顺序模型
	使用者定义
	观察者定义
	读写操作 读写结果
	cacheable/ unbuffered/Shared
	Device/Normal
	访存顺序要求
	
我们把内存分为 几种,这样内存就可以分类 为 61. 是否可以缓存
	2. 是否可以缓冲
	3. 是否可以共享

硬件对 几种内存 操作的先后顺序(memory order) 有了定义
	仅能保证一部分 顺序 能够有正确的结果

访存顺序(memory order) 规定了
	保证了写操作之间的顺序
	不保证对读操作和写操作之间顺序
	不保证写结果与读操作之间的顺序


访存顺序(memory order) 是 软件和存储系统之间对访存行为的一种约定

当软件的访存行为 被  访存顺序(memory order) 保证时,  可以得到预期的正确访存结果
当软件的访存行为 被  访存顺序(memory order) 保证时,不可以得到预期的正确访存结果
	这些访问行为是 真实存在的. 例如一个读操作在一个写操作之后很短的一段时间之内发生,那么该读操作可能读不到该写操作写入的值。
	这时候就需要 程序员用 访存顺序(memory order) 提供的屏障指令来保证结果正确性


存在着那些 memory order 和 其提供的 屏障指令
	严格一致性模型 包括了 "严格" memory order
	顺序一致性模型 包括了 "顺序" memory order
	弱一致性模型   包括了 "弱"   memory order

概念 : 内存一致性

参考书籍
	A primer on memory consistency and cache coherence(带标签).pdf
本文会使用「看见」这个词。当一个处理器(PA)对共享变量(V)的本地副本进行了修改,而另一个处理器(PB)用于保存相应变量的缓存行因此而失效或被更新,则本文称 PB 看见了 PA 对变量 V 的修改

我们来看看一致性模型的定义。
一致性模型,也就是一个用来规定新值"什么时候"传播到某一指定处理器的策略。

这个定义看起来有点像缓存一致性协议
缓存一致性协议也即一个用来将修改过的缓存副本"如何"传播给别的缓存。

俩兄弟看着挺像的,但前者确定的是何时,而后者确定的是如何

缓存一致性,原子性问题,访存顺序问题,三种问题的组合,就是内存一致性问题
	缓存一致性 关注的是数据的一致									从而保证正确性
	原子性文件 关注的是对同一个内存地址访存的不可打断 				从而保证正确性
	访存顺序   关注的是 上一个指令结果和下一个指令执行两者的同步	从而保证正确性

内存一致性 关注的是正确性

内存一致性模型种类

一致性模型的种类 
	1.https://blog.csdn.net/qq_39815222/article/details/107029271 
	2.https://zh.m.wikipedia.org/wiki/%E5%86%85%E5%AD%98%E4%B8%80%E8%87%B4%E6%80%A7%E6%A8%A1%E5%9E%8B#%E5%86%85%E5%AD%98%E4%B8%80%E8%87%B4%E6%80%A7%E6%A8%A1%E5%9E%8B%E5%88%97%E8%A1%A8

线性一致性(Linearizability)或严格一致性(Strict consistency):任何对一个内存位置X的读操作,将返回最近一次对该内存位置的写操作所写入的值。
原子一致性(Atomic consistency):读操作未能立即读到此前最近一次写操作的结果,但多读几次还是获得了正确结果。所有对数据的修改操作都是原子的,不会产生竞态冲突。
顺序一致性(Sequential consistency ):(并发程序在多处理器上的)任何一次执行结果都相同,就像所有处理器的操作按照某个顺序执行,各个微处理器的操作按照其程序指定的顺序进行。换句话说,所有的处理器以相同的顺序看到所有的修改。读操作未必能及时得到此前其他处理器对同一数据的写更新。但是各处理器读到的该数据的不同值的顺序是一致的。
缓存一致性(Cache Coherence)
静态一致性(Quiescent consistency)
处理器一致性(Processor consistency)/PRAM一致性(PRAM consistency,P指pipeline):在一个处理器上完成的所有写操作,将会被以它实际发生的顺序通知给所有其它的处理器;但是在不同处理器上完成的写操作也许会被其它处理器以不同于实际执行的顺序所看到。这反映了网络中不同节点的延迟可能是不相同的。对于双处理器,处理器一致性与顺序一致性是等价的。
释放一致性(Release consistency ):在对一个共享变量进行普通访问之前,进程在之前所有的获得锁而进行的操作必须成功的完成。在释放一个锁操作之前,进程之前的读和写操作必须已经完成。获得和释放锁的操作必须符合“FIFO一致性”。“释放一致性”仅仅关注被锁住的共享内存内存变量,仅仅只需要将对被锁住的共享变量的修改通知给其它的处理器。C#的VolatileWrite函数即实现了释放一致性语义。
因果一致性(Causal consistency )
TSO一致性(Total store ordering)
PSO一致性(Partial store ordering)
弱序一致性(Weak-ordering consistency)
最终一致性(Eventual consistency)
单项一致性模型(Entry Consistency)


内存一致性模型
	sequential consistency // 顺序一致性
	relaxed consistency mode // 非 顺序一致性的都可以放到这里 // 放松一致性  // 也被称为松散一致性模型
		total store ordering // TSO一致性
		partial store ordering // PSO一致性
		weak ordering, release consistency
		弱一致性模型(Weak Consistency)
		释放一致性模型(Release Consistency)
		狭义的 relaxed consistency mode(RMO)
			系统开发人员为了榨取更多的性能
			在PSO的基础上进一步放宽了访存指令的执行限制,不仅允许store-store,store-load乱序
			还进一步允许load-load,load-store乱序
			只要是地址无关的指令,在读写访存的时候都可以打乱访存顺序。

sequential consistency
	我们称一个多处理器系统是「顺序一致的」,当该多处理器系统的运行结果看起来好像所有处理器的操作按照某种线性顺序执行,且在该线性顺序中,各处理器的操作还遵循程序指定顺序。

relaxed consistency mode
	把顺序一致性的要求放低一点。
	虽然这样会让大家脑壳子疼一些,但其实是一种利好,有利于系统性能的提升。
	比顺序一致性更宽松的内存模型都被称为宽松一致性。
	例子 : SPARC 采用的 TSO  ,  Intel 所采用的 TSO

内存一致性在代码中的体现

不管rv芯片遵循哪一个内存一致性模型

缓存一致性 是 硬件负责的,有没有对应的指令 ??? TODO

底层(汇编)编程人员都需要用其提供的内存一致性相关指令 编程 来确保程序的正确性。
指令有 fence相关指令(3个)和所有的A扩展指令。 
程序员用这些指令 和 硬件实现来 确保程序的正确性
硬件越严格,程序员需要做的事就越少 硬件越松散,程序员需要做的事就越多


硬件 中 内存一致性模型 的体现 
	1. 一个确定的内存一致性模型 
	2. 为了弥补内存一致性模型的 不足(并不是不足),而提供的相关指令(safety net)

		riscv 提供了 
			a指令集的 ll/sc 和amo系列 // 精准支持release consistency的原子指令,其中包括大名鼎鼎的LL/SC指令对(RISC-V里叫LR/SC)和包含acquire/release字段的一系列AMO指令。
			fence fence.i sfence.wma // I指令集(必选)提供了FENCE,简单而粗暴

软件中内存一致性模型的体现 
	1.硬件提供的指令 
	2.这些指令在汇编指令集合中的排列
		riscv 的应用
			A扩展指令集和FENCE指令功能互有交叠,对于简单排序存储操作,二者都是胜任的。
			对于synchronization,很显然我们可以使用LR/SC实现

内存一致性实例 : RISCV的内存一致性

// 有两个内存一致型模型

RVWMO
	《The RISC-V Instruction Set Manual, Volume I: User-Level ISA》明确规范了RISC-V的内存一致性模型,称为“RVWMO” (RISC-V Weak Memory Ordering)。
	RVWMO主要遵循了RC(release consistency)理论模型,用较少的内存访问顺序约束,为硬件实现和性能优化提供了宽松的条件;
	同时,禁止若干过于复杂费解的乱序情况,方便了软件程序的开发利用。总体上RVWMO是一种弱内存序模型。
	本质上是Release Consistency与Relaxed Consistency的结合体



RVTSO // 很少实现用这个
	为了便于从x86体系结构向RISC-V迁移,规范还明确了一个称为“Ztso”的标准扩展
	提供完全兼容x86架构的RVTSO(RISC-V Total Store Ordering)内存模型。

// 同时,还有Zam 的扩展,但是该扩展 不是 内存一致性模型

缓存一致性
如何
原子性
// 对应 RVWMO
a扩展指令集的 ll/sc 和amo系列
	精准支持release consistency的原子指令
	其中包括
		大名鼎鼎的LL/SC指令对(RISC-V里叫LR/SC)
		包含acquire/release字段的一系列AMO指令

memory order & 屏障指令
  • 屏障指令
fence fence.i sfence.wma // I指令集(必选)提供了FENCE,简单而粗暴
// 这些对应的是 RVWMO 还是 RVTSO ? 

#define nop()		__asm__ __volatile__ ("nop")

#define RISCV_FENCE(p, s) \
	__asm__ __volatile__ ("fence " #p "," #s : : : "memory")

/* These barriers need to enforce ordering on both devices or memory. */
#define mb()		RISCV_FENCE(iorw,iorw)
#define rmb()		RISCV_FENCE(ir,ir)
#define wmb()		RISCV_FENCE(ow,ow)

/* These barriers do not need to enforce ordering on devices, just memory. */
#define __smp_mb()	RISCV_FENCE(rw,rw)
#define __smp_rmb()	RISCV_FENCE(r,r)
#define __smp_wmb()	RISCV_FENCE(w,w)

为什么 UP(单核), linux 中  #define smp_mb()    barrier()
	用于SMP场合的内存屏障,对于UP不存在memory order的问题(对汇编指令)
	因此,在UP上就是一个优化屏障,确保汇编和c代码的memory order是一致的

内存一致性实例 : ARM的内存一致性

ARM体系结构是一种弱ordered的内存体系结构
Weak Order Consistency
缓存一致性
MESI,如何
原子性
armv7 : 大名鼎鼎的LL/SC指令对(ldrex,strex)
armv8 : ldxr,stxr
memory order & 屏障指令
  • memory order
    内存一致性模型_第1张图片
: 顺序 是执行顺序
  • 屏障指令
riscv
	fence			sync thread
	fence.i  		sync instr & data
	sfence.vma  	virtual memory fence

armv8
	dmb				data memory barrier
	dsb 			data sync barrier
	isb				instruction sync barrier

armv7
	dmb				data memory barrier
					在DMB之后的显示的内存访问执行前,保证所有在DMB指令之前的内存访问完成。
	dsb 			data sync barrier
					等待所有在DSB指令之前的指令完成(之后再执行后续的指令,译注)。
	isb				instruction sync barrier
					清除(flush)流水线,使得所有ISB之后执行的指令都是从cache或内存中获得的(而不是流水线中的)
armv6
	dmb
	dsb
	PrefetchFlush
		The PrefetchFlush instruction flushes the pipeline in the processor,
		so that all instructions following the pipeline flush are fetched 
		from cache or memory after the instruction has been completed.

参考资料

  • 内存模型系列(上)- 内存一致性模型(Memory Consistency)
  • 内存模型系列(下)- 内存持久性模型(Memory Persistency)
  • Memory Consistency Models: A Tutorial
  • Memory Consistency(上)
  • Memory Consistency (下)

  • riscv memory一致性模型 资料
  • [RFC]RISC-V内存一致性模型
  • Linux内核在RISC-V架构下的内存屏障与原子操作

你可能感兴趣的:(riscv,内存一致性)