Arrays 链表与数组:物理内存中哪个更连续?

Arrays 链表与数组:物理内存中哪个更连续?,arrays,c,caching,memory,Arrays,C,Caching,Memory,数组在物理内存中不一定是连续的,尽管它们在虚拟地址空间中是连续的。但是可以说,与链表相比,物理内存中数组的“整洁度”要高得多吗?那么,对于缓存友好型程序来说,哪一个更好呢?连续内存比非连续内存更适合缓存的原因有两个: 如果数据是连续存储的,那么数据可能存储在更少的内存中(在大多数平台上是64字节块)。在这种情况下,所有数据都将装入缓存的可能性更高,加载新缓存线的频率也会更低。如果数据不是连续存储的,而是分散在许多随机内存位置,则每个缓存线中可能只有一小部分包含重要数据,而其余缓存线则包含不重要的

数组在物理内存中不一定是连续的,尽管它们在虚拟地址空间中是连续的。但是可以说,与链表相比,物理内存中数组的“整洁度”要高得多吗?那么,对于缓存友好型程序来说,哪一个更好呢?

连续内存比非连续内存更适合缓存的原因有两个:

  • 如果数据是连续存储的,那么数据可能存储在更少的内存中(在大多数平台上是64字节块)。在这种情况下,所有数据都将装入缓存的可能性更高,加载新缓存线的频率也会更低。如果数据不是连续存储的,而是分散在许多随机内存位置,则每个缓存线中可能只有一小部分包含重要数据,而其余缓存线则包含不重要的数据。在这种情况下,需要更多的缓存线来缓存所有重要数据,如果缓存不够大,无法存储所有这些缓存线,那么缓存效率将降低

  • 硬件在预测下一个要预取的缓存线方面会做得更好,因为很容易预测顺序访问模式。根据链表的元素是否分散,对链表的访问模式可能是随机和不可预测的,而对数组的访问模式通常是顺序的

  • 您是对的,即使数组在中连续存储,也不一定意味着数组也在物理地址空间中连续存储

    但是,这与我在回答的#1)中所作的陈述无关,因为缓存线不能与缓存线的边界重叠。在虚拟地址空间和物理地址空间中,单个内存页的内容始终是连续的

    但你是对的,这可能与我在回答第2段中的陈述有关。假设内存页大小为4096字节(在x64平台上是标准的),缓存线大小为64字节,则每个内存页有64条缓存线。这意味着每64条缓存线都可能位于物理地址空间中的“跳转”边缘。因此,每64条缓存线都可能被硬件缓存预取器预测失误。此外,缓存预取器可能无法立即适应这种新情况,因此在能够可靠地再次预测下一个缓存线并及时预加载它们之前,它可能无法预取多个缓存线。然而,作为一名应用程序程序员,您不必担心这一点。操作系统负责安排虚拟内存空间到物理内存空间的映射,这样就不会有太多可能对性能产生负面影响的“跳跃”。如果您想阅读更多关于此主题的内容,您可能需要阅读以下研究论文:


    通常,数组在缓存效率方面优于链表,因为它们总是连续的(在虚拟地址空间中)。

    我认为这个问题只关注一个问题!我投票赞成重新讨论这个问题。即使这篇文章包含几个问题,这些问题也是如此密切相关,以至于它们实际上是一个问题。此外,我不认为这个问题太广泛。