确定使用障碍物(栅栏)的位置 [英] Determining the location for the usage of barriers (fences)

查看:307
本文介绍了确定使用障碍物(栅栏)的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

x86指令lfence / sfence / mfence用于在Linux内核中实现rmb()/ wmb()/ mb()机制。很容易理解,这些用于序列化存储器访问。但是,在编写代码时,在遇到运行时行为中的错误之前,确定在何时何地使用这些代码要困难得多。

The x86 instructions lfence/sfence/mfence are used to implement the rmb()/wmb()/mb() mechanisms in the Linux kernel. It is easy to understand that these are used to serialize the memory accesses. However, it is much more difficult to determine when and where to use these while writing the code -- before encountering the bug in the runtime behavior.

我有兴趣知道如果有已知的警告,可以检查,在编写/审查代码,这可以帮助我们确定障碍必须插入的位置。我理解这是一个太复杂,但是有一个经验法则或一个清单,可以帮助我们识别需要这些代码的地方。

I was interested to know if there are known caveats that could be checked, while writing/reviewing the code, that can help us determine where the barriers must be inserted. I understand this is a too complex, but is there a rule-of-thumb or a checklist that can help us identify the code-places where these are needed?

推荐答案

我的经验(不是在Linux内核)是两个模式覆盖了绝大部分的屏障需要。

My experience (not in the Linux kernel) is that two patterns cover the vast majority of the need for fencing.

模式发送/接收:线程1向线程2发送数据,并且有一个内存位置, 。线程1需要在数据存储和存储之间至少有一个数据就绪。线程2需要在数据已准备就绪的数据加载和数据加载之间有一个lfence。

Pattern "Send/receive": Thread 1 sends data to thread 2, and there is a memory location that somehow indicates "data is ready". Thread 1 needs at least an sfence between the store of the data and the store into "data is ready". Thread 2 needs an lfence between the load of the data that says "data is ready" and the load of the data.

如果只有常规的设备等)加载/存储涉及传输,则只需要编译器栅栏。此外,LOCK前缀指令暗示栅栏。例如,有时数据就绪位置不仅仅是标志,而是原子计数器,并且用于操纵它的LOCK前缀增量/减量可以用作栅栏。

If only regular (NOT non-temporal, DMA devices etc.) load/stores are involved in the transfer, then only compiler fences are necessary. Also, LOCK-prefixed instructions imply fences. For example, sometimes the "data is ready" location is not simply a flag, but an atomic counter, and the LOCK-prefixed increment/decrement used to manipulate it can serve as the fence.

此模式还包括自旋锁。释放锁是一个发送。

This pattern also covers spin locks. Releasing a lock is a "send". Acquiring a lock is " receive.

模式共识:两个线程必须达成共识关于某事,必须有一个mfence围栏必须在我发表我的投票和我读了另一个线程的投票之间。 Dekker的协议是一个例子,困难的部分是发现这种模式我们曾经错过了TBB的内部之一,其中共识问题是一个异常被抛出了?最终我们意识到这是一个共识的问题,因此需要一个mfence。

Pattern "Consensus": Two threads have to reach consensus about something. There must be an mfence (or one implied by a LOCK-prefixed instruction). The fence must be between the "I published my vote" and "I read the other thread's vote". Dekker's protocol is an example. The hard part is spotting this pattern. We once missed one deep in the internals of TBB where the consensus problem was "has an exception been thrown?" Eventually we realized that it was a consensus problem and consequently needed an mfence.

上面的两个模式是经验法则,不包括所有情况,但我发现他们涵盖了99%的病例。

The two patterns above are rules of thumb that do not cover all cases, but I find that they cover 99% of cases.

这篇关于确定使用障碍物(栅栏)的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