我正在读这篇论文。 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方法)吗?
*注意:作者指出所提供的代码是伪代码,所以也许我的执行困境是没有根据的。
答案 0 :(得分:0)
我的问题是你是否要在C中实现这个代码并进行编译 对于x86或ARM,然后在某些操作系统上运行它,比如说Linux 你有任何保证原始的内存位置 你分配的缓冲区是否物理连续?
答案:是
代码不是伪代码,它是实际的C(仅缺少O(1)
,模数运算符,需要限制% N
从rand()
的返回。连续保证的关键是使用数组。 C中的数组(与指向指针的指针相对)。这保证了虚拟内存中所有元素的顺序内存位置(通常是现代内存管理器发布的唯一内存类型)。
在连续内存访问代码中,您只是迭代连续元素 in-order ,其中非连续示例迭代数组中的随机索引。
你的窘境并非没有根据,因为在很多情况下,对象集合不保证相邻元素在内存中是连续的,但是作者在示例中指定使用 arrays 来保证所有元素是顺序的(根据定义)。
使用0-(N-1)
(因为它缺少rand()
,因为它缺少% N
而不是语法中的伪),非连续示例中的访问不连续(例如{{ 1}}会将赋值限制为index[j] = rand() % N;
,但不能保证涵盖所有索引。从我的阅读中,示例的意图是强调连续块内的直接顺序访问,并且简单地提供了非连续的示例作为一个例子,作者说明了随机访问顺序块中的不同元素。