C 假设内存页大小是2的幂,安全吗?

C 假设内存页大小是2的幂,安全吗?,c,linux,C,Linux,我目前正在开发一个利用内存页大小的便携式C程序(由sysconf(_SC_PAGESIZE)返回)。我知道页面大小通常是2的幂,以便使用位操作进行有效管理;不过,我在任何地方都找不到这方面的保证。那么,假设页面大小是二的幂有多安全呢?有没有架构不满足这个条件的例子?虽然我找不到任何明确的声明,页面大小必须是2的幂,但我认为这是一个非常合理的假设。POSIX的“对齐”概念(请参见POSIX_memalign)是根据两个除数的幂定义的,而不是任意除数的幂定义的-具体地说,对齐参数必须是sizeof(

我目前正在开发一个利用内存页大小的便携式C程序(由sysconf(_SC_PAGESIZE)返回)。我知道页面大小通常是2的幂,以便使用位操作进行有效管理;不过,我在任何地方都找不到这方面的保证。那么,假设页面大小是二的幂有多安全呢?有没有架构不满足这个条件的例子?

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

1)这是通过计算Linux内核中的页面大小来保证的。从正式标准的意义上来说,这并不是一种保证,但由于已经说明的所有原因,这种方法不太可能改变

/usr/src/kernels//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

如果页面大小(页面帧大小)等于二的幂,则从
000000000
1111111111111111111
的整个物理内存空间都是有效地址。如果页面帧大小为3000,则物理地址空间中从
XXXXX 1011 1011 0111
(最后一个有效地址)到
XXXXX 1111 1111 1111
之间会有一个间隙。这并不是说这样的系统不能使用,但它会增加可怕的复杂性,我想不出任何原因。

因为MMU不包括除法器,而是使用位屏蔽将虚拟地址拆分为桌面漫游的部分,这是一个安全的赌注。为什么你需要假设你是否能检索到大小?@skrrgwasme:他的算法可能会受益于二次幂的数组。例如,FFT会。@skrrgwasme:同样的原因,它通常是二的幂:能够使用位运算,也能够重复一半的页面。直到它们出现在基于三值逻辑的计算机上,你是非常安全的。:)我不知道
memalign
函数系列;现在我知道我也需要它们。谢谢任何其他页面大小都需要在PMMU和缓存的高度时间关键路径中使用真正的除法/余数。即架构x86、ARM、PPC、POWER、MIPS、SPARC、SuperH、ColdFire/68XXX,具有2页大小的所有功能。给我看一个没有的,我给你看一个非常破烂的设计…@VictorSchubert:总是使用最常用的函数。C标准已经提供了
对齐的\u alloc
,无需使用posix版本(正如您已经询问的可移植性问题)。另外:它们不需要实现的支持。在手册页中:“posix_memalign()函数是咨询信息选项的一部分,不需要在所有实现中提供。”@Olaf:posix比C11存在的时间更长,实现的范围更广,但是这里提到的
posix_memalign
与您是否应该这样做无关,而是揭示了POSIX的对齐思想,这些思想(或应该)与页面大小的概念相关。@R..:每个相关的POSIX兼容系统都有一个兼容C11的实现。对于大多数非POSIX托管的环境,也有一个。因此,C11支持的系统集应该大于POSIX系统集。不提供C11兼容性的系统也可能不遵循POSIX。X88只覆盖了所有Linux实现的少数,如果您考虑其他OS也就更少了。虽然我同意这一点,但没有理由认为有人会实现页面大小为2的powers以外的其他功能,单CPU文档很难证明这一点。你最后一段有点混乱。物理地址中的间隙也将是逻辑空间中的间隙,这是无法容忍的。但(用余数)除法将避免两者兼而有之。这只是成本(时间和空间)与收益的比例。这样一个单元是不可接受的。MMU总是可以在碎片化的物理内存空间之上提供逻辑一致的虚拟地址空间,因此虚拟内存空间不一定是碎片化的。但物理内存无法绕过它。正如我所写的,这将涉及真正的除法,包括余数,而不是掩蔽!正如其他CPU和硬件设计师所确认的那样,这绝对是不可能的!
00000 0000 0000 0000
\___/ \____________/
  |             \
(page frame)  (page offset)