分布式共享内存,Distributed Shared Memory(DSM),是一种构架,多个机器共享所有的内存,看到的是同一块地址空间。这样就像使用同一个机器一样,操作不同机器上的内存了。

1. 问题

1.1 简单的实现

一个很直接地想法,就是做一个内存的映射表。比如4个4G的机器,组成一个16G的共享内存。那么0-4G映射到机器1上,4-8G映射到机器2上,依次类推。读的时候,直接去对应的机器去读;写的时候,给对应的机器发送一个写的请求,即可。

但是毕竟是分布式,分布式系统环境下一个非常有意思的问题就是网络延迟的不确定性。比如机器A更新了实际物理内存在B上的数据,C再读的时候会有一个很大的延迟。这样就对一致性有了要求。

举个例子

1
2
3
4
5
6
Z = 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,每个指令有一个时间戳。严格按照时间戳执行。这里时间戳是一个假想的。

  1. 所有的core看到同一个指令集合;
  2. 按照同一个顺序(时间戳)执行;
  3. 读写内存必须等到内存值被改变,才能算作完成指令。
    所以整个系统只能有一种操作方式。

2.3 顺序一致性

Sequential consistency:

  1. 指令并集是一样
  2. 多核里每个核内的执行顺序,等价于单核里的执行顺序。
  3. 多核并行执行的结果 == 单核机器执行的结果。 找到一个即可

比strict 放宽了,线程间的指令顺序可以调换。global order 可以不唯一。

3 DSM的实现

一般来说,实现顺序一致性就够了,实际系统很少有严格一致性。DSM的一种实现方式(IVY)就是顺序一致性。

具体做法:

  1. 有一个全局的路由表,每一个虚拟内存,有一个owner和若干个copy。路由表由一个manager管理。
  2. 读写直接在本地操作;如果本地没有对应的缓存,或者读写权限不对,触发pagefault,很像操作系统。
  3. 如果触发读的pagefault,会向manager发请求,告之owner,owner会向该节点发送一个copy。
  4. 如果触发的是写pagefault,会向manager发请求,首先复制owner,然后将原来的owner和copyset的数据全置为invalid,然后设立新的owner。