1

我有我用 C++ 编写的程序。在 linux 上,进程被分配了一定数量的内存。一部分是堆栈,一部分是堆,一部分是文本,一部分是 BSS。

以下是否属实:

分配给我的进程的堆组件的内存量越大 - 翻译后备缓冲区未命中的机会增加?

一般而言 - 我的应用程序进程消耗的内存越多,TLB 未命中的机会就越大?

4

2 回答 2

2

我认为分配的内存量与 TLB 的未命中率之间没有直接关系。据我所知,只要您的程序具有良好的局部性,TLB 未命中率就会很低。

导致 TLB 未命中率高的原因有以下几个: 1.内存不足,运行进程多;2.你的程序的低局部性。3.在代码中循环访问数组元素的低效方式。

于 2014-01-10T02:34:08.257 回答
1

程序通常分为表现出完全不同的内存和执行特征的阶段——您的代码可能会在某个时刻分配大量内存,然后停止执行一些其他不相关的计算。在这种情况下,您的 TLB(基本上只是用于地址转换的缓存)会老化未使用的页面并最终丢弃它们。当你不使用这些页面时,你不应该关心它。

真正的问题是——当您进入某个性能关键阶段时,您是否会使用比您的 TLB 同时支持的页面更多的页面?一方面,现代 CPU 具有大型 TLB,通常具有 2 级缓存 - 现代英特尔 CPU 的 L2 TLB 应该有(IIRC)512 个条目 - 如果您使用 4k 页面(大页面会已经更多了,但由于与较小页面的潜在冲突,TLB 通常不喜欢使用它们..)。

应用程序很有可能处理超过 2M 的数据,但如果可能,您应该避免同时执行此操作 - 通过缓存平铺或更改算法。这并不总是可能的(例如,从内存或 IO 流式传输时),但 TLB 未命中可能不是您的主要瓶颈。当使用相同的数据集并多次访问相同的元素时 - 您应该始终尝试将它们缓存在尽可能近的位置。

也可以使用软件预取来使 CPU 更早地执行 TLB 未命中(以及随后的页面遍历),从而防止它们阻塞您的进度。在某些 CPU 上,硬件预取已经为您执行此操作。

于 2014-01-10T14:49:13.993 回答