c - 我们如何为变量指定物理地址?

标签 c linux performance caching memory-address

欢迎任何建议/讨论!

这个问题实际上作为标题很简短,但我会解释为什么我需要实际地址。


背景:

这些天我对缓存和多核架构着迷,现在我很好奇在并行环境下缓存如何影响我们的程序。

在某些 CPU 型号(例如,我的 Intel Core Duo T5800)中,L2 缓存在内核之间共享。因此,如果程序 A 正在访问物理地址处的内存,如

0x00000000, 0x20000000, 0x40000000...

程序B访问数据在

0x10000000, 0x30000000, 0x50000000...

由于这些地址共享相同的后缀,因此二级缓存中的相关集合将被频繁刷新。我们预计会看到两个程序互相争斗,缓慢地从内存而不是缓存中读取数据,尽管它们在不同的内核中是分开的。

然后我想在实践中验证结果。在这个实验中,我必须知道物理地址而不是虚拟地址。但是我该如何应对呢?


第一次尝试:

从堆中吃一大块空间,掩码,得到某个地址。

我的 CPU 有一个二级缓存,大小为 2048KB,关联性为 8,所以像 0x12340000, 0x12380000, 0x123c0000 这样的物理地址将与二级缓存中的第一组相关。

int HEAP[200000000]={0};
int *v[2];
int main(int argc, char **argv) {

    v[0] = (int*)(((unsigned)(HEAP)+0x3fffc) & 0xfffc0000);
    v[1] = (int*) ((unsigned)(v[0]) + 0x40000); 

    // one program pollute v[0], another polluting v[1]
}

遗憾的是,在虚拟内存的“帮助”下,变量 HEAP 在物理内存中并不总是连续的。 v[0]v[1] 可能与不同的缓存集有关。


第二次尝试

访问/proc/self/mem,尝试获取内存信息。

嗯……看来结果还是关于虚拟内存的。

最佳答案

您对内存和这些地址的理解不完整/不正确。本质上,您尝试测试的内容是徒劳的。

在用户模式进程的上下文中,您看到的几乎每个地址都是 virtual address .也就是说,只有在该进程的上下文中才有意义的地址。操作系统管理此虚拟内存空间(对进程唯一)映射到内存页面的位置的映射。这些内存页面在任何给定时间可能映射到页面调入页面(即驻留在物理 RAM 中)- 或者它们可能被页面调出,并且仅存在于磁盘上的交换文件中。

因此,要解决背景 示例,这些地址来自两个不同的进程 - 尝试比较它们绝对没有任何意义。他们的代码是否存在于任何缓存中取决于许多因素,包括 cache-replacement strategy处理器的数量、操作系统启用的缓存策略、其他进程(包括内核模式线程)的数量等。

在您的第一次尝试中,您仍然无法直接实际测试 CPU 缓存。首先,你的大缓冲区不会在堆上。它将成为可执行文件的数据部分(特别是 .bss)的一部分。堆用于内存分配的 malloc() 系列。其次,如果你分配一些巨大的 1GB 区域并不重要,因为尽管它在你的进程的虚拟地址空间中是连续的,但操作系统会在它认为合适的地方分配虚拟内存页面 - 这可能 < em>不实际上是连续的。同样,您几乎无法控制用户空间的内存分配。 “Is there a way to allocate contiguous physical memory from userspace in linux?”简短的回答是否定的。

/proc/$pid/maps 也不会让您到达任何地方。是的,那里列出了很多地址,但同样,它们都在进程 $pid 的虚拟地址空间中。有关这些的更多信息:How do I read from /proc/$pid/mem under Linux?

关于c - 我们如何为变量指定物理地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13946728/

相关文章:

html - 如何授予 apache 从目录中检索图像的权限?

java - 哪些操作系统支持在 Java 中监视 native (类似 inotify 的)文件

c# - C# 中的简单循环(移动平均)数组

c++ - LD_LIBRARY_PATH 和 LD_LIBRARY_PATH 有什么区别?

c - 将已定义结构的指针初始化为全局变量

c - 如何将变量值传递给 C 中的数组

c - 关闭套接字的问题。程序暂停

regex - makefile 目标上的多个词干

java - ApacheFOP 未利用足够的系统资源

java - Java中有多少个JDBC连接?