gpt4 book ai didi

c++ - 多线程与 std::atomic<>

转载 作者:行者123 更新时间:2023-11-30 04:46:16 28 4
gpt4 key购买 nike

在下面的小代码示例中,我不明白,当一个线程开始增加计数器时,线程会将计数器地址写入内核共享的缓存中,并使计数器锁定在缓存中,直到该线程已经完成在计数器中的写入,但是如果另一个尝试在前一个线程读写修改之间向这个计数器添加+1,他会看到缓存中的数据被锁定然后呢?第二个线程会休眠还是等到缓存中的计数器解锁......?

如果线程休眠,我看不到小数据的原子和互斥之间的好处:

// this_thread::yield example
#include <iostream> // std::cout
#include <thread> // std::thread, std::this_thread::yield
#include <atomic> // std::atomic

std::atomic<bool> ready (false);
std::atomic<int> counter (0);

void count1m(int id) {
while (!ready) { // wait until main() sets ready...
std::this_thread::yield();
}
for (volatile int i=0; i<10000; ++i) {
counter +=1;}
}

int main ()
{
std::thread threads[10];
std::cout << "race of 10 threads that count to 1 million:\n";
for (int i=0; i<10; ++i) threads[i]=std::thread(count1m,i);
ready = true; // go!
for (auto& th : threads) th.join();
std::cout << counter;
}

最佳答案

“缓存锁”只是一个延迟对 MESI 无效或共享请求的响应的核心。

它不是互斥锁或其他任何东西,它是单个内核可以通过调整它使用现有 MESI 缓存一致性协议(protocol)的方式来完成的事情,该协议(protocol)确保缓存永远不会对同一地址具有冲突的值。其他核心不必知道“锁定”,它们只看到对共享线路请求的响应延迟。 (无论如何,它没有任何硬性截止日期或预期的响应时间;它会根据争用以及有多少其他内核也在等待对该行的独占访问以提交他们的存储或 RMW 而有所不同。)

参见 Can num++ be atomic for 'int num'?了解全部详情。 (可以说不是重复的,因为那个从更广泛的前提开始,涵盖了很多与这里无关的内容。)

C++ 内存模型假定一致的共享内存,这基本上是所有多核机器所具有的。始终(AFAIK)与 MESI 的某些变体缓存一致性协议(protocol)。


will the second thread will sleep?

不,这都是硬件层面的。操作系统不知道核心在等待缓存行时停止。

这与常规缓存未命中非常相似,等待数据从 DRAM 而不是另一个核心到达。

关于c++ - 多线程与 std::atomic<>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56868736/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com