内存一致模型——顺序一致模型

来源:互联网 发布:mac 终端 重命名文件 编辑:程序博客网 时间:2024/05/29 13:53

内存一致模型——顺序一致模型

顺序一致模型,是最常见的内存一致模型,定义如下:

【如果一个多处理器系统是顺序一致的】,那么,无论程序怎么运行,结果都与各处理器各自轮流运行后的结果相同,且各处理器内部的执行顺序由程序决定。

从定义中, 可以得出,顺序一致模型有如下要求:

 - 保证单一处理器内部的执行顺序 - 保证多处理器操作同一块内存时的先后顺序

如图所示:

顺序一致性图示

总线结构保证在相同时间内对指定内存块的访问只有一个处理器。这样就保证多处理器之间不会冲突。

下面展示引用文献[1]中的两个例子(a) (b):

这里写图片描述

(a)中就用到了Dekker算法,过程一目了然,放一段代码吧

#include <Windows.h>size_t signal1 = 0;size_t signal2 = 0;volatile bool entered1 = false;volatile bool entered2 = false;DWORD __stdcall worker1Thread(LPVOID param){    for (int i = 1; i < 100000;)    {        //printf("a1 ");        signal1 = 1;        //printf("a2 ");        size_t tsig = signal2;        if (tsig == 0)        {        //  printf("a3 ");            entered1 = true;        //  printf("a4 ");        //  printf("id : %d ", 1);            bool violated = entered2;            if (violated)                printf("worker1 violated");        //  printf("a5 ");            entered1 = false;        //  printf("a6 ");            //printf("checked : ",)            i++;        }    //  printf("a7 ");        signal1 = 0;    //  printf("a8\n");    }    return ERROR_SUCCESS;}DWORD __stdcall worker2Thread(LPVOID param){    for (int i = 1; i < 100000;)    {    //  printf("b1 ");        signal2 = 1;    //  printf("b2 ");        size_t tsig = signal1;        if (tsig == 0)        {        //  printf("b3 ");            entered2 = true;        //  printf("id : %d ", 2);        //  printf("b4 ");            bool violated = entered1;            if (entered1)                printf("worker2 violated");        //  printf("b5 ");            entered2 = false;        //  printf("b6 ");            i++;        }    //  printf("b7 ");        signal2 = 0;    //  printf("b8\n");    }    return ERROR_SUCCESS;}void test24(){    CloseHandle(CreateThread(NULL, 0, worker1Thread, NULL, NULL, NULL));    CloseHandle(CreateThread(NULL, 0, worker2Thread, NULL, NULL, NULL));}

为什么有这么多注释?因为如果你运行这段代码你会发现,会以极低的概率报violated。仔细想想,代码好像又没什么问题。

经过再仔细的分析之后发现,如果某线程在将signal置0之后被操作系统剥夺了cpu时间,那么就会导致冲突出现。下面就会分析无缓存及有缓存情形的一致性模型。

无缓存架构

在很多现如今的CPU实现中,都会有写入缓冲区来作为硬件加速的一种手段。也就是说,CPU对内存的操作会先保存在写入缓冲区中,继而写入内存,而这种行为就导致内存操作非原子。对于单处理器系统而言,并不存在这种问题,因为只有一个处理器,所以写入缓冲区也就只有一个。但是对于多处理器系统来说,就另当别论了,因为各个处理器用的并不是同一块定写入缓冲区,so,问题来了。

多核心多写入缓冲区情况

第一种情形,我们来看一下保证内存写入读取顺序的重要性。在Dekker算法中,对于一个顺序一致模型来说,当进行互斥区进入判断时,并不会存在两个信号量都为0的情况出现。在这种情形下就会出现这种冲突,如图所示:

多核心多写入缓冲区

单个核心在读取某内存时,会先检查自己写入缓冲区中是否包含对应地址的内存写入,如果存在则返回写入的值,如上文所提,单核心系统不会存在冲突问题;而如果不存在,则会直接到内存中读取数据。如果有多个核心,图中所示就是引起冲突的原因。

引用:

[1] Sarita V. Adve, Kourosh Gharachorloo.Shared Memory Consistency Models:A Tutorial[R].Palo Alto, California 94301 USA:WRL,1995.

0 0
原创粉丝点击