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

时间:2013-09-30 11:30:48

标签: c++11 x86 sse c11 memory-barriers

我们从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 instructions ... is no requirement on backwards compatibility and memory order is undefined"。据信,当需要时,严格的可订购性与旧版本的处理器x86兼容,但是新的命令,即SSE([NT]除外) - 被剥夺了自动释放 - 获取订单,是吗?

2 个答案:

答案 0 :(得分:8)

以下摘自Intel's Software Developers Manual, volume 3,第8.2.2节(2014年9月版325384-052US):

  
      
  • 读取不会与其他读取重新排序。
  •   
  • 写入不会与较旧的读取重新排序。
  •   
  • 写入内存不会与其他写入重新排序,但以下情况除外:   
        
    • 使用CLFLUSH指令执行写入;
    •   
    • 使用非时间移动指令(MOVNTI,MOVNTQ,MOVNTDQ,MOVNTPS和MOVNTPD)执行的流存储(写入);和
    •   
    • 字符串操作(参见第8.2.4.1节)。
    •   
  •   
  • 可以使用较旧的写入对不同位置进行重新排序,但不能将较旧的写入重新排序到同一位置。
  •   
  • 读取或写入不能使用I / O指令,锁定指令或序列化指令重新排序。
  •   
  • 读取不能通过早期的LFENCE和MFENCE指令。
  •   
  • 写入不能通过早期的LFENCE,SFENCE和MFENCE指令。
  •   
  • LFENCE指令无法通过早期读取。
  •   
  • SFENCE指令无法通过更早的写入。
  •   
  • MFENCE指令无法通过早期的读取或写入。
  •   

前三个项目符号描述了发布 - 获取顺序,并且在那里明确列出了例外。正如您所看到的,只有可缓存性控制指令(MOVNT*)在异常列表中,而SSE / SSE2和其他向量指令的其余部分遵循一般的内存排序规则,并且不需要使用{{1 }}

答案 1 :(得分:2)

正常的 1 SSE加载和存储指令以及使用内存源操作数时的隐含负载确实具有相同的获取版本 排序的行为,作为GP寄存器的正常加载和存储。

它们,但通常直接用于对大于8字节的std::memory_order_acquire个对象执行std::memory_order_releasestd::atomic操作,因为{{3}对于大于8字节的SSE或AVX加载和存储。缺失的保证不仅仅是理论上的:有几种实现(包括像AMD的Ryzen这样的全新实现)将大量负载或存储分成两个较小的负载。

1 即,未在接受答案的例外列表中列出的那些:NT存储,clflush和字符串操作。