简体   繁体   English

用户空间中的虚拟内存地址范围

[英]The range of virtual memory address in userspace

In linux, the range of virtual memory address in userspace, in other words, the range of value returned by malloc, is same as entire 64bits virtual memory space? 在Linux中,用户空间中虚拟内存地址的范围(即malloc返回的值的范围)与整个64位虚拟内存空间相同吗? Or, is there any sub-range of 64bits virtual memory space which is guaranteed not to be seen in userspace? 或者,是否有保证不能在用户空间中看到的64位虚拟内存空间的任何子范围?

Answers for UNIX system or Windows system are welcome. 欢迎回答UNIX系统或Windows系统。

Of course I don't intend to introduce such buggy codes depending on this into some production. 当然,我不打算将这种错误代码引入某些产品中。 I just imagine that if there is a spare space, we can use the space to store flgas, for example is_constructed flag for lazy construction, and can spare much space. 我只是想象,如果有一个备用空间,我们可以使用该空间来存储flgas,例如is_constructed标志用于延迟构造,并且可以节省很多空间。 Usually, 1byte (stack) allocation is needed even if we use only 1bit. 通常,即使我们仅使用1bit,也需要1byte(堆栈)分配。 In addition, such value encoding into memory address may cause wrong memory prefetch or branch misprediction. 此外,将这种值编码到内存地址中可能会导致错误的内存预取或分支错误预测。 Then, I want to check which of saving memory-bandwidth and CPU misprediction is larger. 然后,我要检查节省内存带宽和CPU错误预测中哪个较大。

The possible range of virtual addresses is processor and kernel and ABI specific . 虚拟地址的可能范围取决于 处理器内核以及ABI But I strongly advise against coding some tricks related to some bits in addresses and pointers (since your code might work on some processors, but not on others). 但是我强烈建议您不要编码一些与地址和指针中的某些位有关的技巧(因为您的代码可能在某些处理器上有效,而在其他处理器上则无效)。

These days, some * x86-64 processors apparently use only 48 bits of the virtual address space, but I don't recommend using that knowledge in your code (it might be wrong within a few years, or on some higher end models). 如今某些 * x86-64处理器显然只使用了48位虚拟地址空间,但我不建议在您的代码中使用该知识(几年内或某些高端型号可能会出错)。 See also x86-64 ABI . 另请参见x86-64 ABI

If a pointer is outside that 48 bits range, you get a page fault, ie a SIGSEGV, the processor is not ignoring the unimplemented bits. 如果指针超出48位范围,则会出现页面错误,即SIGSEGV,处理器不会忽略未实现的位。 So upper bits of pointers or addresses should be all zeros or all ones. 因此,指针或地址的高位应全为零或全为1。

On Linux, you might play with cat /proc/self/maps and cat /proc/$$/maps to get more clues. 在Linux上,您可以使用cat /proc/self/mapscat /proc/$$/maps以获得更多线索。

BTW, on Linux, you could reserve, using mmap(2) with MAP_ANONYMOUS | MAP_NORESERVE 顺便说一句,在Linux上,您可以使用带有MAP_ANONYMOUS | MAP_NORESERVE mmap(2)进行MAP_ANONYMOUS | MAP_NORESERVE MAP_ANONYMOUS | MAP_NORESERVE , some large address range (and either later call mmap with MAP_FIXED inside it, or never use it) to avoid it being later used by your process (or, as commented by damon , use MAP_32BITS which is x86-64 specific) This is probably more sensible than relying on the address bits to be restricted to 48 bits. MAP_ANONYMOUS | MAP_NORESERVE ,一些较大的地址范围(以及以后在其中调用带有MAP_FIXED mmap ,或者从不使用它)以避免它稍后被您的进程使用(或者,如damon所评论的那样,使用特定于x86-64的MAP_32BITS )可能比将地址位限制为48位更为明智。

Also, catching SIGSEGV on Linux is tricky (you'll need some processor specific code) and costly. 另外,在Linux上捕获SIGSEGV 棘手 (您将需要一些处理器特定的代码)且成本很高。 Perhaps you want some external pager mechanism (which exists on GNU Hurd, but not on Linux). 也许您需要某种外部寻呼机机制 (在GNU Hurd上存在,但在Linux上不存在)。 Or mmap -ing some pseudo-file on some FUSE filesystem. 或者mmap在某些FUSE文件系统上添加一些伪文件。

NB: most x86-64 processors have only 48 bits of addresses, but I don't recommend using that. 注意:大多数x86-64处理器只有48位地址,但是我不建议使用该地址。

Note 2: Processor makers remembered what IBM/360 did: ignoring the upper address bits (originally 24 bits). 注2:处理器制造商记得IBM / 360所做的事情:忽略了高地址位(最初为24位)。 When IBM had to extend address to 31 bits it was a nightmare for the software industry. 当IBM必须将地址扩展到31位时,这对于软件行业来说是一场噩梦。 So hardware makers understood the lesson, and disallow today (in hardware) playing naughty tricks on unused address bits. 因此,硬件制造商了解了这一教训,并禁止今天(在硬件中)对未使用的地址位进行顽皮的欺骗。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM