3

从指南了解 linux kernel 3rd edition,第 8.2.10 章,Slab coloring-

从第 2 章我们知道,同一个硬件缓存行映射了许多不同的 RAM 块。在本章中,我们还看到相同大小的对象最终存储在缓存中的相同偏移量处。在不同的slab中具有相同偏移量的对象将以相对较高的概率最终映射到同一缓存行中。因此,高速缓存硬件可能会浪费内存周期,将两个对象从同一高速缓存行来回传输到不同的 RAM 位置,而其他高速缓存行未得到充分利用。板分配器尝试通过称为板着色的策略来减少这种令人不快的缓存行为:将称为颜色的不同任意值分配给板。

在此处输入图像描述

(1)我无法理解平板着色试图解决的问题。当正常进程访问数据时,如果它不在缓存中并且遇到缓存未命中,则将数据与来自进程尝试访问的数据的周围地址的数据一起提取到缓存中以提高性能。如何会出现相同的特定缓存行不断被交换的情况?一个进程在两个不同内存区域的内存区域内不断访问相同偏移量的两个不同数据地址的概率非常低。即使确实发生了,缓存策略通常也会根据某些议程(例如 LRU、Random 等)选择要交换的行。不存在这样的策略可以根据被访问地址的最低有效位中的匹配来选择驱逐行.

(2)我无法理解平板着色(从平板的末尾到开头占用空闲字节并导致第一个对象具有不同偏移量的不同平板)如何解决缓存交换问题?

[已解决]经过小型调查,我相信我找到了问题的答案。答案已发布。

4

3 回答 3

1

我想我明白了,答案与关联性有关。

一个缓存可以分为若干个集合,每个集合只能缓存某种内存块类型在里面。例如,set0 将包含地址为 8 的倍数的内存块,set1 将包含地址为 12 的倍数的内存块。这样做的原因是为了提高缓存性能,避免每个地址都在整个缓存中搜索的情况. 这种方式只需要搜索某组缓存。

现在,从链接了解 CPU 缓存和性能

从 Henessey 和 Patterson 的第 377 页,缓存放置公式如下:(块地址)MOD(缓存中的集合数)

让我们获取内存块地址0x10000008(来自slabX,颜色为C)和内存块地址0x20000009(来自slabY,颜色为Z)。对于大多数N(缓存中的集合数),计算<address> MOD <N>将产生不同的值,因此缓存数据的集合不同。如果地址具有相同的最低有效位值(例如0x100000080x20000008),那么对于大多数N计算将产生相同的值,因此块将与相同的缓存集发生冲突。

因此,通过为不同slab中的对象保持不同的偏移量(colors ),slabs对象可能会到达缓存中的不同集合,并且不会与同一集合发生冲突,从而提高了整体缓存性能。

编辑:此外,如果缓存是直接映射的,则根据维基百科CPU Cache,不存在缓存替换策略,并且模计算产生将存储内存块的缓存块:

直接映射缓存 在这种缓存组织中,主存中的每个位置只能进入缓存中的一个条目。因此,直接映射缓存也可以称为“单向集相联”缓存。它没有这样的替换策略,因为没有选择要驱逐哪个缓存条目的内容。这意味着如果两个位置映射到同一个条目,它们可能会不断地相互淘汰。虽然更简单,但直接映射缓存需要比关联缓存大得多才能提供相当的性能,而且更不可预测。令 x 为缓存中的块数,y 为内存的块数,n 为缓存中的块数,然后借助等式 x = y mod n 进行映射。

于 2017-10-14T14:37:15.817 回答
1

经过多次研究和思考,我得到了看似更合理的解释,而不仅仅是具体的地址示例。首先,你必须学习缓存、标签、集合、行分配等基础知识。

可以确定 colour_off 的单位是来自 linux 内核代码的 cache_line_size。colour_off是基本偏移单位,colour是 struct 中 colour_off 的数量kmem_cache

int  __kmem_cache_create (struct kmem_cache *cachep, unsigned long flags)
   cachep->align = ralign;
   cachep->colour_off = cache_line_size();  // colour_off's unit is cache_line_size
    /* Offset must be a multiple of the alignment. */
   if (cachep->colour_off < cachep->align)
      cachep->colour_off = cachep->align;
   .....
   err = setup_cpu_cache(cachep, gfp);

https://elixir.bootlin.com/linux/v4.6/source/mm/slab.c#L2056

所以我们可以分两种情况来分析。 第一个是缓存>平板。 在此处输入图像描述 你看到slab 1、slab2、slab3 ...不可能发生碰撞,主要是因为缓存足够大,除了slab1和slab5会发生碰撞。所以在着色机制不是那么清楚的情况下提高性能。但是对于slab1和slab5我们只是忽略解释它的原因,我相信你在阅读以下内容后会解决它。

第二个是slab > cache。 在此处输入图像描述 空行表示 color_off 或缓存行。显然,slab1 和slab2 不可能在由tick 和slab2、slab3 标记的线上发生碰撞。我们确保着色机制优化两个相邻平板之间的两条线,更不用说slab1与优化更多线的slab3,2 + 2 = 4线,你可以数一下。

总而言之,着色机制通过尽可能使用原本无用的内存来优化缓存性能(详细地说只是优化了开头和结尾的一些 colour_off 行,而不是其他仍然可以碰撞的行)。

于 2019-08-04T10:14:56.887 回答
0

假设你有一个 256 KB 的缓存,它使用了一个超级简单的算法,它缓存行 =(真实地址和 0x3FFFFF)。

现在,如果您在每个兆字节边界上都有平板,那么平板 1 中的第 20 项将把平板 2 的第 20 项踢出缓存,因为它们使用相同的缓存行标记。

通过偏移slab,不同的slab共享相同的缓存行标签的可能性会降低。如果 Slab 1 和 Slab 2 都保存 32 字节的对象,并且 Slab 2 偏移 8 个字节,那么它的缓存标签将永远不会完全等于 Slab 1。

我确定我的一些细节有误,但请记住它的价值。

于 2017-10-13T20:01:07.693 回答