C 如何为变量指定物理地址?

C 如何为变量指定物理地址?,c,linux,performance,caching,memory-address,C,Linux,Performance,Caching,Memory Address,欢迎提出任何建议/讨论 这个问题的标题其实很简单,但我会解释为什么我需要实际地址 背景: 这些天来,我对缓存和多核架构非常着迷,现在我很好奇,在并行环境下,缓存是如何影响我们的程序的 在某些CPU型号中(例如,我的Intel Core Duo T5800),二级缓存在内核之间共享。所以,如果程序A正在访问物理地址处的内存,比如 0x00000000、0x20000000、0x40000000… 和程序B在 0x10000000、0x30000000、0x50000000… 由于这些地址共享相同

欢迎提出任何建议/讨论

这个问题的标题其实很简单,但我会解释为什么我需要实际地址


背景

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

在某些CPU型号中(例如,我的Intel Core Duo T5800),二级缓存在内核之间共享。所以,如果程序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,字符**argv){
v[0]=(int*)((无符号)(堆)+0x3fffc)和0xfffc0000);
v[1]=(int*)((无符号)(v[0])+0x40000);
//一个程序污染v[0],另一个程序污染v[1]
}
遗憾的是,在虚拟内存的“帮助”下,变量
HEAP
在物理内存中并不总是连续的
v[0]
v[1]
可能与不同的缓存集相关


第二次尝试

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


嗯。。。结果似乎仍然与虚拟内存有关。

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

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

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

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


/proc/$pid/maps
也不会带你去任何地方。是的,其中列出了很多地址,但同样,它们都在进程
$pid
的虚拟地址空间中。关于这些方面的更多信息:

我认为您不能指定物理地址,至少在没有内核更改的情况下是这样。但您可以使用/proc/self在批量级别了解物理地址/maps@anishsane嗯,我转储了
/proc/self/maps
,但它与物理地址有什么关系?第一个字段似乎是虚拟地址,
dev
字段与内存设备相关吗?哦,对不起,是的,前两个字段确实是虚拟地址。。。我用它来获取一些虚拟地址,这些地址对应于我打开的PCI设备的物理条地址。。。抱歉误导…在现代桌面CPU上,在物理地址级别操作并不容易。在小型微控制器上编写汇编程序很容易,但您不会观察到缓存(我知道的那些没有缓存)的影响。您是对的,如果我们只是尝试访问单个地址,它可能会被分派到其他进程。但是,我尝试访问的是某种类型的物理地址(比如0x???0000)。如果我们知道大数组中的哪个位置符合我们的条件,这会有所帮助。您试图从usermode程序访问的任何地址都不是物理地址。这是一个虚拟地址,你不知道它将映射到物理地址空间中的何处。嗯,当我们有足够的资源(比如超过2个内核,很多内存)时,我们是否可以假设操作系统不会分页/重新映射页面,环境是否足够稳定?内核的数量与内存的分页进出无关。事实上,更多的CPU内核可能会使进程更容易分页。当然,如果您有无限的RAM,那么您的交换分区利用率将几乎为零。但是这对你有什么好处呢?如果你想了解缓存的性能,你可以简单地对循环中某些代码的第一次执行进行计时,并将其与后续迭代进行比较