是否有CPU执行这种可能的L1缓存写优化?


9

当具有L1高速缓存的CPU进行写操作时,通常会发生这种情况(假定正在写入的高速缓存行已在L1高速缓存中),高速缓存(除了更新数据外)会将高速缓存行标记为脏,并在稍后将行与更新的数据一起写出。

一种可能的优化方法是使缓存将写入内容与缓存的先前内容进行比较,如果它们相同,则不要将行标记为脏。因为这可以使高速缓存有时避免回写,所以我可以看到CPU制造商如何看待这种逻辑所需要的门。

我的问题:是否有执行此优化的CPU?

关于我为什么要问的背景:我正在编写一些需要经常访问内存的代码;也就是说,能够侦听缓存行为的人不应该推断出我在做什么。我的某些访问是写操作,并且以明显的方式来实现此代码,许多写操作将写入已经存在的相同数据。我需要进行写操作,因为根据数据,我正在写的数据可能相同也可能不同,并且无论如何都要执行相同的操作很重要。如果CPU通过不实际写“ no-change-write”来进行优化,则意味着高速缓存的行为将根据我在做什么而变化,这将颠覆我的目标。

那么,是否有CPU尝试以这种方式优化写入?


11
据说计算机科学中有两个真正困难的问题:缓存失效,命名正确以及一次关闭错误。这是为什么其中第一个比较棘手的示例。
梅森惠勒

@poncho,您说“能够听取缓存行为的人不应该推断出我在做什么。” 现在,如果某些CPU实现了这种“智能回写”功能,除非真正更新了数据,否则该功能不会使高速缓存无效,那么通过在内存层次结构中将CPU距离CPU进一步一层,便可以观察流量/时序实际写入和虚拟写入之间的差异。这是您所关心的吗?
TheCodeArtist

@poncho同样,您真正的问题似乎是关于实现更好的特权/安全模式,而不会泄漏使用情况信息。也许您应该问这个问题?...
TheCodeArtist

1
@TheCodeArtist:好吧,已经发布了加密的边通道攻击,通过使攻击程序监视共享缓存,加密例程可以被运行在同一CPU的不同内核上的另一个程序攻击。我相信这样的程序可以潜在地检测是否清除了L1高速缓存行,因此,如果CPU在讨论中进行了优化,则可以推断出与我感兴趣的程序有关的信息。我并不是在谈论“安全模式”,因为我不具备修改CPU或操作系统的能力。
雨披

4
即使今天是对的,也不能保证明天是对的。
pjc50

Answers:


4

经过数小时的搜索,我找不到使用这种特定优化功能的CPU。提到的大多数优化通常与读/写操作和数据访问的命中/未命中有关:

(第7和第7页) https://cseweb.ucsd.edu/classes/fa14/cse240A-a/pdf/08/CSE240A-MBT-L15-Cache.ppt.pdf

但是,这并不意味着无法执行此优化。通常,可以以编程方式访问CPU缓存行的大小。也可以访问高速缓存寄存器中的当前值,但是这样做有些危险。如果在错误的时间访问了错误的寄存器,则可能会篡改与正在运行的程序相关的寄存器。或者,您可能会无意间修改您要阅读的行的内容。

在寄存器的缓存中获取当前值

此外,所有理论解决方案都需要某种形式的软件实现(汇编程序)。我发现最接近的是ARM体系结构,该体系结构似乎允许缓存操作。除此之外,您还需要知道所需CPU的高速缓存行的大小。您可以以行大小为单位,仔细地将缓存内容读取到内存中的辅助位置,并将其与将要写入寄存器(在这种情况下为L1缓存行)的数据进行比较。

读取CPU缓存内容

从那里,您可以设计一个基于软件的系统,以防止相同的重写。尽管简化了一点,但之所以如此,是因为该解决方案必须适用于现有的任何CPU。

我发现与缓存一致性相关的另一种可能性:

维基百科上有关acche连贯性的文章的相关段落

关于此问题,引起我注意的重点是Snarfing的描述:

它是一种机制,当第二个主控制器修改主存储器中的位置时,高速缓存控制器会同时监视地址和数据,以尝试更新其自身的存储位置副本。当观察到对高速缓存具有副本的位置的写操作时,高速缓存控制器将使用新数据更新其自己的被封存内存位置副本。

