算法优化:优化缓存利用率
Posted 算法杂话
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法优化:优化缓存利用率相关的知识,希望对你有一定的参考价值。
1. 数据布局 & Cache利用率
2. 不好的数据布局
2.1 不完全使用的结构体
2.3 动态内存分配
1. 数据布局 & Cache利用率
每个cache line用实线矩形框表示,cache line中不同的数据域用虚线分隔。cache line中已缓存数据且被使用的部分(used parts)用绿色表示,已缓存数据但未使用的部分(touched but unused parts)用红色表示,完全干净的部分(completely unused)用白色表示,如Figure 1所示。
数据结构中的无用数据浪费cache的空间,降低cache的利用率,增加cache miss,从而导致程序性能变差,如Figure 2所示。
2. 不好的数据布局
2.1 不完全使用的结构体
考虑如下结构体,该结构体有a, b, c, d四个成员,但是在影响程序性能的关键循环中只使用到成员a和b。
未被使用的成员缓存到cache中,不仅浪费cache的空间,且增加cache miss。
修改方法
2.2 地址对齐
对齐约束条件:(1) 结构体内成员按其长度自对齐
(2) 结构体的大小为结构体的有效对齐值的整数倍
结构体的有效对齐值的确定:
-
当未明确指定时,结构体中最大成员的长度为有效值 -
当用#pragma pack(n)指定时,Min(n, 结构体中最大成员的长度) 为有效值 -
当用__attribute__((packed_size))指定长度时,packed_size为有效值
举例说明:
如果交换成员a和b,那么就无需为结构体内部对齐而添加填充字节(padding)。
为减少padding,最简单的方法是对结构体内部成员按照长度从大到小的顺序进行排序。
除了结构体内部成员对齐(对齐约束条件1),还需要满足结构体整体大小的对齐(对齐约束条件2),考虑下面的例子:
结构体整体大小要求是4的整数倍对齐,由于结构体大小是6个字节,因此结构体必须是8字节对齐,因此编译器会在结构体数组成员之间添加2字节的填充,如Figure 8所示。
2.3 动态内存分配
动态内存分配器除了分配有效负载需要的字节数外,还会额外分配一些空间用于存储头部以及填充字节。频繁使用动态内存分配会降低内存利用率,因此,更好的做法是分配一块大的内存块(memory chunk),然后根据需要使用其中不同的区域,从而减少动态内存分配的次数。
以上是关于算法优化:优化缓存利用率的主要内容,如果未能解决你的问题,请参考以下文章