slab 着色如何最大限度地利用 Cache Lines 或 Cache Rows?
Posted rtoax
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了slab 着色如何最大限度地利用 Cache Lines 或 Cache Rows?相关的知识,希望对你有一定的参考价值。
我正在内核代码中进行slab着色,我能够将slab着色与高速缓存的使用相关联,如下所示:
假设我们有一个 32 位系统,其中物理地址为 32 位。所以这里的物理地址是 32 位的,这个地址被分成三个不同的部分,即标签、索引和数据。标签、索引和数据的长度由缓存行大小和总缓存内存决定。因此,假设高速缓存的大小为 4MB,每个高速缓存行为 64 字节,那么数据为 6 位(log2(高速缓存行)),索引为 16 位,即表示高速缓存的总位数,即 22位减去数据的位,所以它变成了 16 位。如果位(即 10 位)用于标记,则休息。
缓存内存有不同的行,对于 4MB 的缓存大小和 64 Bytes 的缓存行,它有 65536 个不同的行。每行有两个字段,即标签和数据。数据代表从主存储器获取的数据,标签代表作为上述物理地址一部分的值。
当 CPU 查找内存地址时,它会查找缓存,并在查找时将物理地址分解为三个不同的部分,即标记、索引和数据。索引字段用于标识缓存中的行,在直接寻址缓存中,该索引代表缓存中的行。一旦行被知道,cahce 存储器的 Tag 字段与物理地址的 Tag 字段进行比较,如果匹配,则发生缓存命中,否则发生缓存未命中。
我使用上面的描述来明确我对缓存内存的看法。
在 Linux Kernel 中,一个软件缓存使用多个 Slab,每个 Slab 从 Buddy System 分配一个 Page(至少一页)来分配对象。并且这些由不同slab分配的页面可能位于物理地址的相同索引字段下,并且由于所有slab都将使用相同的缓存行并且会导致性能不佳,因为相同的缓存行用于对象上的对象不同的slab。
让我们看看在上面定义的缓存系统中这是如何发生的:
缓存有 65536 行,每行 64 字节,这意味着行的物理索引为 16 位,缓存数据为 6 位。现在说一个页面大小为 4K 意味着它使用 12 位。所以这意味着它使用了数据的 6 位和索引的 6 位。Index 的其余位 (10) 表示同一个 Index 所容纳的页数,这是什么意思?这意味着索引中的其余位表示将使用相同缓存行或缓存行的页面数,在我们的例子中是 1024,即 2^10。到目前为止,我还没有考虑物理地址的标记位来计算页面数,如果我认为这意味着有 1024*1024 个页面将使用相同的缓存行。
那么这么多页使用同一个Cache行,那么性能如何提升呢?
可以通过对不同slab 上的对象使用不同的Cache Rows 来提高性能。我们知道每个slab从一个物理页面地址开始,可以通过将每个页面上的第一个对象偏移缓存行大小的倍数来完成。如果我们在slab上偏移对象,那么它将使用不同的缓存行。
这是我从 Linux 内核中学到的最大限度地利用缓存行的知识,但我仍然有一个问题,即每个slab上的第一个对象被偏移量取代,因此不同slab的第一个对象使用不同的缓存行。那么它如何有效地提高性能,因为我们只针对第一个对象?我能说第一个对象有重要的信息,即结构体slab_t,这就是尽快访问这些信息的原因吗?
如果我在这里遗漏了什么,请告诉我。
一旦您确定了第一个对象的位置和大小,由于填充,所有其他对象都必须效仿
“颜色”的想法可能来自“彩虹的颜色”。硬件缓存将世界视为一系列重叠的条纹。在这种情况下,slab 分配器有意识地浪费内存,使特定slab 中的条目倾向于占据特定“颜色”的(彩虹)条纹。当涉及 DMA 并且您知道活动将非常快速和激烈时,您基本上会使用它,从而证明浪费内存是合理的。
但是,是的,请不要发布一个类似的问题,然后“开始 yammering for attention”。人们不会在这里闲逛,只是屏住呼吸等待复杂的技术问题出现,他们尤其倾向于跳过没有直接切入要点的帖子。
以上是关于slab 着色如何最大限度地利用 Cache Lines 或 Cache Rows?的主要内容,如果未能解决你的问题,请参考以下文章