- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我最近了解到 row hammer攻击。为了执行此攻击,程序员需要刷新 CPU 的完整缓存层次结构以获取特定数量的地址。
我的问题是:为什么是 CLFLUSH x86 有必要吗?如果所有 L* 缓存都透明地运行(即不需要显式缓存失效),那么使用该指令的原因是什么?除此之外:CPU 不是可以自由地推测内存访问模式,从而完全忽略指令吗?
最佳答案
我认为主要用例是 Non-volatile DIMMs ,尤其是英特尔的Optane DC PM。通常是mapped WB-cacheable因此需要显式刷新(或 movnt
)以确保数据持久保存到非 volatile 存储中。
(但是clflush
是在Pentium 4天与SSE2同时引入的。我不知道那里的想法是什么;可能出于性能原因而进行显式缓存控制,就像相反的那样预取。)
Skylake 引入了弱有序的更高性能 CLFLUSHOPT,因为它对于直接连接到内存层次结构的非 volatile 存储非常有用。刷新缓存可确保数据写入实际内存,而不是 CPU 中的脏数据。
另请参阅 SuperUser answer有关 Optane DC PM(持久内存)的一些链接和背景。它是物理地址空间中的非 volatile 存储,而不仅仅是使用软件技巧的虚拟地址空间。
Dan Luu 的 article on clwb
and pcommit
很有趣:让操作系统不妨碍访问存储的好处,详细介绍了英特尔当时针对 clflush/clwb 的计划及其内存排序语义。它是在英特尔仍计划需要名为 pcommit
(持久提交)的指令作为此过程的一部分时编写的,但英特尔后来决定删除该指令:Deprecating the PCOMMIT Instruction (from Intel)有一些关于原因以及幕后工作原理的有趣信息。
如果在 x86 中可以做到这一点,那么对于设备的非缓存一致性 DMA 也可能很重要。 (但自从第一个带有缓存的 x86 CPU 以来,x86 一直具有缓存一致性 DMA,以避免破坏现有软件。)
显然,不可能将 MMIO/PCIe 设备内存区域映射为可回写 (WB) 缓存。 how to do mmap for cacheable PCIe BAR也许 P4 架构师在引入它时就考虑到了 future 的可能性。
在上一个链接中,Bandwidth 博士提到了一个部分解决方法,实际上涉及需要 CLFLUSH 来保持正确性:
map the MMIO range twice -- once for store operations from the processor to the FPGA using the Write-Combining (WC) memory type, and once for reads from the processor to the FPGA using the Write Protect (WP) or Write Through (WT) types. You will need to maintain coherence manually by using CLFLUSH on cache lines in the "read only" region when you write to the alias of that line in the "write only" region.
因此,您可能需要 clflush(NV-DIMM 除外)。
关于x86 - 为什么 x86 中存在 CLFLUSH?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39336536/
我正在尝试了解使用 CLFLUSH 对性能的影响。为此,我写了一个小指针追逐基准测试。我拿 std::vector>其中第一个元素是下一个条目的偏移量,第二个元素是有效载荷。我从条目 0 转到下一个条
我想尝试测量内存访问的时间差异,从缓存访问时和从主内存访问时。 考虑这个程序: #include #include #include #include #include #include
你能告诉我如何使用 clflush() 指令吗?我编写了以下简单代码来测量从缓存中读取变量的执行时间与从缓存中逐出变量后的执行时间之间的差异。但是我没有找到确凿的结果。使用 clflush() 清除缓
考虑以下代码段: #include #include #include #define ARRAYSIZE(arr) (sizeof(arr)/sizeof(arr[0])) inline vo
我们正在尝试使用 Intel CLFLUSH 指令在用户空间刷新 Linux 中进程的缓存内容。 我们创建了一个非常简单的 C 程序,它首先访问一个大数组,然后调用 CLFLUSH 来刷新整个数组的虚
我正在尝试使用 clflush 手动逐出缓存行以确定缓存和行大小。我没有找到任何关于如何使用该指令的指南。我所看到的只是一些代码为此目的使用了更高级别的函数。 有一个内核函数void clflush_
我最近了解到 row hammer攻击。为了执行此攻击,程序员需要刷新 CPU 的完整缓存层次结构以获取特定数量的地址。 我的问题是:为什么是 CLFLUSH x86 有必要吗?如果所有 L* 缓存都
是clflush 1 还刷新关联的 TLB 条目吗?我认为不会,因为 clflush 在缓存行粒度上运行,而 TLB 条目存在于(更大的)页面粒度 - 但我准备好感到惊讶。 1 ...或 clflus
OpenCL clFinish() API 调用会阻塞,直到命令队列上的所有命令都已完成执行。相关函数, clFlush() ,据说 Issues all previously queued Open
通常,缓存行是 64B,但非 volatile 内存的原子性是 8B。 例如: x[1]=100; x[2]=100; clflush(x); x缓存行对齐,初始设置为 0 . 系统崩溃 clflus
我已经编写了两个程序来检查 clflush 是否正在从缓存中逐出我的数据。在我编写的两个程序中,只有一个给出了正确的结果(按照我的预期,在 clflush 之后,访问时间必须比刷新之前更长)。 这是我
英特尔文档中的 clflush 描述称“刷新包含 m8 的缓存行。”。此外,在 Intel 文档中,m8 表示“内存中的一个字节”。 我很困惑为什么它只是m8,它只有一个字节。因为对于32位或64位系
英特尔文档中的 clflush 描述称“刷新包含 m8 的缓存行。”。此外,在 Intel 文档中,m8 表示“内存中的一个字节”。 我很困惑为什么它只是m8,它只有一个字节。因为对于32位或64位系
我是一名优秀的程序员,十分优秀!