C++ 缓存友好代码

17 Mar 2025 | 4 分钟阅读

在本文中,我们将讨论 C++ 中的缓存友好代码及其工作原理和几个示例。

C++ 中的缓存友好代码是什么?

旨在最大化内存访问模式以充分利用 CPU 缓存的编程被称为“缓存友好代码”,CPU 缓存是一种快速、紧凑的内存,用于保存频繁请求的数据。在适当的缓存管理下,程序运行得更快,因为信息的检索速度比从 RAM(主内存)访问信息的速度更快。C++ 中适当的缓存管理通过将相关或频繁请求的数据在内存中放置在一起,使我们的数据和算法紧密相邻,以确保因缓存中缺少重要方面而导致的缓存未命中得到减少。

缓存友好的重要性

在现代系统中,内存的运行速度明显慢于 CPU。CPU 如果必须等待数据从 RAM 加载,可能会出现性能瓶颈。通过优化代码和数据结构以尽可能有效地利用缓存,可以大大提高编程性能。

示例 1

让我们举一个例子来说明 C++ 中的缓存友好代码。

输出

 
Cache-friendly row-major time: 0.484802 seconds   

说明

在此示例中,外层循环遍历行,内层循环遍历列。输出是行主序的连续内存访问,这非常优化并最大化了缓存使用率。

示例 2

让我们再举一个例子来说明 C++ 中的缓存友好代码。

输出

 
Cache-unfriendly column-major time: 0.96013 seconds   

说明

此示例的二维数组缓存友好性较差,因为我们由于非连续内存访问而按列访问它。由于 二维数组在 C++ 中以行主序存储,因此以列主序样式访问元素通常会导致缓存未命中。

示例 3

让我们再举一个例子来说明 C++ 中的缓存友好代码。

输出

 
Cache-friendly row-major time: 0.587543 seconds   

说明

  • 矩阵分配:由于矩阵的大小,最好使用 std::vector 动态分配它,以避免堆栈溢出问题。
  • 内存访问优化:使用行主序循环进行内存访问,因为首先遍历行然后遍历列会利用数据局部性,这与 C++ 中的做法类似。增强内存连续性局部性可以减少缓存未命中,从而加快进程。

结论

总之,缓存友好代码是优化性能的一个重要概念,尤其是在处理 C++ 中二维数组等大型数据结构时。缓存友好编程通过在访问内存时同时使用时间局部性和空间局部性,力求确保适当的缓存命中,同时保持数据访问的连贯性和及时性。它可以通过允许使用行来顺序组织内存来大大提高缓存效率。当代码被编写为访问元素时,它有助于 CPU 快速填充缓存行,从而无需长时间访问较慢的主内存。然而,缓存不友好的模式,例如列主序访问,可能会导致性能不佳,因为它们会导致频繁的缓存未命中和碎片化的内存访问。