Robert Love说:"set_task_state ( task,state)将给定的任务设置为给定的状态。如果适用,它还提供了一个内存屏障,以便在其他处理器上强制排序(这只在SMP系统上是需要的),否则它等同于task->state = state
我的问题是:内存屏障如何在其他处理器上强制排序?
罗伯特洛夫这样说是什么意思--为什么这是必需的?他可能在说的这个顺序是什么?他是在说这里的调度队列吗?
如果是这样,SMP中的每个处理器是否都有不同的调度队列?我很困惑
发布于 2015-06-18 20:22:18
为了挤出额外的性能,您的CPU执行Out of Order Execution,它可以以不同于代码中给定的顺序运行操作。优化编译器可以改变操作的顺序,使代码更快。编译器编写者/内核类型必须注意不要改变期望(或者至少符合规范,这样他们就可以说你的期望是不正确的)
下面是一个例子
1: CPU1: task->state = someModifiedStuff
2: CPU1: changed = 1;
3: CPU2: if (changed)
4: CPU2: ...如果我们没有设置状态的障碍,我们可以重新排序1和2。因为两者都不引用另一个,所以单线程实现不会看到任何差异。但是,在SMP情况下,我们重新排序1和2行3可以看到更改,但不会看到状态更改。例如,如果CPU1运行第2行(而不是第1行),然后CPU2运行第3行和第4行,则CPU2将以旧状态运行,如果它随后清除了change,则CPU1刚才所做的更改将丢失。
障碍告诉系统,在某个点上,在1和2之间,它必须使事情保持一致,然后才能继续。
在“记忆屏障”上搜索一下,你会找到一些不错的帖子:Memory Barriers Are Like Source Control Operations
发布于 2015-06-18 21:01:13
内存屏障是必需的,因为当前的CPU执行大量无序执行:它们一次加载许多指令,并以不确定的顺序执行它们,如果它们之间没有依赖关系的话。
为了避免由于编译器优化而导致的重新排序,volatile关键字就足够了(这里指的是C++ )。因此,同步原语(例如lock)是通过正确使用volatile和某种汇编fence指令来实现的(它们有很多,或多或少很强大:参见http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html中的7.5.5节)
你知道锁是什么吗?
x = 0;
thread 1: thread 2:
a.lock(); a.lock();
x++; x++;
a.unlock(); a.unlock();x将导致正确的2。现在假设在这两个线程的指令的执行顺序中没有保证。如果执行的指令是(a和x是独立的,所以如果lock()没有正确地实现内存屏障,那么将允许无序执行):
x = 0;
thread 1: thread 2:
x++; x++;
a.lock(); a.lock();
a.unlock(); a.unlock();x可能会导致等于2或1。
https://stackoverflow.com/questions/30914442
复制相似问题