多核程序设计——存储模型

最近在看《现代体系结构上的UNIX系统——内核程序员的SMP和Caching技术》,这里抄点东西作为笔记吧!

顺序存储模型强制存储器操作(load和store)都按照程序次序来执行,即这些指令是按照在随程序执行的指令流中出现的顺序次序来执行的。它也指定了,由不同处理器完成的load和store操作也要以某种顺序、但又是非确定性的方式排序。这种存储模型应该是大家最容易理解的,甚至都认为实际MP也是这样工作的。但是,这种存储结构是非常落后的,现代处理器应该已经淘汰了这种结构。

书中讲到了一个例子,如下;

处理器一 处理器二
store %r1, A store %r1, B
load %r2, B load %r2, A

在强定序(strong order)的系统中,一共有四种可能的存储排序。但是可以肯定的是最后一条指令一定是load指令,也就是说至少有一条load指令会读取由别的处理器保存的新值。Dekker算法就是利用了这样的性质。Dekker算法是一种用在硬件中没有原子的读-改-写存储器操作(test-and-set或者xchg类似的指令)的情况下实现的临界区的技术。

enum state {UNLOCKED, LOCKED };
typedef struct {
    char status[2];
    char turn;
} lock_t;

void
initlock(lock_t *lock)
{
    lock->status[0] = UNLOCK;
    lock->status[1] = UNLOCK;
    lock->turn = 0;
}

void
lock(volatile lock_t *lock)
{
    lock->status[CPUID()] = LOCKED;

    while(lock->status[othercpu()] == LOCKED) {
        if(lock->turn != cpuid()) {
            lock-status[cpuid()] = UNLOCKED;
            while(lock->turn == othercpu())
                ;
            lock->status[cpuid()] = LOCKED;
        }
    }
}

void
unlock(loct_t *lock)
{
    lock->status[cpuid()] = UNLOCKED;
    lock->turn = othercpu();
}

TSO(完全存储定序):

完全存储定序相对强定序来说,对内存操作的顺序规律弱化了。首先,一个来自存储器的load指令的任意序列,假定它们都使用独立的寄存器,就能以任何次序来执行。所有保存指令都要确定次序,因此命名为完全存储定序(total store ordering)。完全存储定序MP中,如SPARC提供一种atomic-swap指令,它把单个位置的加载和保存操作当做一个不可分割的整体操作。

当一条atomic-swap指令发出时,他就被放到保存缓存区,相对于以前的store指令按FIFO次序进行处理。但是它会屏蔽更多的存储器操作,直到保存缓冲区为空、原子交换操作完成为止。

Dekker算法在TSO下是不能工作的,这是因为第一张表中的指令的可能顺序变多了,没有了前面分析的规律。在TSO结构下,lock指令就需要以下面的方式实现。

void
lock(void lock_t *lock_status)
{
    while(swap_atomic(lock-status, 1) == 1)
        ;
}

PSO(部分存储定序):

PSO则相对更加宽松,store指令的顺序也不一定以FIFO的顺序执行了。但是可以保证store缓存中对相同位置的store操作以程序顺序执行。同时load指令仍然会查看store缓冲,看是否有命中,如果有的话则返回最近向那个位置执行的store指令所带的数据。在PSO中也需要atomic_swap指令来实现锁,其行和TSO时介绍的是一样的。原子交换操作阻止了再进一步发出存储器操作,但是在原子交换操作执行的时候,store缓存不保证为空,也就是说原子操作会在前面的store指令完成前结束。但是由于指令是顺序发射的(这个保证现在看来比较勉强),临界段内的store和load指令都还没有发射。所以,PSO的上锁实现和TSO是基本一样的。

那么,解锁的时候呢?考虑下面一段临界区指令流:

atomic-swap              /*获得锁*/
load    %r1, counter       /*获得原来的值*/
add     %r2, %r1, 1        /*累加计数器*/
store %r2, counter       /*保存新值*/
clear %r3
store %r3, lock          /*释放自旋锁*/

考虑倒数第一条指令和倒数第一条指令,他们都是store指令。在PSO结构中,对不同位置的store指令的顺序是不确定的。倘若,释放自旋锁指令在保存新值指令之前完成,则整个临界区就被破坏了。因为绝对不允许这种情况出现,所以SPARC体系结构包括了一种称为store-barrier的指令,强制造成一定程度的顺序。用《POSIX多线程程序设计》中的一句话,内存屏障就是一睹移动的“墙”。墙壁之间的指令顺序是不一定的,但是墙壁两侧的指令是有相对顺序规律的。

所以,PSO结构下释放自旋锁的方式如下:

void
unlock(volatile lock_t *lock_status)
{
    store_barrier();
    *lock_status();
}

其实我看本书的目的是为了看懂《Is Parallel Programming Hard, And, if so, What Can You Do About It?》。这本书貌似只有电子版的,并发编程网有一个翻译版本叫《深入理解并行编程V1.0》,个人觉得这两本书配合起来看非常爽,因为他们侧重点不同,可以互补理解。

Blog地址:intheworld的专栏

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-25 21:13:54

多核程序设计——存储模型的相关文章

Bitcask存储模型

