0

我正在读一本书,其中有这一段:

C 中的数组可以看作是一块连续的内存。更准确地说,数组的最后一维是连续的部分。我们称之为行主要顺序。了解这一点以及缓存故障在访问未缓存数据时将完整的缓存行加载到缓存中以防止后续缓存故障这一事实,我们可以看到为什么使用 array[0][0] 访问维度为 10000x10000 的数组可能会加载 array[ 0][1] 在缓存中,但是在之后访问 array[1][0] 会产生第二个缓存错误,因为它距离 array[0][0] 是 sizeof(type)*10000 字节,因此肯定不会在同一缓存行上。这就是为什么这样的迭代效率低下的原因:

#define ARRLEN 10000

int array[ARRLEN][ARRLEN];
size_t i, j;

for (i = 0; i < ARRLEN; ++i)
{
    for(j = 0; j < ARRLEN; ++j)
    {
        array[j][i] = 0;
    }
}

您能否向我解释一下他们在本段中试图解释的内容以及他们正在谈论的“缓存错误”是什么?

4

1 回答 1

12

将数组想象成书中的页面。如果每页包含 1024 个字符,那么声明为的数组a[100][1024]就像一本 100 页的书。通过阅读每一页来阅读本书的效率更高。也就是说,您按照 a[0][0]、a[0][1]、...、a[0][1023]、a[1][0] 的顺序进行迭代。即,您阅读整页,然后翻页。如果您遍历最左边的索引,就像从每一页读取一个字符,在您读取一个字符后翻页,然后当您读到书的末尾时返回第 1 页以读取第二个字符。翻页是缓存故障。

于 2021-01-03T13:36:57.203 回答