linux内核中内存障碍的目的

时间:2015-06-18 11:44:38

标签: linux linux-kernel embedded-linux

Robert Love说" set_task_state(task,state)将给定任务设置为给定状态。如果适用,它还提供内存屏障以强制在其他处理器上进行排序(这仅在SMP系统上需要)否则它相当于 task-> state = state

我的问题是: 内存屏障如何强制在其他处理器上进行排序?

罗伯特的爱意味着什么 - 为什么需要这个? 他可能会谈论这个顺序是什么?他在这里谈论调度队列吗?

如果是这样,SMP中的每个处理器都有不同的调度队列吗? 我很困惑

2 个答案:

答案 0 :(得分:2)

为了挤出额外的性能,你的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将以旧状态运行,如果随后清除已更改,则CPU1刚刚进行的更改将丢失。

屏障告诉系统,在某些时候,在1到2之间,它必须使事情保持一致才能继续前进。

搜索内存障碍',您会找到一些好帖子:Memory Barriers Are Like Source Control Operations

答案 1 :(得分:1)

内存障碍是必需的,因为当前的CPU执行大量乱序执行:如果它们之间没有依赖关系,它们一次加载许多指令并以非确定性顺序执行它们。

为了避免由于编译器优化而重新排序,volatile关键字就足够了(在这里谈到C ++)。因此,同步原语(例如lock)通过正确使用volatile和某种汇编程序fence指令来实现(其中有许多指令,或多或少强大:见7.5节)。 5 {in http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html

你知道锁是什么吗?

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可能会等同于21