系统崩溃时clflush或clflushopt是原子的吗? [英] Is clflush or clflushopt atomic when system crash?

查看:149
本文介绍了系统崩溃时clflush或clflushopt是原子的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,高速缓存行为64B,但非易失性存储器的原子性为8B.

Commonly, cacheline is 64B but atomicity of non-volatile memory is 8B.

例如:

x[1]=100;
x[2]=100;
clflush(x);

x 是高速缓存行对齐的,最初设置为 0 .

x is cacheline aligned, and is initially set to 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存储不能在全局可观察性中重新排序.请参阅:在x86-64上,是"movnti"或"movntdq",系统崩溃时是指令原子吗?.

The global observablility order of stores may differ from the persist order on Intel x86 processors. This is referred to as relaxed persistency. The only case in which the order is guaranteed to be the same is for a sequence of stores of type WB to the same cache line (but a store reaching GO doesn't necessarily meant it's become durable). This is because CLFLUSH is atomic and WB stores cannot be reordered in global observability. See: On x86-64, is the "movnti" or "movntdq" instruction atomic when system crash?.

x86-TSO内存模型不允许对存储进行重新排序,因此另一个代理不可能观察到 x [2] == 100 x [1]!= 100 在正常操作期间(即处于易失性状态而不会崩溃).但是,如果系统崩溃并重新启动,则持久状态可能为 x [2] == 100 x [1]!= 100 .即使在退出 clflush 后系统崩溃了,因为 clflush 的退出并不一定意味着刷新的缓存行已到达持久性域.

The x86-TSO memory model doesn't allow reordering stores, so it's impossible for another agent to observe x[2] == 100 and x[1] != 100 during normal operation (i.e., in the volatile state without a crash). However, if the system crashed and rebooted, it's possible for the persistent state to be x[2] == 100 and x[1] != 100. This is possible even if the system crashed after retiring clflush because the retirement of clflush doesn't necessarily mean that the cache line flushed has reached the persistence domain.

如果您想消除这种情况,可以按照以下方式移动 clflush :

If you want to eliminate that possibly, you can either move clflush as follows:

x[1]=100;
clflush(x);
x[2]=100;

英特尔处理器上的

clflush 是针对所有写入的顺序排列的,这意味着该行可以保证在以后的所有存储变为全局可观察之前到达持久性域.请参阅:永久性存储器编程主程序(PDF)和Intel SDM V2.第二家商店可以在同一行或任何其他行.

clflush on Intel processors is ordered with respect to all writes, meaning that the line is guaranteed to reach the persistence domain before any later stores become globally observable. See: Persistent Memory Programming Primary (PDF) and the Intel SDM V2. The second store could be to the same line or any other line.

如果希望 x [1] = 100 x [2] = 100 成为全局可观察的之前成为持久性,请在之后添加 sfence Intel CSX上的 clflush 或AMD处理器上的 mfence ( clflush 仅由AMD处理器上的 mfence 订购). clflush 本身足以控制持久顺序.

If you want x[1]=100 to become persistent before x[2]=100 becomes globally observable, add sfence after clflush on Intel CSX or mfence on AMD processors (clflush is only ordered by mfence on AMD processors). clflush by itself sufficient to control persist order.

或者,按如下所示使用序列 clflushopt + sfence (或 clwb + sfence ):

Alternatively, use the sequenceclflushopt+sfence (or clwb+sfence) as follows:

x[1]=100;
clflushopt(x);
sfence;
x[2]=100;

在这种情况下,如果发生崩溃并且 x [2] == 100 处于持久状态,则可以保证 x [1] == 100 . clflushopt 本身不施加任何持久性排序.

In this case, if a crashed happened and if x[2] == 100 in the persistent state, then it's guaranteed that x[1] == 100. clflushopt by itself doesn't impose any persist ordering.

这篇关于系统崩溃时clflush或clflushopt是原子的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