gpt4 book ai didi

c - 系统崩溃时 clflush 或 clflushopt 是原子的吗?

转载 作者:行者123 更新时间:2023-12-03 15:41:18 25 4
gpt4 key购买 nike

通常,缓存行是 64B,但非 volatile 内存的原子性是 8B。
例如:

x[1]=100;
x[2]=100;
clflush(x);
x缓存行对齐,初始设置为 0 .
系统崩溃 clflush();可以吗 x[1]=0 , x[2]=100重启后?

最佳答案

在以下假设下:

  • 我假设您显示的代码表示一系列 x86 汇编指令,而不是尚未编译的实际 C 代码。
  • 我还假设代码是在 Cascade Lake 处理器上执行的,而不是在新一代 Intel 处理器上执行(我认为带有 Barlow Pass 的 CPL 或 ICX 支持 eADR,这意味着持久性不需要显式刷新,因为缓存位于持久域)。这个答案也适用于现有的 AMD+NVDIMM 平台。

  • 存储的全局可观察性顺序可能与 Intel x86 处理器上的持久顺序不同。这称为松弛持久性。唯一保证顺序相同的情况是将 WB 类型的存储序列放入同一缓存行(但到达 GO 的存储并不一定意味着它变得持久)。这是因为 CLFLUSH是原子的,WB 存储不能在全局可观察性中重新排序。见: On x86-64, is the “movnti” or "movntdq" instruction atomic when system crash? .
    如果两个存储跨越缓存线边界或者如果存储的有效内存类型是 WC:
    x86-TSO 内存模型不允许重新排序存储,因此另一个代理不可能观察到 x[2] == 100x[1] != 100在正常操作期间(即在没有崩溃的 volatile 状态下)。但是,如果系统崩溃并重新启动,则持久状态可能为 x[2] == 100x[1] != 100 .即使退休后系统崩溃,这也是可能的 clflush因为 clflush的退休并不一定意味着刷新的缓存行已到达持久域。
    如果你想消除它,你可以移动 clflush如下:
    x[1]=100;
    clflush(x);
    x[2]=100;
    clflush英特尔处理器上的所有写入都是按顺序排列的,这意味着该行保证在任何后续存储变为全局可见之前到达持久域。见: Persistent Memory Programming Primary (PDF)和英特尔 SDM V2。第二家商店可以在同一行或任何其他行。
    如果你想要 x[1]=100在之前变得持久 x[2]=100成为全局可观察的,添加 sfence之后 clflush在英特尔 CSX 或 mfence 上在 AMD 处理器上( clflush 仅由 mfence 在 AMD 处理器上订购)。 clflush本身足以控制持久顺序。
    或者,使用序列 clflushopt+sfence (或 clwb+sfence )如下:
    x[1]=100;
    clflushopt(x);
    sfence;
    x[2]=100;
    在这种情况下,如果发生崩溃并且如果 x[2] == 100在持久状态下,则保证 x[1] == 100 . clflushopt本身不会强加任何持久排序。

    关于c - 系统崩溃时 clflush 或 clflushopt 是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65439089/

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