【问题标题】:Contiguous Memory Allocation in C and Memory Access LatencyC 中的连续内存分配和内存访问延迟
【发布时间】:2018-05-30 17:40:39
【问题描述】:

我正在阅读这篇论文。 http://www.ece.cmu.edu/~ece447/s13/lib/exe/fetch.php?media=moscibroda.pdf

其中讨论了当前用于大多数多核架构的内存访问方法。该论文提供了当前方法在处理并发线程时的局限性示例,其中 on 访问的是连续指令中的内存和顺序指令中的其他不连续内存位置。

根据论文,在顺序指令中访问连续内存的线程将首先由内存控制器服务。我当然不怀疑这一点,但作者提供了两个代码来说明一个连续内存被顺序访问的应用程序和一个连续内存不被顺序访问的应用程序。这是代码。

连续内存访问

// initialize arrays a, b
for (j=0; j<N; j++)
    a[index[j]] = b[index[j]];
for (j=0; j<N; j++)
    index[j] = j; // streaming index
for (j=0; j<N; j++)
        b[index[j]] = scalar * a[index[j]];

非连续内存访问

// initialize arrays a, b
for (j=0; j<N; j++)
   index[j] = rand(); // random # in [0,N]
 for (j=0; j<N; j++)
    a[index[j]] = b[index[j]];
for (j=0; j<N; j++)
  b[index[j]] = scalar * a[index[j]];

我的问题是,如果您要在 C 中实现此代码并为 x86 或 ARM 编译它,然后在某些操作系统(例如 Linux)上运行它,您能否保证您正在分配的原始缓冲区的内存位置物理上是连续的吗?它们不只是虚拟连续内存吗(除非使用了类似 kmalloc() 的 Linux 方法)?

*注:作者指定提供的代码是伪代码,所以也许我对实现的困惑是没有根据的。

【问题讨论】:

  • 您认为什么是“原始缓冲区”?你的意思是声明的数组abindex
  • 您阅读的代码可能比现有的更多。代码不是伪代码,而是实际的 C。连续保证的关键是使用了 arrays。数组(相对于指向类型指针的指针)保证所有元素的顺序内存位置。在连续内存访问代码中,您只是按顺序迭代连续元素,其中非连续示例迭代数组中的随机索引。
  • @DavidC.Rankin。他们是吗?它们在虚拟内存中肯定是连续的,因为我可以使用 C 迭代器操作使用指针来迭代虚拟内存中的位置。这是否也适用于内存中虚拟内存位置的物理值? IE创建数组时,编译器是否在虚拟内存映射中选择物理位置连续的一组位置?
  • @JackFrye 即使页面不连续,每个的页面上都有PAGE_SIZE字节,这很重要。
  • @AnttiHaapala 这意味着他的代码只是伪代码,实现将完全依赖于操作系统。他提到他在 Windows XP 上进行了测试。您所描述的是 GNU Linux API。此代码不能用于任何 N。它必须是伪代码。对吗?

标签: c multithreading memory memory-management


【解决方案1】:

我的问题是你是否要在 C 中实现这段代码并编译它 对于 x86 或 ARM,然后在某些操作系统上运行它,比如 Linux,会 你有任何保证原始的内存位置 您分配的缓冲区在物理上是连续的吗?

回答:是的

代码不是伪代码,它是实际的 C(仅缺少 % N,模运算符,需要限制 rand()0-(N-1) 的返回)。连续保证的关键是使用了 arrays。 C 中的数组(相对于 指向类型指针的指针)。这保证了虚拟内存中所有元素的顺序内存位置(这通常是现代内存管理器分配的唯一类型的内存)。

在连续内存访问代码中,您只是按顺序迭代连续元素,而非连续示例迭代数组中的随机索引。

您的困惑并非没有根据,因为在很多情况下,对象的集合并不能保证相邻元素在内存中是连续的,但是作者在示例中指定使用 arrays 来保证所有元素是顺序的(根据定义)。

通过使用rand() 使非连续示例中的访问变得非连续(这是伪的,因为它缺少% N,但不是语法)(例如index[j] = rand() % N; 将限制分配给0-N,但不保证涵盖所有索引)从我的阅读来看,该示例的目的是强调连续块内的直接顺序访问,而非连续示例只是作为反例提供,其中作者说明随机访问顺序块中的不同元素。

【讨论】:

  • “保证虚拟内存中所有元素的顺序内存位置” - 是的,但是当尝试优化程序以获得关于内存延迟的最佳性能时,它是虚拟地址空间 -重要的连续性,还是物理地址空间连续性?鉴于(AFAIK)RAM 模块对操作系统级别的结构(如页表)一无所知,我怀疑是后者。
  • 这需要博士学位论文才能完全回答这个问题(我没有声称在硬件或内存管理器中拥有,法律是的)我怀疑是前者关键方面。如果(我说如果),内存管理器足够聪明,可以将物理地址空间的非连续部分捆绑在一起,并将其作为连续的虚拟地址块提供给程序,我认为程序不会有任何了解或关心的方式。这是我的怀疑,不多也不少。
  • 是的@DavidC.Rankin 我认为我们在这里缺少一个很难谈论的硬件方面,因为它因操作系统和硬件架构而异。对于@JeremyFriesner 而言,我认为问题在于虚拟地址空间如何映射到物理 RAM 位置。作者关注的是硬件的物理内存访问模式。我担心的是,他编写的第一个 C 代码并不能保证连续的虚拟内存访问将对应于 RAM 控制器的连续物理内存访问
  • 是的,我看到了这个问题,我只是不确定是否有一个基于您所解决问题的通用答案。机器原理、Harvard 和 Von Neumann 架构并没有改变,但是它们的使用方式以及分散在地址和数据总线上的高速缓存的组合发生了变化。我认为您的问题是否存在“保证连续虚拟内存访问将对应于 RAM 控制器的连续物理内存访问”的确切答案必须取决于控制器的实现。这对我来说几乎是巫术:)
猜你喜欢
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-22
  • 1970-01-01
  • 2015-03-08
  • 1970-01-01
  • 2013-11-14
相关资源
最近更新 更多