Intel 64和IA-32 |原子操作包括获取/释放语义

时间:2011-01-27 06:14:45

标签: assembly locking x86 intel memory-fences

根据英特尔64和IA-32架构软件开发人员手册,LOCK信号前缀“确保处理器在声明信号时独占使用任何共享内存”。这可以是总线或缓存锁的形式。

但是 - 这就是我提出这个问题的原因 - 我不清楚,如果这个前缀也提供了任何内存屏障。

我正在多处理器环境中使用NASM进行开发,并且需要使用可选的获取和/或发布语义来实现原子操作。

那么,我是否需要使用MFENCE,SFENCE和LFENCE指令,或者这是多余的?

3 个答案:

答案 0 :(得分:7)

不,不需要使用与MFENCE, SFENCE and LFENCE前缀相关的说明LOCK

MFENCE, SFENCE and LFENCE指令保证所有CPU内核的内存可见性。例如,MOV指令不能与LOCK前缀一起使用,因此为了确保所有CPU内核都可以看到内存移动的结果,我们必须确保将CPU缓存刷新到RAM并且我们通过围栏指示到达。

编辑:有关英特尔手册锁定原子操作的更多信息:

  

锁定的原子操作

     

32位   IA-32处理器支持锁定原子   对系统中的位置的操作   记忆。通常这些操作   用于管理共享数据结构   (如信号量,段   描述符,系统段或页面   表)其中两个或更多   处理器可以同时尝试   修改相同的字段或标志。该   处理器使用三个相互依赖   执行锁定的机制   原子操作:

     

•保证原子操作

     

•使用LOCK#信号和LOCK指令前缀

进行总线锁定      

•缓存一致性协议,确保可以在缓存的数据结构上执行原子操作(缓存锁定);这种机制存在于Pentium 4,Intel Xeon和P6系列处理器中

     

这些机制是相互依存的   以下方式。一定的基础   记忆交易(如阅读   或在系统内存中写入一个字节)   始终保证得到处理   原子。也就是说,一旦开始,   处理器保证   操作将在之前完成   另一个处理器或总线代理是   允许访问内存位置。   处理器还支持总线   锁定以执行所选内存   操作(例如   读取 - 修改 - 写入操作   共享的内存区域)通常   需要原子地处理,但是   不会自动处理这种方式。   因为经常使用内存   位置通常缓存在   处理器的L1或L2缓存,原子   通常可以进行操作   在处理器的缓存中没有   断言总线锁定。在这里   处理器的缓存一致性协议   确保其他处理器   缓存相同的内存位置   原子管理得当   操作在缓存上执行   记忆位置。

答案 1 :(得分:4)

否。来自IA32手册(第3A卷,第8.2章:内存订购):

  

读取或写入无法通过I / O指令重新排序,已锁定   说明,或序列化说明。

因此,锁定指令不需要使用fence指令。

答案 2 :(得分:-1)

编译intel_lock1.c(在上面的URL中可用)时仍会出现问题 在没有args'-D_WITH_CLFLUSH_'的情况下使用GCC 5或7的linux上 '-D_WITH_HLE_'(因此既不使用CLFLUSH *也不使用HLE XACQUIRE) - mutex_lock汇编程序现在看起来像:

# 74 "intel_lock1.c" 1
    LFENCE
    lock subl   $1, lck(%rip)
    rep nop
    SFENCE

所以,我正在尝试用MFENCE替换{L,S} FENCE。

我仍然不太明白两个线程如何以相同的-1 * lck值结束。