假设内存页面大小是2的幂是否安全?

时间:2016-11-10 00:57:54

标签: c linux

我目前正在开发一个便携式C程序,它利用内存页面大小(由sysconf(_SC_PAGESIZE)返回)。我知道大多数情况下页面大小是2的幂,以允许使用按位运算进行有效管理;不过,我发现无法保证这一点。那么假设页面大小是2的幂是多么安全?是否有任何不满足这种条件的架构示例?

2 个答案:

答案 0 :(得分:3)

虽然我找不到任何明确的陈述,即页面大小必须是2的幂,但我认为这是一个非常合理的假设。 POSIX的“对齐”概念(参见posix_memalign)是根据两个权力来定义的,而不是任意的除数 - 具体来说,对齐参数必须是sizeof(void*)的两倍幂 - 并且看来你应该能够通过这个界面实现页面对齐的内存。除此之外,所有真实世界的架构都使用两种页面大小的功能,并且没有合理的理由来改变它;其他任何东西在硬件上的成本都要高得多。

答案 1 :(得分:1)

1)通过计算Linux内核中的页面大小来保证它。这不是正式标准意义上的保证,但由于已经陈述的所有原因,这种方法不太可能发生变化。

来自/usr/src/kernels/<your_kernel>/include/asm-generic/page.h

#define PAGE_SHIFT      12
#ifdef __ASSEMBLY__
#define PAGE_SIZE       (1 << PAGE_SHIFT)
#else
#define PAGE_SIZE       (1UL << PAGE_SHIFT)
#endif

正如您所看到的,页面大小实际上是根据班次定义的,因此总是2的幂。请注意,此代码用于通用体系结构案例,并且该特定体系结构为PAGE_SHIFT定义了不同的值。

2)实际上,您可以通过getconf程序在终端输入getconf PAGESIZE来获取页面大小。这可以用于生成快速编译时检查,这比编写可能从未使用过的备份案例要容易得多。

3)页面大小由MMU决定。因此,您最接近正式标准的是来自不同制造商的处理器文档。例如,英特尔软件开发人员手册第3A卷中的表4-1列出了英特尔处理器中的分页模式和页面大小的详尽列表:

Intel Page Sizes

4)我可以告诉你,每个主要的处理器架构都使用2的幂的页面大小。

5)实际上存在一个主要问题 - 物理内存空间的碎片 - 如果不这样做的话。页面和页面框架大小需要相等,因此如果您具有两个页面大小的非幂,那么您将获得两个页面框架的非幂。假设您在页面框架大小为3000的系统上(为了简化示例)总共有32个页面框架。因此,物理地址长17位,5位用于选择页帧,12位用于寻址3000字节。

00000 0000 0000 0000
\___/ \____________/
  |             \
(page frame)  (page offset)

如果页面大小(页面帧大小)等于2的幂,则从00000 0000 0000 000011111 1111 1111 1111的整个物理内存空间都是有效地址。如果页面框架大小为3000,那么从XXXXX 1011 1011 0111(最后一个有效地址)到XXXXX 1111 1111 1111的物理地址空间中会有一个间隙。这并不是说这样的系统无法使用,但是它无可估量地增加了可怕的复杂性。