- 论坛徽章:
- 1
|
本帖最后由 arm-linux-gcc 于 2013-04-19 10:10 编辑
回复 1# zylthinking
对屏障我没什么研究,但是我觉得LZ的问题应该从汇编指令这个层次上来探讨这个问题
a = 1; //这条C代码语句并不是一条汇编指令就能够完成的
arm里面对一个变量赋值,是需要先从内存装载到通用寄存器,计算完之后在填回内存
所以a = 1;这种代码,汇编应该是:
ldr r0, #1 //把立即数1填到r0
str r0, [变量a的地址] //把r0中的内容填到变量a的地址去(可能是填进了内存,也可能是填进了cache,后面的讨论就假设是读写的cache)
我说明一下我的理解
把LZ代码简化一下
thread a(core 0) thread b(core 1)
y = 1; if (x == 2)
x = 2; z = y;
else
z = 0;
由于乱序,假如线程a中的两句颠倒了,在两个核中的实际运行情况如下
thread a(core 0) thread b(core 1)
x = 2; if (x == 2)
y = 1; z = y;
else
z = 0;
把实际运行情况(线程a中的两句由于乱序发生了颠倒)展开成汇编
cycle core 0 core 1
--------------------------------------------------------------------------------------
0 ldr r0, #2 ......
1 str r0, [变量x的地址] ...... //这里把r0写入cache,要注意这句执行完以后,cache中x的值才会为2,
//也就是说core 1必须在下一个周期去取,得到的才会是2
2 ldr r1, #1 ldr r0, [变量x的地址] //假如这一句在cycle 2这个时刻之前执行了,那么后面的判断必然不成立
3 str r1, [变量y的地址] cmp r0, #2 //比较变量x是不是等于2
4 ...... bne balabalabala //如果不等则跳到后面balabalabala处,如果相等则不跳转(继续执行紧接着的后面的一条指令)
5 ...... ldr r1, [变量y的地址] //对比core 0中的情况,在core 1这里取y值时,core 0早就把y值写到cache了
6 ...... str r1, [变量z的地址]
balabalabala
所以这种情况不加屏障也是没有问题的,但是使用mutex仍然更保险一下
不知道能否解释LZ提出的问题
|
|