对多核共享变量的读写操作

在PC处理器中,往往没有像嵌入式系统那样含有一块多核共享的高速缓存(一般是SRAM)。也就是说我们在PC处理器的多核共享变量都是统一被映射到内存(DDR)中去的。那么这就会导致一系列的问题。

首先,由于每个核都有自己的独立的L1 Cache(包括数据和指令),而多个核共享一个L2 Cache,以及更高层级的Cache。那么在某一个核中对一个多核共享变量做读写操作的话,若采用一般指令进行写,那么这变量的值仅仅会在那个核的L1 Cache中折腾,而可能不会影响到存储器中的那个真正的对象。

然后,这也会导致在某一个核中,你每次对该共享变量进行读操作时,其值可能不是最新的,即,在你刚读好这个变量时它可能已经被其它核给修改了。

因此,这得出一个结论:你不能用普通的写操作来修改多核共享变量;在你读多核共享变量前必须确保其它核没有再次修改它。

 

我们对多核共享变量进行修改时,会采取具有锁总线特性的指令。在x86中有:xchg、cmpxchg等,除此以外还有带有LOCK前缀的基本算术运算操作。在Blackfin561 Dual-Core DSP中,可以使用testset指令;ARMv7以前的处理器可以用SWP和SWPB,在ARMv7架构中加入了更强大的LDREX和STREX对,形成LL-SC作为原子操作指令对。

 

因此,如果我们将多核共享变量作为同步锁的话,那么用SWAP、TEST AND SET等指令对其进行读、写同时操作,并且加锁总线。如果我们在操作一个多核共享的数据结构,那么我们在操作前应该上锁,然后每次对必要结果的修改应该用上述带有锁总线的指令进行操作。还有一种是用普通的写指令将结果写到Cache后,然后再无效化当前核的整个Cache。但是这个做法也很耗时间,而且原本已经进Cache的数据也都被清空了。

当然,在很多时候,我们为了图个方便,会把相同的数据结构赋值多份给每个核,呵呵。虽然这样会比较浪费空间,但也是一种手段。

下面给各位看一下加锁总线和没有锁总线的执行区别:

上述代码,使用LLVM1.5,GNU99编译选项编译 

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值