CPU 寄存器和缓存一致性

发布于 2024-08-15 20:02:58 字数 634 浏览 7 评论 0原文

当涉及到 MESI 等缓存一致性协议时,CPU 寄存器和 CPU 缓存之间有什么关系?如果某个值存储在CPU的缓存中,并且还存储在寄存器中,那么如果缓存行被标记为“脏”,会发生什么情况?据我了解,即使缓存已更新(由于 MESI),也不能保证寄存器会更新其值。

Hench 这段代码:(

 static void Main()  
  {  
  bool complete = false;   
  var t = new Thread (() =>  
  {  
    bool toggle = false;  
    while (!complete) toggle = !toggle;  
  });  
  t.Start();  
  Thread.Sleep (1000);  
  complete = true;  
  t.Join();        // Blocks indefinitely  
}

假设编译器没有优化循环外“完整”的加载)
据我了解,第二个线程看不到“完成”的更新,因为它的值保存在寄存器内(但是CPU 2的缓存已更新)。

放置内存屏障是否会强制“刷新”所有寄存器?寄存器和缓存有什么关系?寄存器和内存屏障又如何呢?

What's the relation between CPU registers and CPU cache when it comes to cache coherence protocols such as MESI? If a certain value is stored in the CPU's cache, and is also stored in a register, then what will happen if the cache line will be marked as "dirty"? To my understanding there is no guarantee that the register will update it's value even though the cache was updated (due to MESI).

Hench this code:

 static void Main()  
  {  
  bool complete = false;   
  var t = new Thread (() =>  
  {  
    bool toggle = false;  
    while (!complete) toggle = !toggle;  
  });  
  t.Start();  
  Thread.Sleep (1000);  
  complete = true;  
  t.Join();        // Blocks indefinitely  
}

(let's assume the compiler didn't optimized the load for 'complete' outside the loop)
to my understanding, the update to "complete" isn't visible to the second thread since it's value is held inside a register (CPU 2's cache was update however).

Does placing a memory barrier forces to "flush" all of the registers? What's the relation of registers to the cache? and what about registers and memory barriers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凡尘雨 2024-08-22 20:02:58

没有关系。使用“易失性”关键字。

There is no relationship. Use the "volatile" keyword.

断肠人 2024-08-22 20:02:58

现代 C++ | C++11

你应该使用 std::atomic

#include <thread>
#include <atomic>
#include <chrono>

std::atomic_bool g_exit{ false }, g_exited{ false };

using namespace std::chrono_literals;

void fn()
{
    while (!g_exit)
    {
        // do something (lets say it took 5s)
        std::this_thread::sleep_for(5s);
    }

    g_exited = true;
}

int main()
{
    std::thread wt(fn);
    wt.detach();

    // do something (lets say it took 2s)
    std::this_thread::sleep_for(2s);

    // Exit

    g_exit = true;

    for (int i = 0; i < 5; i++) { 
        std::this_thread::sleep_for(1s);
        if (g_exited) {
            break;
        }
    }
}

Modern C++ | C++11

You should use std::atomic

#include <thread>
#include <atomic>
#include <chrono>

std::atomic_bool g_exit{ false }, g_exited{ false };

using namespace std::chrono_literals;

void fn()
{
    while (!g_exit)
    {
        // do something (lets say it took 5s)
        std::this_thread::sleep_for(5s);
    }

    g_exited = true;
}

int main()
{
    std::thread wt(fn);
    wt.detach();

    // do something (lets say it took 2s)
    std::this_thread::sleep_for(2s);

    // Exit

    g_exit = true;

    for (int i = 0; i < 5; i++) { 
        std::this_thread::sleep_for(1s);
        if (g_exited) {
            break;
        }
    }
}
千寻… 2024-08-22 20:02:58

x86平台中使用的MESI协议保证了高速缓存的一致性,即一个CPU高速缓存的变化会自动传播到其他CPU高速缓存。
因此,x86 和 x64 上的 volatile 关键字仅用于防止重新排序。

MESI protocol used in x86 platform guarantees cache coherence, i.e. changes in one CPU cache are automatically propagated to other CPU caches.
Therefore volatile keyword on x86 and x64 is useful only to prevent reordering.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文