内存屏障和锁 从X86往ARM平台移植

1.内存屏障

ARM架构下,不需要使用内存屏障的几个典型场景:

1)存在地址依赖时,不需要显示使用内存屏障,也可以保证内存一致性

LDR X1,[X2]

AND X1, X1, XZR

LDR X4, [X3, X1]

第三行的汇编语句从内存地址 [X3, X1]读数据到寄存器X4时,需要依赖X1从地址[X2]中读到的值,所以这种情况下LDR

X1,[X2]先于LDR X4, [X3, X1]执行。

2)存在控制依赖时,不需要显示使用内存屏障,也可以保证内存一致性

r1 = x;

if (r1 == 0) nop();

y = 1;

如果一个条件分支依赖于一个加载操作,那么在条件分支后面的存储操作都在加载操作后执行,所以“r1

= x;”先于“y = 1;”执行

3)存在寄存器数据依赖时,不需要显示使用内存屏障,也可以保证内存一致性

LDR X1,[X2]

AND X3, X3, X1

SUB X3, X3, X1

STR X4, [X3]

执行最后的STR指令时依赖于X3寄存器中存放的内存地址,而X3寄存器的值又依赖于从X2内存地址中获取到数据X1寄存器的值;这些寄存器之间存在数据依赖,所以“LDR

X1,[X2]”先于“STR X4, [X3]”执行。

x86和arm架构之间的内存序差异

内存乱序行为          x86      arm

读-读乱序              不允许  允许

读-写乱序              不允许  允许

写-读乱序              允许    允许

写-写乱序              不允许  允许

原子操作-读写乱序      不允许  允许

说明:该表内容中主要指大部分情况下的单词内存访问行为,如x86中的字符串处理指令、非易失内存编程指令等批量内存访问行为不在讨论范围内。

以写-读乱序为例,假设在程序中连续访问2个全局变量a和b

初始的内存操作为:

cpu0:

x = 1;

r1 = y;

cpu1:

y = 1;

r2 = x;

初始值:x = y = 0;

由于x86和arm架构都存在写-读乱序行为。故其实际执行序列可能如下所示:

cpu0:

r1 = y;

x = 1;

cpu1:

r2 = x;

y = 1;

所以最终的执行结果可能是r1 = r2 = 0;

总的来说,x86架构下的内存序要比arm下严格,大部分情况下的内存访问都是定序的,如果不加修改的将多线程程序移植到arm架构下,就可能出现功能问题。

1.3 代码移植注意事项:

1.3.1 cpu内存屏障指令移植:

 略

ARM架构的几种屏障指令的区别:

isb -- 流水线全部刷掉,让后面的指令,重新去取指令

dsb -- 保证dsb指令之前的指令全部执行完了之后,后面的指令执行;没有刷流水线

dmb -- 为了保序

1.3.2 编译器屏障移植:

程序编译时,特别是加入了优化选项-O2/O3后,编译器可能将代码打乱顺序执行,即编译生成后的汇编代码的执行顺序可能与原始的高级语言代码中的执行顺序不一致。所以编译器提供了编译阶段的内存屏障,用于指导编译器及时刷新寄存器的值到内存中,保证该编译器屏障前后的内存访问指令在编译后是定序排布的。

常见的编译型屏障定义如下:

#define barrier() __asm__ __volatile__("":::"memory")

x86属于强内存序架构,大部分情况使用编译型屏障就可以保证多线程内存访问的一致性。但是在arm下无法做到这一点。

在x86架构下,读屏障和写屏障的宏smp_rmb()和smp_wmb()都设置成了编译器内存屏障,而在arm架构下则都设置成了cpu指令级内存屏障,从这里可以看出2个架构之间的差异。所以我们需要将源代码中的编译型屏障改写成cpu级内存屏障。

1.3.3 尽可能使用acquire和release语义进行同步

armv8增加了load-acquire(LDLARB,LDLARH和LDLAR)和store-release(STLLRB,STLLRH和STLLR)指令,这可以直接支持C++原子库中的相关语义。这些指令可以理解成半屏障。这些半屏障指令的执行效率要比全屏障更高,所以在能够使用这些类型的屏障时,我们尽可能acquire和release语义来做线程间的同步。

read-acquire用于修饰内存读取指令,一条read-acquire读指令会禁止它后面的内存操作指令被提前执行,即后续内存操作执行重排时无法向上越过屏障。

write-release用于修饰内存写指令,一条write-release的写指令会禁止它上面的内存操作指令被滞后到写操作完成后才执行,即写指令之前的内存操作指令重排时不会向下越过屏障。


2. 锁的移植

2.1 架构差异

2.1.1 指令集差异

2.1.2 内存序差异

2.2 注意处理器差异

除了架构差异外,在锁的移植过程中还需要注意处理器的差异。

x86架构下大部分处理器的l3 cacheline大小一般为64byte,而kp920芯片的l3 cache line大小为128byte,所以在设计锁时要格外注意,尽量避免多线程相互独立修改的变量共享同一个cacheline的情况出现,即通常所说的“伪共享”现象--这对性能有较大影响。




什么是伪共享?

缓存系统是以cache line为单位存储的。最长见的缓存大小是64个字节。当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。cache line的写竞争是运行在SMP系统中并行线程实现可伸缩性最重要的限制因素。

2个线程写同一个变量可以在代码中发现。为了确定互相独立的变量是否共享了同一个cache line,就需要了解内存布局,可以使用intel VTune分析工具。

分析工具

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343