- 论坛徽章:
- 0
|
原帖由 iterator 于 2008-5-23 21:07 发表 ![]()
惭愧地说,其实你举了这个例子后,我就更加不懂了.
可能是因为刚接触这个概念,整个弄糊涂了.
能简单讲讲么.多谢了
当然,我也是不太懂的,但大概原理还是可以说说。
乱序,并非是全乱执行,它只是对于没有依赖性的指令乱序执行。
在我上面举的这个例子中,a=i就不会在i++之前执行,因为两条指令之间有依赖,称为WAW依赖(write after write )。同样,还有RAW、WAR依赖。
所以preempt_disable中对抢占计数器加是个安全的操作,和这个计数器有关联的指令不会被乱序执行,只需要防止编译器把相关指令提前即可,用barrier足够。
那么什么时候要防止乱序呢?通常在一个块内存,既对CPU可见,又对设备可见时。举个例子:
一个结构体
- struct dev
- {
- int enable;
- void *ptr;
- }dev;
复制代码
这个结构体所处的内存,设备和CPU都可以看到。正确操作设备的顺序是先给ptr指针赋值,在对enable写1启用设备。那么,下面的代码反应了这个过程:
- dev.ptr = buffer;
- dev.enable = 1;
复制代码
这里的两个写操作是没有相关性的。所以CPU可以乱序执行它们。这就造成了一个情况,ptr还没赋值之前,enable就已经写1了。那么设备可能在ptr为非法值时启动执行。我们要防止这种情况,就要用内存屏障。如下:
- dev.ptr = buffer;
- wmb();
- dev.enable = 1;
复制代码
大概的原理就是这样。 |
|