----<大规模分布式存储系统:原理解析与架构实战>读书笔记 近期一直在分析OceanBase的源代码,恰巧碰到了OceanBase的核心开发人员的新作<大规模分布式存储系统:原理解析与架构实战>.看完样章后决定入手,果然物有所值. 对于准备学习分布式的同学,这是一本不错的书籍,相对系统,全面的介绍了分布式的相关技术和项目,基本都是干货. 另一半是在介绍OceanBase的内容,对我来说,正是踏破铁鞋无觅处.接下来会有几篇专门研究存储引擎的读书笔记哟.废话不多说,转入正题. 1.存

Bitcask 存储模型的实现 - merge与hint文件

在<Bitcask存储模型的实现 - 基本框架>中,我们了解了Bitcask存储模型中数据的存储方式.内存索引的组织形式,以及如何使用缓存加速数据读取.另外,Bitcask存储模型中提出闲时进行merge减少数据冗余.运用hint文件加速创建内存索引,下面我们来看merge的具体实现.如何用hint文件加速索引创建. merge Bitcask是日志型存储模型,对于新增和更改的操作,都Append到磁盘,磁盘使用率将随着操作的增多而增长. 以上图例表示,key及对应val最开始存放在25.w,

剖析Elasticsearch集群系列第一篇 Elasticsearch的存储模型和读写操作

剖析Elasticsearch集群系列涵盖了当今最流行的分布式搜索引擎Elasticsearch的底层架构和原型实例. 本文是这个系列的第一篇,在本文中,我们将讨论的Elasticsearch的底层存储模型及CRUD(创建.读取.更新和删除)操作的工作原理. Elasticsearch是当今最流行的分布式搜索引擎,GitHub. SalesforceIQ.Netflix等公司将其用于全文检索和分析应用.在Insight,我们用到了Elasticsearch的诸多不同功能,比如: 全文检索 比如找

C语言存储模型

描述方法(三个方面) 作用域 代码块.函数原型 文件作用域 链接类型 外部链接 内部链接 空链接 存储时期 静态存储时期 动态存储时期 变量类型 变量存储类型 作用域 链接类型 存储时期 C语言存储模型(类) 文件 外部 静态 具有外部链接的静态 内部(static) 具有内部链接的静态 代码块 无链接 静态(static) 空链接静态变量 动态 自动变量 寄存器(性质与自动变量类似,存储在寄存器中) 寄存器 注: 具有外部链接的在其他文件使用前必须以exturn声明 具有静态存储期的变量必须使

LSM树存储模型

----<大规模分布式存储系统:原理解析与架构实战>读书笔记 之前研究了Bitcask存储模型,今天来看看LSM存储模型,两者虽然同属于基于键值的日志型存储模型.但是Bitcask使用哈希表建立索引,而LSM使用跳跃表建立索引.这一差别导致了两个存储系统的构造出现明显的分化.为此,我还先去捣腾了一番跳跃表的实现.今天算是进入了正题. LSM的结构 LSM的基本思想是将修改的数据保存在内存,达到一定数量后在将修改的数据批量写入磁盘,在写入的过程中与之前已经存在的数据做合并.同B树存储模型一样,L

Bitcask 存储模型

Bitcask 存储模型 Bitcask 是一个日志型.基于hash表结构的key-value存储模型,以Bitcask为存储模型的K-V系统有 Riak和 beansdb新版本. 日志型数据存储 何谓日志型?就是append only,所有写操作只追加而不修改老的数据,就像我们的各种服务器日志一样.在Bitcask模型中,数据文件以日志型只增不减的写入文件,而文件有一定的大小限制,当文件大小增加到相应的限制时,就会产生一个新的文件,老的文件将只读不写.在任意时间点,只有一个文件是可写的,在Bi

教你构建iSCSI服务器实现SAN存储模型

iSCSI(Internet Small Computer System Interface)Internet 小型计算机系统接口,是一种基于 TCP/IP的协议,用来建立和管理 IP 存储设备.主机和客户机等之间的相互连接,并创建存储区域网络(SAN).SAN 使得 SCSI 协议应用于高速数据传输网络成为可能,这种传输以数据块级别(block-level)在多个数据存储网络间进行. SCSI 结构基于客户/服务器模式,其通常应用环境是:设备互相靠近,并且这些设备由 SCSI 总线连接.iSC

智能合约从入门到精通:Solidity语法之内存变量的布局和状态变量的存储模型

简介:在前面我们已经讲过Solidity语言的一些语法内容,在矩阵元JUICE开放平台的JIDE开发时,一定要注意Layout in Memory和Layout of State Variables in Storage,即内存变量的布局和状态变量的存储模型.内存变量的布局(Layout in Memory) Solidity预留了3个32字节大小的槽位: 0-64:哈希方法的暂存空间(scratch space) 64-96:当前已分配内存大小(也称空闲内存指针(free memory poi

计算机数据存储模型

数据存储模型 当今社会,计算机无处不在,我们知道在计算机CPU用来计算数据,内存和Flash用来存储数据.计算机中的数据是现实社会中的内容在计算机中以另外一种方式来存储.我们的图片.文字.视频等资料都可以保存到计算机中.那么计算机又是如何保存这些数据的呢?在计算机中的这些数据到底是以什么方式存在?本节课将会为大家解答这些疑问,让大家从底层理解什么是计算机中的数据. 计算机电路模型 当我们拆开计算机,可以看到里面是一块电路板,上面有各种各位的元器件,有很多绕老绕去的线路,看起来很复杂.所有的计算都