读锁操作方法、写锁操作方法及系统的制作方法_2

文档序号:8258442阅读:来源:国知局
描述中的附图仅仅是本申请中记载的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
[0034]图1为本申请读锁操作方法一个实施例的流程图;
[0035]图2为本申请读锁操作系统一个实施例的模块图;
[0036]图3为本申请写锁操作方法一个实施例的流程图;
[0037]图4为本申请写锁操作系统一个实施例的模块图。
【具体实施方式】
[0038]本申请实施例提供一种读锁操作方法、写锁操作方法及系统。
[0039]为了使本技术领域的人员更好地理解本申请中的技术方案,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都应当属于本申请保护的范围。
[0040]首先介绍本申请读锁操作方法的一个实施例。
[0041]图1示出了本申请读锁操作方法一个实施例的流程图。如图1所示,该实施例的方法包括:
[0042]SlOO:设置每个核心对应的私有引用计数。
[0043]现代CPU采用了大量的技术来抵消内存访问带来的延迟。读写内存数据期间,CPU可以执行成百上千条指令。多级静态随机存储器(Static Random Access Memory, SRAM)缓存(以下简称为缓存)是减小这种延迟带来的影响的主要手段。
[0044]例如,对于双核心的计算机系统,核心I和核心2分别有对应的缓存I和缓存2。所述缓存可以是计算核心的缓存。例如,对于CPU而言,CPU内部常常带有一级缓存、二级缓存,甚至有的CPU还带有三级缓存。对于包括一级缓存、二级缓存的CPU来说,CPU需要操作的数据,一种情况是从内存中先读入到二级缓存,再从二级缓存读入到一级缓存,再从一级缓存读入到CPU中执行。一般来说,越靠近CPU的存储器,速度越快,但造价也越高;越远离CPU的存储器,速度越慢,但造价也越便宜。一般在靠近CPU的存储器中存储CPU读写频繁的数据,以提高造价高的存储器的利用率。
[0045]本步骤中,优选的,可以将私有引用计数(private_read_ref)置于缓存中。例如,可以将私有引用计数设置在CPU的一级缓存中。当然,视CPU的体系架构以及不同级的存储器的容量,也可以将私有引用计数设置在二级缓存中,还可以设置在其它读取速度与CPU原子操作速度同量级的存储器中。本申请实施例对此并不做特别限定。事实上,缓存往往对程序是透明的,也就是说程序没办法控制一个变量是否要放到缓存中,以及要放在哪一级缓存。当程序要操作一个变量时,CPU可以检查该变量是否在一级缓存中,如果有,直接从一级缓冲中读;如果没有,可以检查是否在二级缓存中:如果有,把变量从二级缓存载入到一级缓存,如果二级缓存也没有,把变量从内存中载入到二级缓存和一级缓存中。
[0046]现有技术中,不同线程对同一数据的读操作,涉及同一引用计数,即对同一引用计数操作。这个引用计数read_ref,按照计算机领域一般规则称为全局read_ref。特别是同一计算核心的不同线程,包括同一进程中的不同线程,或者是不同进程中的不同线程,在对同一数据进行读操作时,对同一个全局read_ref进行自加(++)或自减(一)操作。如果在多核心计算机系统中,对于多个核心的情况,仍然只采用一个全局引用计数,则会出现如【背景技术】中分析得到的问题。
[0047]本步骤中,对于不同核心,为每个核心设置私有应用计数。例如,对于核心1,设置其对应的私有引用计数,例如为read_ref_corel ;对于核心2,也设置其对应的私有引用计数,例如为read_ref_COre2。对于还包括其它核心的情况,可以依此类推。
[0048]对于每一核心对应的私有引用计数,可以不是永久(或称之为固定)分配的,而是临时分配的。例如,可以在每个核心的线程对数据进行首次加读锁前进行分配;在该核心的线程对该数据的读操作执行完毕之后收回该私有引用计数。具体的,可以设置一个私有引用计数的数组[reacLref]。在每个核心的线程对数据进行首次加读锁前,申请分配该[read_ref]数组中的一项。该数组[read_ref]的空间可以设置的足够大。数组中每一项可以设置为整形(int)。数组中每一项的初始值可以初始化为O。当然,针对某一数据的读操作,也可以将[read_ref]数组中的每一项固定分配至每一个核心。
[0049]优选地,实际操作中,可以将[read_ref]数组中的每一项分配到缓存中的一个缓存行中(cache line)。缓存行是多核心CPU维护缓存一致性的最小单元,也是内存交换的实际单位。实际当中,大多数平台上的一个缓存行要大于8字节,大多缓存行是64字节。如果[read_ref]数组定义为int型,贝U为8字节。可见,一个缓存行可以存储8个read_ref。如果一个缓存行中存储不止一个reacLref的情况,则操作数组中不同元素时就会有冲突。为了避免冲突,可以将[read_ref]数组中每一个read_ref存储在一个缓存行中。例如,可以将[read_ref]数组中的每一项声明为一个结构体,同时声明一个结构体大小为64字节。这样,[read_ref]数组中的每一项都独占一个缓存行,可以避免操作时产生冲突。
[0050]SllO:在不同核心的线程对同一数据进行读取过程中,以不同核心对应的私有引用计数进行加读锁、解读锁操作。
[0051]例如,同一计算机系统中包括2个计算核心,分别为核心I和核心2。再例如,核心I和核心2都要对同一数据进行读取。按照S100,核心I可以申请I个私有引用计数,标记为read_ref_corel ;类似的,核心2也可以各申请I个私有引用计数,如为read_ref_core20
[0052]这样,在核心I的线程对该数据进行读取过程中,首先进行加读锁。即,核心I的私有引用计数read_ref_corel执行加I操作。这样,read_ref_corel由初始值O变为I。之后,核心I的线程对该数据进行读取。读操作执行完毕之后,进行解读锁操作。即,核心I的私有引用计数read_ref_corel执行减I操作。这样,read_ref_corel由I变为O。
[0053]类似的,在核心2的线程对该数据进行读取过程中,首先进行加读锁。即,核心2的私有引用计数read_ref_core2执行加I操作。这样,read_ref_core2由初始值O变为I。之后,核心2的线程对该数据进行读取。读操作执行完毕之后,进行解读锁操作。即,核心2的私有引用计数read_ref_core2执行减I操作。这样,read_ref_core2由I变为O。
[0054]本申请实施例采用的上述方式,使得不同核心的线程对同一数据进行读操作时,独立的对该核心对应的私有引用计数操作。这些不同核心对应的私有引用计数不需要在各个核之间同步,因此执行效率得到提升。而且,读锁的扩展性也得以提高,即无论多少个核心的线程并发加、解读锁,加解读锁的时间几乎都不会增加。
[0055]此外,不同核心对应的私有引用计数不需要在各个核之间同步,省去了各个核心之间的通信过程,从而省去了核间通信所需的带宽、时间等的开销。
[0056]所述SllO具体可以包括如下步骤:
[0057]Slll:第一核心的线程对数据进行读取过程中,以第一核心对应的私有引用计数进行加读锁、解读锁操作。
[0058]S112:第二核心的线程对所述数据进行读取过程中,以第二核心对应的私有引用计数进行加读锁、解读锁操作。
[0059]上述以私有引用计数进行的加读锁操作,具体包括:不同核心的进程以各核心对应的私有引用计数执行加I操作。以私有引用计数进行的解读锁操作,具体包括:不同核心的进程以各核心对应的私有引用计数执行减I操作。在加读锁和解读锁操作之间,各核心的进程可以对所述数据进行读取。
[0060]需要说明的是,同一核心的多个不同线程对同一数据进行读操作的过程,可以以同一私有计数器执行加读锁、解读锁操作。例如,在核心I的线程I对该数据进行读取过程中,首先进行加读锁。核心I的私有引用计数read_ref_corel执行加I操作。这样,read_ref_corei由初始值O变为I。之后,核心I的线程I对该数据进行读取。在核心I的线程I对该数据进行读取的过程中,核心I的线程2也要对同一数据执行读操作,则将read_ref_corel的值加1,并对该数据进行读取。则此时read_ref的值为2。核心I的线
当前第2页1 2 3 4 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1