架构差异
在代码移植过程中,我们需要格外注意不同架构之间的内存序模型的差异。
简要总结x86和ARM之间的内存序差异,如表1所示:
内存乱序行为 |
x86 |
ARM |
---|---|---|
读-读乱序 |
不允许 |
允许 |
读-写乱序 |
不允许 |
允许 |
写-读乱序 |
允许 |
允许 |
写-写乱序 |
不允许 |
允许 |
原子操作-读写乱序 |
不允许 |
允许 |
表1内容中主要指的是大部分情况下的单次内存访问行为。
批量内存访问行为,如x86中的字符串处理指令、非易失内存编程指令等不在其讨论范围内。
简单说明一下表1中内存乱序行为的含义。
以写-读乱序为例,假设在程序中连续访问两个全局变量,执行的操作序列是先写一个值到全局变量,再读取另一个全局变量的值,如下所示:
CPU 0 |
CPU 1 |
---|---|
x = 1 r1 = y |
y = 1 r2 = x |
初始值:x = 0且y = 0 |
由表1可知,在x86和ARM架构中都存在写-读乱序行为。故其实际执行序列可能如下所示:
CPU 0 |
CPU 1 |
---|---|
r1 = y x = 1 |
r2 = x y = 1; |
初始值:x = 0 且 y = 0 |
所以最终的执行结果有可能是r1 = 0且r2 = 0。
总的来说,x86架构下的内存序要比ARM下严格得多,大部分情况下的内存访问都是定序的,如果不加修改的将多线程程序移植到ARM架构下,就可能会出现功能问题。
父主题: 内存屏障