谁决定内存访问模式?

Posted

技术标签:

【中文标题】谁决定内存访问模式?【英文标题】:Who decides the memory access pattern? 【发布时间】:2021-08-29 02:07:30 【问题描述】:

我正在尝试了解内存访问模式。我的问题很简单。

我通过将参数提供给gcc 来决定我的程序的模式。因此,我可以根据我的代码进行设置。 我的操作系统决定了内存访问模式。因此,我无法为我的任何程序更改它。 我的 CPU 决定使用哪种内存访问模式。因此,我的 PC 上运行的任何操作系统都使用该模式。

【问题讨论】:

取决于你所说的记忆模式。 CPU 硬件能够处理物理内存访问和到这些物理页面的虚拟内存映射。操作系统将分配物理页面并对虚拟内存页表进行编程。当你 malloc 时,你会得到一个线性的虚拟内存范围,后面可能有分散的物理页面。一般来说,HW是how,OS是what,app只是OS提供的用户 每当我让 CPU 访问内存时,由于我的代码实现,我想使用最近邻内存访问模式。是否可以?另一种方法是,在运行我的程序之前,我怎么知道将使用哪种模式?我是新手,如果我的问题很垃圾,请见谅。 看来您实际上是在寻找算法,与 CPU/OS/Compile 标志无关。您必须使用数组将其实现为算法,例如我在 SO:***.com/questions/7862190/… 您将数据放入一个或多个数组中,并以您理解的某种结构组织它,这样您就可以走最近的邻居。 除非您访问的数据驻留在单个内存页面中,否则您无法保证程序的实际物理内存访问模式,因为操作系统可以在物理内存中的任何位置分配您的虚拟内存。见here 【参考方案1】:

谁决定内存访问模式?

主要是;编写代码的人通过他们做出的选择来决定内存访问模式。

举个愚蠢的例子;如果你决定遍历一个数组(比如for(i = 0; i <= size; i++) do_something(&my_array[i]); ),那么你就产生了一个很好的线性访问模式;如果您决定改为遍历链表(例如while(current != NULL) do_something(current); current = current->next; ),那么您可能会遇到相对不稳定的访问模式。

但是;在某些情况下,编译器/链接器可能会尝试优化内存访问模式。这主要只是稍微改变了细节(单个读/写的确切顺序,而不是整体模式本身),但在某些情况下,编译器可以进行更明显的优化(主要涉及嵌套循环和数组)。

注意 1:结果很可能是“虚拟内存访问模式”。下面会有一个完整的内存层次结构——操作系统将控制虚拟内存到物理内存的映射(并处理交换空间等事情);然后将有多个级别的缓存和其他内置在硬件中的“类似缓存的东西”。这些都不重要。它使实际访问的内容复杂化(哪个缓存的哪个部分,或者哪个物理内存,或者交换空间的哪个部分,或者......),但是无论什么访问仍然会以相同的顺序(和相同的模式)发生实际上正在被访问。

注 2:典型的程序很少是简单/单一的算法。如果一个程序(网络浏览器、计算机游戏、编译器……)有数百个片段,那么程序的访问模式将是每个片段的单独访问模式的某种组合。

【讨论】:

我想检查一下我是否理解正确。根据汇编代码,CPU 选择了合适的内存访问模式,它可以随时改变。例如;在10-20行之间,使用线性访问模式,60-80行,可以使用分散模式。我说的对吗? @Prihex:为了使软件正常工作,CPU 必须严格保证其执行任务。这些严格的保证足够灵活,允许 CPU 在完成某些内存访问时进行一些小的优化,但是以有意义的方式改变整体访问模式是不够的。如果程序集描述了线性访问模式,CPU 就不能忽略代码并去踢球。 嗯,主要访问模式由 CPU 架构师描述。根据我的代码,它可以改变。例如'mov bx, 2' 然后'mov ax, [100]'。第二个有内存操作。在此之前,将 bx 设置为 2 将导致第二次操作的线性模式。所有这一切都是一个例子。但是,是这样的吗? @Prihex:单个内存访问不足以建立模式。如果你有mov ax,[100]然后mov [200],ax然后mov bx,[300]; CPU 将别无选择,必须按照给定的顺序进行这些访问(这恰好是线性访问模式,因为这就是代码所说的)。如果你有mov ax,[100] 然后mov bx,[200] 然后mov [300],ax; CPU 将被允许以任何顺序执行前 2 次加载(但最后一个存储必须是最后一个并且 CPU 无法更改)。 @Prihex:主要是;内存排序规则(特别是对于 80x86)的设计使得 CPU 只能在不太可能导致差异时重新排序内存访问;这意味着(除了少数罕见的特殊情况)您可以假设 CPU 将按照程序的顺序进行内存访问(即使理论上可能不是)。

以上是关于谁决定内存访问模式?的主要内容,如果未能解决你的问题,请参考以下文章

调试模式下内存映射向量的读取访问冲突

对于缓存的 GPU,哪种内存访问模式更有效?

如何高效的访问内存

如何高效的访问内存

内存模式下的H2数据库无法被Console访问

如何优化间接基数排序? (又名如何优化不可预测的内存访问模式)