new/malloc或delete/free是否占用或无效缓存行?

nin*_*eee 6 c c++ caching

我很好奇缓存行为.以下是与缓存相关的一些问题:

  1. 写操作是否将数据带入缓存?考虑像A [i] = B [i]之类的赋值,将A [i]加载到缓存中吗?因为我只是在A [i]中写入内容而不是读取它的值.

  2. 分配大内存时,内存可能来自操作系统.并且出于安全原因,OS将数据初始化为零(参考).如果赋值将数据带入缓存(问题1),这种机制会占用缓存吗?

  3. 假设有一个已分配的数组B,整个B现在位于缓存中.在我释放数组B后,B占用的缓存行是否会变为无效(可用)?

有人能给我一个暗示吗?

小智 3

从这里https://people.freebsd.org/~lstewart/articles/cpumemory.pdf

--

  1. 写操作是否会将数据带入缓存?

来自文章:

默认情况下,CPU 核心读取或写入的所有数据都存储在缓存中。有些内存区域无法缓存,但这只是操作系统实现者必须关心的事情;它对于应用程序员来说是不可见的。还有一些指令允许程序员故意绕过某些缓存。这将在第 6 节中讨论。

--

  1. 当分配大内存时,内存可能来自操作系统。这个机制会占用缓存吗?

可能不是。只有读或写数据后才会占用缓存。来自文章:

在支持请求分页的 Linux 等操作系统上,mmap 调用仅修改页表……在 mmap 调用时不会分配实际内存。

分配部分发生在首次访问内存页时,无论是通过读取或写入数据,还是通过执行代码。为了响应随后出现的页面错误,内核使用页表树进行控制并确定页面上必须存在的数据。这种页面错误的解决方案并不便宜,但进程使用的每个页面都会发生这种情况。

--

3.假设有一个已分配的数组B,并且整个B现在都在缓存中。当我释放数组B后,B占用的缓存线是否会立即变得无效(可用)?

根据文章,只有当另一个 CPU 上有写操作时,才会发生缓存行失效

多年来发展起来的是 MESI 缓存一致性协议(修改的、独占的、共享的、无效的)。该协议以使用 MESI 协议时缓存线可以处于的四种状态命名。...如果第二个处理器想要写入高速缓存行,则第一个处理器发送高速缓存行内容并将本地高速缓存行标记为无效。

并且缓存行也可以被驱逐:

程序员不太感兴趣的另一个缓存细节是缓存替换策略。大多数缓存首先驱逐最近最少使用(LRU)元素。

根据我使用 TCMalloc 的经验,free()这并不是从缓存中逐出内存的令人信服的理由。相反,它可能会损害性能。在free()TCMalloc 上,只是将释放的内存块放入其缓存中。malloc()当应用程序下次请求一块内存时,就会返回这块内存。这就是像 TCMalloc 这样的缓存分配器的本质。如果这块内存仍然在缓存中,那么性能会更好!