6

我正在使用 C# 并希望尽可能避免unsafe使用代码。如果我有一个大小可以填充缓存行的对象或数组,并且我想写入对象的每个字段或数组的索引,CPU 是否会在刷新写入行之前等待所有写入发生或当只有一个或几个写入发生时,它会提前刷新吗?

如果我只想在对行的所有写入发生后才进行刷新,我是否应该在例程结束时快速连续地执行所有写入?我知道 CPU 和缓存一致性协议可能对此有所不同,我正在寻找一个普遍正确的经验法则答案。

4

2 回答 2

2

CPU会在刷新写入行之前等待所有写入发生还是会在仅发生一个或几个写入时提前刷新?

CPU 可能会提前刷新该行,但前提是该集合受到属于高速缓存的其他访问的高压。这不太可能。缓存的结构有助于避免过早刷新最近访问的数据。

我应该在例程结束时快速连续地完成所有写入吗?

一般来说是的。 时间局部性很重要,这意味着当访问按时间紧密分组时,缓存性能最佳。其他技巧也可能适用。例如,您可以尝试通过在所需写入之前对您的结构进行虚拟写入来“加热”高速缓存行。这允许一些内存级别的并行性,其中核心在执行干预代码的同时加载缓存行。当您执行真正的写入时,缓存行在 L1 中准备就绪的机会会更好。

通常,对代码中的不自然行为要非常谨慎,以提高缓存性能。 缓存做得很好,只是留给自己。您应该始终在任何更改之前和之后衡量性能。你认为可能是一种改进实际上可能会受到伤害。如果您的程序是多线程的,那么另一个大罐蠕虫会与内核之间的缓存争用有关。

于 2013-02-22T17:13:02.103 回答
1

自然,CPU 会尝试尽可能少地访问内存,但这并不一定意味着“您的”内存块将保留在缓存中,只要您愿意。

通常,内存块将被读取一次并写入一次,但不能保证这一点。可能会发生某些事情会中断您的代码,并且系统可能会决定刷新该缓存行以为其他内容腾出空间。整个内存区域甚至可以完全从内存中删除并刷新到磁盘,这样当您的代码继续运行时,它会导致页面错误,从而再次加载内存。

让您的写入时间更近当然会使内存更有可能在该操作期间保留在缓存中。

于 2013-02-22T16:52:51.550 回答