Memory 如何获取页面大小

Memory 如何获取页面大小,memory,kernel,Memory,Kernel,我在一次采访中被问到这个问题,请告诉我答案:- 您没有内核的文档。您只知道您的内核支持分页。 你将如何找到页面大小?没有可以告诉您页面大小的标志或宏 我得到了提示,因为你可以利用时间得到答案。我仍然没有任何线索。在我看来,这就像是一个关于“分页实际上是如何工作的”的问题 他们希望您解释更改页面大小对系统执行的影响 我对这些东西有点生疏,但是当一个页面满了,系统开始交换页面,这会减慢速度。因此,您希望运行一些将内存填充到不同大小的程序,并测量执行任务所需的时间。在某个点上会有一个跳跃,完成任务所花

我在一次采访中被问到这个问题,请告诉我答案:-

您没有内核的文档。您只知道您的内核支持分页。 你将如何找到页面大小?没有可以告诉您页面大小的标志或宏


我得到了提示,因为你可以利用时间得到答案。我仍然没有任何线索。

在我看来,这就像是一个关于“分页实际上是如何工作的”的问题 他们希望您解释更改页面大小对系统执行的影响

我对这些东西有点生疏,但是当一个页面满了,系统开始交换页面,这会减慢速度。因此,您希望运行一些将内存填充到不同大小的程序,并测量执行任务所需的时间。在某个点上会有一个跳跃,完成任务所花费的时间会突然跳跃


就像我说的,我对这样做的实现有点生疏。但我很确定这就是他们想要的答案。

运行如下代码:

for (int stride = 1; stride < maxpossiblepagesize; stride += searchgranularity) {
    char* somemem = (char*)malloc(veryverybigsize*stride);
    starttime = getcurrentveryaccuratetime();
    for (pos = somemem; pos < somemem+veryverybigsize*stride; pos += stride) {
        // iterate over "veryverybigsize" chunks of size "stride"
        *pos = 'Q'; // Just write something to force the page back into physical memory
    }
    endtime = getcurrentveryaccuratetime();
    printf("stride %u, runtime %u", stride, endtime-starttime);
}
for(int-stride=1;stride
将结果与X轴上的跨步和Y轴上的运行时一起绘制。在stride=pagesize处应该有一个点,此时性能不再下降

这会导致许多页面错误。一旦跨步超过页面大小,错误的数量就会停止增加,因此程序的性能不再明显下降


如果您想变得更聪明,可以利用
mprotect
系统调用必须在整个页面上工作这一事实。用小一点的试试,你会得到一个错误。我肯定还有其他类似的“漏洞”——但是上面的代码可以在任何支持分页并且磁盘访问比RAM访问更昂贵的系统上使用。这将是每一个半正常的现代系统。

无论他们期望得到什么答案,这几乎肯定是一个脆弱的解决方案。首先,您可以有多个页面大小,因此对于一个小的分配,您可能得到的任何答案都可能与下一个多兆字节的分配无关(请参阅Linux支持之类的内容)

我怀疑这个问题更多的是为了看看你是如何解决这个问题的,而不是你想出的最终解决方案


顺便说一句,这个问题与linux无关,因为您确实有相关文档以及POSIX合规性,您只需调用sysconf(_SC_PAGE_SIZE)。

最基本的分页与交换无关。它是关于将物理内存分割成固定大小的块,这样每个块都可以有自己的属性(例如,可写、可执行),并且可以在虚拟内存(与物理内存相反)中不连续地重新排列它们。然后,我们可以利用页面错误来实现交换。请注意,系统在物理RAM已满(或更早)时开始交换,而不是在单个页面已满时。对于Unix系统,mprotect是一个很好的观点,但它不是通用的@Borealid@Jon我给出了类似的答案,正如你们在这里根据页面错误和性能基础所解释的。就连我也试着用块写的方式将读/写操作和时间联系起来,但看起来这些家伙没给我留下深刻印象(