根据英特尔64和IA-32架构软件开发人员手册,LOCK信号前缀“确保处理器在声明信号时独占使用任何共享内存”。这可以是总线或缓存锁的形式。
但是 - 这就是我提出这个问题的原因 - 我不清楚,如果这个前缀也提供了任何内存屏障。
我正在多处理器环境中使用NASM进行开发,并且需要使用可选的获取和/或发布语义来实现原子操作。
那么,我是否需要使用MFENCE,SFENCE和LFENCE指令,或者这是多余的?
答案 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值结束。