优化cache利用、减少cache miss的方法
1. 数据局部性优化
- 时间局部性:如果某个数据项被访问了,则在不久的将来它很可能再次被访问。尽量保持频繁使用的数据驻留在缓存中。
- 空间局部性:当一个内存位置被访问后,附近的位置很快也会被访问。通过优化数据结构和算法,确保相邻的数据在物理上也是相邻的。
2.优化数据布局与内存分配
- 内存对齐:确保数据结构对齐到缓存行(通常64字节),避免跨缓存行访问的开销
- 分块处理(Blocking):将大数据集分割为与缓存容量匹配的小块,例如矩阵乘法中将大矩阵拆分为子矩阵,确保每个块的数据在处理时能完全驻留在缓存中
- 避免伪共享(False Sharing):在多线程编程中,若多个线程频繁修改同一缓存行中的不同变量,会导致缓存行无效化,多线程,会用到多核,这里涉及到了多核间 cache 一致性的问题,一个核改了数据,其他核的私有cache的数据就会无效。可通过填充(Padding)或独立分配内存来隔离变量
3.循环优化
- 循环分块(Loop Tiling):将大的循环分割成小的块,使得每个块可以完全加载到缓存中,从而减少缓存未命中。
- 循环交换(Loop Interchange):改变嵌套循环的顺序以改进空间局部性。例如,在处理二维数组时,如果按照列优先顺序存储数据,应该优先遍历列而不是行。
4. 使用合适的数据结构
选择适合于缓存友好的数据结构。例如:
- 数组优于链表,因为数组中的元素通常是连续存储的,有利于利用空间局部性。
- 对象池技术可以减少对象分配和回收的成本,提高缓存命中率
5.使用合适的算法,减少跳跃,减少空间
设计考虑缓存效率的算法,比如:
- 在排序算法中,快速排序通常比归并排序更缓存友好,因为它倾向于访问相邻的数据。快排的空间相关性更好。
- 使用位图代替哈希表或其他集合类型,可以减少内存占用,提高缓存利用率。需要频繁使用的内存减少,可减少 miss 次数,cache 的大小是固定的,如果频繁访问的数据很多,有的数据就会被替换掉
6.优化cache替换算法
- 操作系统使用不同的页面置换算法(如LRU、FIFO等)来决定哪些内存页应该被交换到磁盘上以腾出空间给更常用的页。有效的页面置换算法可以减少缓存未命中。