在linux中,用户空间中的虚拟内存地址范围,换句话说,malloc返回的值范围,与整个64位虚拟内存空间相同? 或者,是否存在64位虚拟内存空间的子范围,保证不会在用户空间中看到?
欢迎使用UNIX系统或Windows系统的答案。
当然,我不打算将这些错误代码引入某些产品中。 我想象一下,如果有一个备用空间,我们可以使用空间存储flgas,例如用于懒惰构造的is_constructed标志,并且可以节省很多空间。通常,即使我们仅使用1位,也需要1字节(堆栈)分配。另外,这种编码到存储器地址中的值可能导致错误的存储器预取或分支错误预测。然后,我想检查哪个节省内存带宽和CPU误预测更大。
答案 0 :(得分:3)
虚拟地址的可能范围是处理器和内核和ABI特定的。但我强烈建议不要编写与地址和指针中的某些位相关的一些技巧(因为你的代码可能在某些处理器上有效,但在其他处理器上则无效)。
现在,某些 * x86-64处理器显然只使用了48位的虚拟地址空间,但我不推荐在代码中使用知识(在几年内可能是错误的,或者在某些高端模型上)。另请参阅x86-64 ABI。
如果指针位于48位范围之外,则会出现页面错误,即SIGSEGV,处理器不忽略未实现的位。因此,指针或地址的高位应全部为零或全部为。
在Linux上,您可以使用cat /proc/self/maps
和cat /proc/$$/maps
来获取更多线索。
MAP_ANONYMOUS | MAP_NORESERVE
保留一些大的地址范围(以及稍后在其中调用mmap
和MAP_FIXED
,或从不使用它)以避免以后被你的进程使用(或者,如damon所评论的那样,使用特定于x86-64的MAP_32BITS
这可能比依赖地址位更合理限制为48位。
另外,在Linux上捕获SIGSEGV
是tricky(您需要一些特定于处理器的代码)并且代价高昂。也许你想要一些external pager mechanism(存在于GNU Hurd上,但不存在于Linux上)。或mmap
- 某些FUSE文件系统上的某些伪文件。
注意:大多数x86-64处理器只有48位地址,但我不建议使用它。
注2:处理器制造商记得IBM/360做了什么:忽略高位地址位(最初为24位)。当IBM不得不将地址扩展到31位时,这对软件行业来说是一场噩梦。因此硬件制造商理解了这一教训,并且今天(在硬件中)不允许在未使用的地址位上玩顽皮的技巧。