【问题标题】:Loop stride and cache line循环步长和缓存线
【发布时间】:2026-02-14 22:05:02
【问题描述】:

我正在学习缓存行,以及循环步长对缓存的影响。我遇到了this 页面,它显示了循环的执行时间与循环步幅。根据基准,增加循环步幅会减少执行时间,这让我很困惑。据我了解,如果缓存行是 64 字节,并且假设在第一种情况下循环步长仅为 1,这意味着循环按顺序遍历数组元素,那么执行时间应该最短,因为 16 个整数(4 字节 x 16 = 64bytes) 被加载到缓存中。由于所有 16 个元素都加载到同一个高速缓存行中,因此执行时间应该最短,最大跨度为 16。当步幅增加到 16 以上时,应该会增加执行时间,因为数组元素不会在缓存行中,但页面上的图形完全相反。

【问题讨论】:

    标签: arrays caching cpu-architecture cpu-cache


    【解决方案1】:

    在该示例中,长度是恒定的,因此步幅越大 - 您通过的元素越少。

    有趣的现象是它不适用于缓存行以下,那是因为你不能带行的一部分。所以低于 16,你要付出同样的代价来获取所有的缓存行。超过 16 行时,您开始跳过一些行。例如,高于 32 (128B) 您每隔一行获取一次 - 因此 +/- 一半的时间(假设您的执行时间主要由内存延迟决定)

    【讨论】:

    • 所以当你说“低于 16 时,你会付出同样的代价来获取所有缓存行”,这是否意味着整个数组(所有元素)都被加载到缓存中,而当数组的 16 部分以上时是否加载到缓存中?我的印象是加载的元素数量取决于步幅
    • 缓存以 64 字节粒度完成。如果您访问缓存行的一个元素,您仍然必须获取整行。但是,如果您的步幅是两个缓存行宽,则您不必获取中间的行。如果你画它,你会发现任何超过 64B 的步幅都会允许一些跳跃,并且步幅越长,你得到的跳跃越多