mfence和asm volatile的差异(“”:“:”,“memory”) [英] difference in mfence and asm volatile ("" : : : "memory")

查看:560
本文介绍了mfence和asm volatile的差异(“”:“:”,“memory”)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知, mfence 是一个硬件内存障碍,而 asm volatile(:::memory)是编译器障碍。但是,可以使用 asm volatile(:::memory)来代替保护。

我感到困惑的原因是这个链接


<解决方案

x86和x64没有弱内存排序。在x86 / x64上,所有商店都有一个发布栏,所有负载都有一个收购栏。所以,你应该只需要 asm volatile(::memory)



英特尔和AMD的概述以及参考相关制造商的规格,请参阅 http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/



一般诸如易失性之类的东西在每个字段的基础上使用,其中对该字段的加载和存储本质上是原子的。在加载和存储到某个字段时已经是原子的(即所讨论的操作是一个加载或存储到一个字段,因此整个操作是原子的) volatile x86 / x64上不需要字段修饰符或内存屏障。便携式代码尽管如此。



当涉及到非原子的操作时 - 例如,加载或存储到大于本地字的字段,或加载或存储到操作中的多个字段 - 无论CPU如何,都可以将操作视为 atomic 的方式建筑。通常这是通过像互斥体这样的同步原语完成的。 Mutexes(我用过的)包含内存屏障以避免处理器重新排序等问题,因此您不必添加额外的内存屏障指令。我通常认为不使用同步原语是一种过早的优化;但是,过早优化的性质当然是97%的时间:)

在不使用同步原语的情况下,您正在处理多场不变,确保处理器不重新排序存储和加载到不同存储位置的内存屏障是非常重要的。

现在,就不发布mfence指令在asm易变但在clobber列表中使用内存。从我已经能够阅读


如果您的汇编程序指令以不可预知的方式访问内存,请将内存添加到破坏寄存器列表中。这会导致GCC不将内存值保存在汇编指令的寄存器中,也不会优化存储或加载到该内存。

当他们说GCC,并没有提到有关CPU的任何信息,这意味着它仅适用于编译器。缺少mfence意味着没有CPU内存屏障。您可以通过反汇编生成的二进制文件来验证。如果没有发出mfence指令(取决于目标平台),那么很明显CPU不会被告知发出内存围栏。



根据您的平台, 你还在做什么,你想做什么,或许有什么更好或更清晰......可移植性不足。


As far as I have understood, mfence is a hardware memory barrier while asm volatile ("" : : : "memory") is a compiler barrier. But,can asm volatile ("" : : : "memory") be used in place of mfence.

The reason I have got confused is this link

解决方案

Well, a memory barrier is only needed on architectures that have weak memory ordering. x86 and x64 don't have weak memory ordering. on x86/x64 all stores have a release fence and all loads have an acquire fence. so, you should only really need asm volatile ("" : : : "memory")

For a good overview of both Intel and AMD as well as references to the relavent manufacturer specs, see http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/

Generally things like "volatile" are used on a per-field basis where loads and stores to that field are natively atomic. Where loads and stores to a field are already atomic (i.e. the "operation" in question is a load or a store to a single field and thus the entire operation is atomic) the volatile field modifier or memory barriers are not needed on x86/x64. Portable code notwithstanding.

When it comes to "operations" that are not atomic--e.g. loads or stores to a field that is larger than a native word or loads or stores to multiple fields within an "operation"--a means by which the operation can be viewed as atomic are required regardless of CPU architecture. generally this is done by means of a synchronization primitive like a mutex. Mutexes (the ones I've used) include memory barriers to avoid issues like processor reordering so you don't have to add extra memory barrier instructions. I generally consider not using synchronization primitives a premature optimization; but, the nature of premature optimization is, of course, 97% of the time :)

Where you don't use a synchronization primitive and you're dealing with a multi-field invariant, memory barriers that ensure the processor does not reorder stores and loads to different memory locations is important.

Now, in terms of not issuing an "mfence" instruction in asm volatile but using "memory" in the clobber list. From what I've been able to read

If your assembler instructions access memory in an unpredictable fashion, add `memory' to the list of clobbered registers. This will cause GCC to not keep memory values cached in registers across the assembler instruction and not optimize stores or loads to that memory.

When they say "GCC" and don't mention anything about the CPU, this means it applies to only the compiler. The lack of "mfence" means there is no CPU memory barrier. You can verify this by disassembling the resulting binary. If no "mfence" instruction is issued (depending on the target platform) then it's clear the CPU is not being told to issue a memory fence.

Depending on the platform you're on and what you're trying to do, there maybe something "better" or more clear... portability not withstanding.

这篇关于mfence和asm volatile的差异(“”:“:”,“memory”)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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