Linux slab分配器和缓存性能

时间:2017-10-13 14:13:58

标签: linux memory memory-management linux-kernel slab

从指南了解linux内核第3版,第8.2.10章,Slab着色 -

  

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

Writing Code With Your Data

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

(2)我无法理解平板着色是如何从平板末端到开头的自由字节,以及第一个对象具有不同偏移的不同平板的结果,解决了缓存 - 等待问题?

[已解决] 经过一次小规模的调查后,我相信我找到了一个问题的答案。答案已经发布。

3 个答案:

答案 0 :(得分:2)

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

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

现在,从链接Understanding CPU Caching and performance

  

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

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

因此,通过为不同楼板中的对象保留不同的偏移量( colors ),slabs对象可能会在缓存中到达不同的集合,并且不会碰撞到相同的集合,整体缓存性能提高。

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

  

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

答案 1 :(得分:1)

经过大量的研究和思考,我得到的解释似乎更合理,不仅是通过具体的地址示例。 首先,您必须学习诸如缓存,标签,集合,行分配之类的基础知识。

从Linux内核代码可以肯定colour_off的单位是cache_line_size。 colour_off是基本偏移量单位,colour是结构kmem_cache中colour_off的数量。

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

因此,我们可以在两种情况下进行分析。  第一个是缓存>平板。 enter image description here 您会看到slab 1 slab2 slab3 ...几乎不可能发生冲突,因为除了slab1 vs slab5可能会发生冲突之外,缓存足够大。因此在这种情况下,着色机制尚不清楚,无法提高性能。但是,对于slab1和slab5,我们只是忽略不了解释原因,我相信您在阅读以下内容后会得出结论。

第二个是平板>缓存。 enter image description here 空行表示color_off或缓存行。显然,slab1和slab2不可能在刻度线和slab2 slab3所标记的行上发生碰撞。 我们确保着色机制可以优化两个相邻平板之间的两条线,而slab1和slab3可以减少更多的行,而2 + 2 = 4线则可以计算。

总而言之,着色机制通过尽可能地使用原始无用的内存来优化缓存性能(详细地说,仅在开始和结束时优化colour_off的某些行,而不是仍然可以冲突的其他行)。

答案 2 :(得分:0)

假设您有一个256 KB的缓存,它使用超简单的算法,它会缓存line =(实际地址AND 0x3FFFFF)。

现在,如果你在每兆字节边界上开始使用slab,那么Slab 1中的第20项将从Slab 2的第20项中取出缓存,因为它们使用相同的缓存行标记。

通过偏移平板,不同的平板将不太可能共享相同的缓存行标记。如果Slab 1和Slab 2都保存32字节对象而Slab 2偏移8字节,则其缓存标记永远不会与Slab 1完全相同。

我确定我有一些错误的细节,但要把它当作值得的。