相关疑难解决方法(0)

什么时候需要x86 LFENCE,SFENCE和MFENCE指令?

好吧,我已经从SO关于x86处理器围栏阅读下列适量(LFENCE,SFENCEMFENCE):

和:

而且我必须说实话,我还不能确定何时需要围栏.我试图从删除完全锁定并尝试通过栅栏使用更细粒度的锁定的角度来理解,以最小化延迟延迟.

首先,这是我不明白的两个具体问题:

有时在进行存储时,CPU会写入其存储缓冲区而不是L1缓存.但是,我不了解CPU执行此操作的条款?

CPU2可能希望加载已写入CPU1的存储缓冲区的值.据我了解,问题是CPU2无法在CPU1的存储缓冲区中看到新值.为什么MESI协议不能将刷新存储缓冲区作为其协议的一部分?

更一般地,可以请人试图描述的总体方案,并帮助时解释LFENCE/ MFENCESFENCE被需要的指令?

NB阅读本主题的一个问题是,当我只对Intel x86-64架构感兴趣时,"通常"为多CPU架构编写的文章数量.

cpu x86 assembly multithreading memory-fences

40
推荐指数
1
解决办法
2万
查看次数

英特尔内存模型是否使SFENCE和LFENCE冗余?

英特尔内存模型保证:

  • 商店不会与其他商店重新订购
  • 载荷不会与其他载荷重新订购

http://bartoszmilewski.com/2008/11/05/who-ordered-memory-fences-on-an-x86/

我已经看到声称由于Intel内存模型,SFENCE在x86-64上是多余的,但从来没有LFENCE.上述内存模型规则是否使指令冗余?

optimization x86 assembly atomic memory-barriers

15
推荐指数
1
解决办法
1355
查看次数

GCC对读/写指令的重新排序

Linux的同步原语(自旋锁,互斥锁,RCU)使用内存屏障指令强制重新排序内存访问指令.这种重新排序可以由CPU本身或编译器完成.

有人可以展示一些GCC生成的代码示例吗?我主要对x86感兴趣.我之所以问这个问题,是为了理解GCC如何决定可以重新排序的指令.不同的x86 mirco架构(例如:沙桥与常春藤桥)使用不同的缓存架构.因此,我想知道GCC如何进行有效的重新排序,无论缓存架构如何,都有助于执行性能.一些示例C代码和重新排序的GCC生成的代码将非常有用.谢谢!

memory cpu gcc linux-kernel compiler-optimization

13
推荐指数
2
解决办法
5830
查看次数

原子操作,std :: atomic <>和写入顺序

GCC汇编了这个:

#include <atomic>
std::atomic<int> a; 
int b(0);

void func()
{
  b = 2; 
  a = 1;
}
Run Code Online (Sandbox Code Playgroud)

对此:

func():
    mov DWORD PTR b[rip], 2
    mov DWORD PTR a[rip], 1
    mfence
    ret
Run Code Online (Sandbox Code Playgroud)

所以,为我澄清一些事情:

  • 读取'a'的任何其他线程是否保证将'b'读为2.
  • 为什么MFENCE在写入"a"之后才发生.
  • 无论如何,对"a"的写入保证是原子(在狭窄的非C++意义上)操作,这是否适用于所有英特尔处理器?我假设这个输出代码.

另外,clang(v3.5.1 -O3)这样做:

mov dword ptr [rip + b], 2
mov eax, 1
xchg    dword ptr [rip + a], eax
ret
Run Code Online (Sandbox Code Playgroud)

这似乎对我的小脑子更直接,但为什么不同的方法,每个方法的优势是什么?

c++ compiler-construction x86 assembly

11
推荐指数
1
解决办法
2267
查看次数

x86-SSE指令是否具有自动发布 - 获取订单?

正如我们从C11-memory_order所知道的那样:http://en.cppreference.com/w/c/atomic/memory_order

从C++ 11-std :: memory_order开始:http://en.cppreference.com/w/cpp/atomic/memory_order

在强排序系统(x86,SPARC,IBM大型机)上, 发布 - 获取顺序是自动的.没有为此同步模式发出额外的CPU指令,只会影响某些编译器优化(例如,禁止编译器在原子存储释放之前移动非原子存储或在原子载荷获取之前执行非原子加载)

但这对于x86-SSE指令是否正确(除了[NT] - 非时间,我们总是必须使用L/S/MFENCE)?

这里说,"sse指令......不要求向后兼容性,并且内存顺序未定义".据信,当需要时,严格的可订购性与旧版本的处理器x86兼容,但是新的命令,即SSE(除了[NT]) - 被剥夺了自动释放 - 获取订单,是吗?

x86 sse memory-barriers c++11 c11

8
推荐指数
1
解决办法
799
查看次数

`std :: memory_order_acquire`的语义是否需要x86/x86_64上的处理器指令?

众所周知,在x86上,操作load()store()内存屏障memory_order_consume, memory_order_acquire, memory_order_release, memory_order_acq_rel不需要处理器指令用于缓存和管道,并且汇编程序的代码总是对应std::memory_order_relaxed,并且这些限制仅对编译器的优化是必需的:http:// www. stdthread.co.uk/forum/index.php?topic=72.0

此代码反汇编代码确认store()(MSVS2012 x86_64):

std::atomic<int> a;
    a.store(0, std::memory_order_relaxed);
000000013F931A0D  mov         dword ptr [a],0  
    a.store(1, std::memory_order_release);
000000013F931A15  mov         dword ptr [a],1  
Run Code Online (Sandbox Code Playgroud)

但是这段代码并没有为load()(MSVS2012 x86_64)确认这一点,使用lock cmpxchg:

    int val = a.load(std::memory_order_acquire);
000000013F931A1D  prefetchw   [a]  
000000013F931A22  mov         eax,dword ptr [a]  
000000013F931A26  mov         edx,eax  
000000013F931A28  lock cmpxchg dword ptr [a],edx  
000000013F931A2E  jne         main+36h (013F931A26h)  

    std::cout << val << "\n";
Run Code Online (Sandbox Code Playgroud)

安东尼威廉姆斯说 …

c++ concurrency x86 memory-barriers c++11

7
推荐指数
1
解决办法
1034
查看次数

为什么(或不是?)SFENCE + LFENCE相当于MFENCE?

正如我们从之前的回答中所知道的,它是否在处理器x86/x86_64中指示LFENCE?我们不能使用SFENCE而不是MFENCE顺序一致性.

这里的答案表明MFENCE= SFENCE+ LFENCE,即LFENCE没有我们不能提供顺序一致性的东西.

LFENCE 无法重新排序:

SFENCE
LFENCE
MOV reg, [addr]
Run Code Online (Sandbox Code Playgroud)

- 到 - >

MOV reg, [addr]
SFENCE
LFENCE
Run Code Online (Sandbox Code Playgroud)

例如重新排序MOV [addr], reg LFENCE- > LFENCE MOV [addr], reg机制提供- 存储缓冲区,它重新排序存储 - 负载以提高性能,并且因为LFENCE它不会阻止它.并SFENCE 禁用此机制.

什么机制禁用LFENCE无法重新排序(x86没有机制 - Invalidate-Queue)?

并且只是在理论上或者在现实中重新排序SFENCE MOV reg, [addr]- > MOV reg, [addr] SFENCE可能吗?如果可能,实际上,什么机制,它是如何工作的?

x86 assembly x86-64 memory-fences memory-barriers

5
推荐指数
3
解决办法
1091
查看次数