换句话说,可能已经存在机制。只是它们可能未用于您建议的优化。您将必须实现执行读/写比较的软件。


也可以访问高速缓存寄存器中的当前值,但是这样做有些危险。 嗯,这没有道理。您是指CPU寄存器吗?编译器生成或手写的asm代码使用寄存器来保存其所操作的值...
Peter Cordes

如果您尝试在软件中实现此功能,则只需让编译器生成if (mem != x) { mem = x; }代替的代码即可mem = x;。这有时只是对多线程程序中共享缓存行的优化,因为写入会干扰其他线程的读取。
彼得·科德斯

1
“咆哮”与此无关。这只是被动监听。 CPU缓存使用MESI,因此它们可以具有连贯的回写缓存。
彼得·科德斯

@PeterCordes如果您发现我的回答令人反感,我深表歉意。但是,看来您在这件事上比我有更多的见识。那么,为什么不亲自回答这个问题呢?我的回答显然不符合您的要求...


3

写入L1缓存是非常非常关键的操作。

回写完全相同的数据似乎很少。在这种特殊情况下,加快速度的优化并不会带来很多的加速。

另一方面,这种优化需要在每次写入高速缓存时比较旧数据和新数据。更糟糕的是,它要求在写入时必须实际可用要写入的数据!

在现代CPU上通常不是这种情况。例如,可能仍在计算要写入的数据。缓存仍然可以继续进行,如果需要,可以加载缓存行,将缓存行标记为已修改,依此类推,甚至在计算完成之前。除了对缓存行进行实际修改之外,所有记账操作都已经执行。如果要比较新写入的结果和旧的缓存行数据,则不可能。

例如,如果您有C代码,则[i] = x / y; 在大多数CPU上,x / y除法会花费非常长的时间。但是,将结果存储到[i]所需的大多数工作已经在除法完成之前很久了;唯一缺少的是将八个结果字节移到高速缓存行。刷新缓存行的操作将自动等待,直到分割完成。读取[i]的操作可能会被重定向,以直接从分频器获得结果。


使用MESI进行一致性的高速缓存仍然可以执行RFO,但是如果准备好之后对数据进行比较,则将该行保留为Exclusive状态,而不是Modified状态。未在硬件中完成的真正原因是,由于数据提交到高速缓存时,它会花费额外的高速缓存读取,并且将需要某种原子性的读取/比较/写入周期(带有脏位的可选设置),从而使其无法正常运行。流水线实施。
彼得·科德斯

1

一种可能的优化方法是让缓存将写入内容与缓存的先前内容进行比较,如果它们相同,则不要将行标记为脏

这样的优化是否会使CPU将某些内容写入缓存的时间加倍?因为每个高速缓存行写入现在都将带有比较操作,该操作不是免费的。

因此,实际上,现在的优化取决于一个非常模糊的因素:一个普通软件用相同的数据重写其可缓存内存的次数。


这种比较将在CPU逻辑中实现。不需要额外的CPU操作,但是信号时间可能会增加,这可能是有问题的。
ziggystar

@ziggystar好吧,我不是硬件专家,但是我已经习惯了一切都需要付费的想法。因此,将操作与缓存行进行比较。可能很快。但这仍然是成本。而且我认为实施者决定不付款。经过一番思考和衡量之后,甚至可能会如此。
Vladislav Rastrusny 2015年

1
但是,您谈论的是时间,而成本可能只是门数量的增加。
ziggystar,2015年

1
@ziggystar:这不仅仅是更多的大门。当数据发送到缓存时,通常,发送数据的过程可以将缓存行标记为已修改。通过这种“优化”,旧数据和新数据都必须通过这些门,这将导致一定的延迟,然后才可以使缓存无效。您必须将所有这些压缩到一个处理器周期中,否则写入高速缓存行的过程将突然花费两个周期。现在让事情变得更复杂,请考虑当我将八个连续的字写入高速缓存行时会发生什么。
gnasher729 2015年

1
并且这些写操作中的每一个都会延迟是否更改缓存行的决定。因此,当第二次写入发生时,高速缓存行不知道是否已对其进行修改(尚未)。这将会非常好玩。
gnasher729 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.