繁体   English   中英

原子变量还需要锁定读取-修改-存储操作吗?

[英]atomic variable also require lock on read-modify-store operation?

我知道原子变量是无锁的!!
它不会锁定线程,但我有一个问题..
像 std::atomic::fetch_add 这样的 Read-Modify-Store 操作也是原子执行的???
我认为这个操作不仅仅是一个指令。
它需要多个周期......所以如果我不锁定 memory 总线(实际上我不知道互斥锁是否包含 memory 总线锁定),其他线程可以在读取和存储操作之间进行 memory 操作。
所以我认为即使原子变量也需要锁定......

我是不是很清楚???

You konwing 就在早期的 x86 架构中。

在 x86 架构中,提供了指令前缀 LOCK。原子变量依赖于该指令。早期的 LOCK 是通过锁定总线来实现的,以防止 memory 从其他 CPU 内核访问。 可以想象,这种实现效率非常低

大多数x86处理器都支持CAS的硬件实现,保证了多处理器多核系统中原子操作的正确性。 CAS 的实现也不会锁定总线,只会阻止其他 CPU 对检查相关 memory 的缓存块的访问。 让你看看代码。 示例代码是:

#include <iostream>
#include <thread>
#include <atomic>
 
std::atomic<long long> data;
void do_work()
{
    data.fetch_add(1, std::memory_order_relaxed);
}
 
int main()
{
    std::thread th1(do_work);
    std::thread th2(do_work);
    std::thread th3(do_work);
    std::thread th4(do_work);
    std::thread th5(do_work);
 
    th1.join();
    th2.join();
    th3.join();
    th4.join();
    th5.join();
 
    std::cout << "Result:" << data << '\n';
}

将上述代码转换为指令。 在 gcc 8 do_work function 翻译成

        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], 1
        mov     DWORD PTR [rbp-12], 0
        mov     rax, QWORD PTR [rbp-8]
        mov     edx, OFFSET FLAT:data
        lock xadd       QWORD PTR [rdx], rax
        nop
        pop     rbp
        ret

使用lock xadd来确保原子操作符。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM