尽可能使用acquire和release语义进行同步
相比ARMv7,ARMv8增加了load-acquire(LDLARB,LDLARH和LDLAR)和store-release(STLLRB,STLLRH和STLLR)指令,这可以直接支持C++原子库中的相关语义。这些指令可以理解成半屏障。这些半屏障指令的执行效率要比全屏障更高,所以在能够使用这种类型的屏障时,我们尽可能acquire和release语义来做线程间的同步。
Read-Acquire用于修饰内存读取指令,一条read-acquire的读指令会禁止它后面的内存操作指令被提前执行,即后续内存操作指令重排时无法向上越过屏障。
Write-Release用于修饰内存写指令,一条write-release的写指令会禁止它上面的内存操作指令被乱序到写指令完成后才执行,即写指令之前的内存操作指令重排时不会向下越过屏障。
所以,为进一步提高性能,我们可以将编译器屏障移植中首例的代码改写成如下所示:
thread0(void) { data = 1; barrier(); __atomic_store_n (&flag, 1, __ATOMIC_RELEASE); } thread1(void) { if (__atomic_load_n (&flag, __ATOMIC_ACQUIRE) != 1) return; assert(data == 1); }
父主题: 代码移植注意事项