C和内存访问延迟中的连续内存分配

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C和内存访问延迟中的连续内存分配相关的知识,希望对你有一定的参考价值。

我正在读这篇论文。 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方法)?

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

答案

我的问题是,如果您要在C中实现此代码并将其编译为x86或ARM,然后在某些操作系统(例如Linux)上运行它,您是否可以保证您分配的原始缓冲区的内存位置在物理上是连续的?

答:是的

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

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

您的窘境并非毫无根据,因为有许多实例,其中对象集合不保证相邻元素在内存中是顺序的,但作者在示例中指定使用数组,以保证所有元素都是顺序的(根据定义)。

使用rand()(由于它缺少% N,但在语法中没有伪),非连续示例中的访问不连续(例如index[j] = rand() % N;会将赋值限制为0-N,但不保证所有索引从我的阅读中,该示例的意图是强调连续块内的直接顺序访问,并且非连续示例仅作为对比示例提供,其中作者示出随机访问顺序块内的不同元素。

以上是关于C和内存访问延迟中的连续内存分配的主要内容,如果未能解决你的问题,请参考以下文章

JDK常用数据结构

C 程序是不是可以访问和更改分配给另一个程序的堆中的内存地址?

linux内存池能分配连续物理内存吗

C++ 中 vector 如何实现内存分配

C 中的共享内存代码片段

C之静态内存和动态内存