分布式共享内存
分布式共享内存,Distributed Shared Memory(DSM),是一种构架,多个机器共享所有的内存,看到的是同一块地址空间。这样就像使用同一个机器一样,操作不同机器上的内存了。
1. 问题
1.1 简单的实现
一个很直接地想法,就是做一个内存的映射表。比如4个4G的机器,组成一个16G的共享内存。那么0-4G映射到机器1上,4-8G映射到机器2上,依次类推。读的时候,直接去对应的机器去读;写的时候,给对应的机器发送一个写的请求,即可。
但是毕竟是分布式,分布式系统环境下一个非常有意思的问题就是网络延迟的不确定性。比如机器A更新了实际物理内存在B上的数据,C再读的时候会有一个很大的延迟。这样就对一致性有了要求。
举个例子1
2
3
4
5
6Z = X = Y = f_x = f_y = 0
thread1: x = 1, f_x = 1
thread2: while f_x == 0;
y = 2, f_y = 1
thread3: while f_y == 0;
z = x + y
z 有可能为,0,1,2,3。为什么呢?
| x | y | z | f_x f_y |
thread1发送了写x和f_x的请求,f_x到达了,x有可能没有到达,所以thread2继续执行了;同样道理,f_y到达了,y有可能没有到达,所以thread3看到的x和y可能是更新过的,也可能是没有更新过的。
1.2 替代方案:
本地缓存数据;读的时候直接读;写的时候发送写到所有的副本上。 z 可能为 2, 3。因为p3不依赖p1,可能会延迟。也就是p1->p2->p3,p3此时没有接受到p1的数据。
2. 一致性问题
2.1 what is correct
其实这时候,我们需要一个概念,描述什么样的标准是正确的;或者说程序员默认的,能接受的。并行体系结构,如何判定执行结果是正确的?一个直观的想法,并行处理的结果,等价于一个单核单内存执行相同指令的结果。那么什么是等价?标准有严有松,因而引发了不同级别的一致性定义。
分布式系统里的一致性,根据wiki的定义,指的是特定的操作会产生特定的结果,相当于程序员和系统之间的一个协议。这里再具体一点,指的是系统提供的读写接口,会有什么样的效果。
一致性有强有弱。对于一个操作集合,如果能找出一个全局的顺序,使得在并行构架上执行这个集合的结果等价于该全局顺序,就是强一致性;否则是弱一致性。
DSM里面使用的是强一致性,所以这里介绍两种一致性模型,strict consistency和Sequential consistency。
2.2 严格一致性。
strict consistency,每个指令有一个时间戳。严格按照时间戳执行。这里时间戳是一个假想的。
- 所有的core看到同一个指令集合;
- 按照同一个顺序(时间戳)执行;
- 读写内存必须等到内存值被改变,才能算作完成指令。
所以整个系统只能有一种操作方式。
2.3 顺序一致性
Sequential consistency:
- 指令并集是一样
- 多核里每个核内的执行顺序,等价于单核里的执行顺序。
- 多核并行执行的结果 == 单核机器执行的结果。 找到一个即可
比strict 放宽了,线程间的指令顺序可以调换。global order 可以不唯一。
3 DSM的实现
一般来说,实现顺序一致性就够了,实际系统很少有严格一致性。DSM的一种实现方式(IVY)就是顺序一致性。
具体做法:
- 有一个全局的路由表,每一个虚拟内存,有一个owner和若干个copy。路由表由一个manager管理。
- 读写直接在本地操作;如果本地没有对应的缓存,或者读写权限不对,触发pagefault,很像操作系统。
- 如果触发读的pagefault,会向manager发请求,告之owner,owner会向该节点发送一个copy。
- 如果触发的是写pagefault,会向manager发请求,首先复制owner,然后将原来的owner和copyset的数据全置为invalid,然后设立新的owner。