用户空间中的虚拟内存地址范围 [英] The range of virtual memory address in userspace

查看:328
本文介绍了用户空间中的虚拟内存地址范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在linux中,用户空间中虚拟内存地址的范围(即malloc返回的值的范围)与整个64位虚拟内存空间相同吗? 或者,是否有64位虚拟内存空间的任何子范围可以保证不在用户空间中看到?

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? Or, is there any sub-range of 64bits virtual memory space which is guaranteed not to be seen in userspace?

欢迎使用UNIX系统或Windows系统的答案.

Answers for UNIX system or Windows system are welcome.

当然,我不打算将这种错误代码引入某些产品中. 我只是想象,如果有一个备用空间,我们可以使用该空间来存储flgas,例如is_constructed标志用于延迟构造,并且可以节省很多空间.通常,即使我们仅使用1bit,也需要1byte(堆栈)分配.此外,将这种值编码到内存地址中可能会导致错误的内存预取或分支错误预测.然后,我要检查节省内存带宽和CPU错误预测中哪个较大.

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. Usually, 1byte (stack) allocation is needed even if we use only 1bit. 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.

推荐答案

可能的虚拟地址范围是 processor kernel

The possible range of virtual addresses is processor and kernel and ABI specific. 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).

这几天,一些 * x86-64 处理器显然只使用了虚拟地址空间的48位,但是我不建议在代码中使用该知识(几年内或之后可能会出错)一些高端型号).另请参见 x86-64 ABI .

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). See also x86-64 ABI.

如果指针超出48位范围,则会出现页面错误,即SIGSEGV,处理器 not 会忽略未实现的位.因此,指针或地址的高位应为全零或全为一.

If a pointer is outside that 48 bits range, you get a page fault, i.e. a SIGSEGV, the processor is not ignoring the unimplemented bits. So upper bits of pointers or addresses should be all zeros or all ones.

在Linux上,您可以使用cat /proc/self/mapscat /proc/$$/maps以获得更多线索.

On Linux, you might play with cat /proc/self/maps and cat /proc/$$/mapsto get more clues.

顺便说一句,在Linux上,您可以使用 mmap(2 )MAP_ANONYMOUS | MAP_NORESERVE一起使用,地址范围要大一些(以后再调用内部带有MAP_FIXEDmmap,或者从不使用它),以避免以后被您的进程使用(或如 damon ,使用特定于x86-64的MAP_32BITS)这可能比依赖于受限制的地址位更为明智.到48位.

BTW, on Linux, you could reserve, using mmap(2) with 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.

此外,在Linux上捕获SIGSEGV棘手的(您需要一些处理器特定的代码)并且成本很高.也许您想要一些外部传呼机制(在GNU上存在) Hurd,但不在Linux上).或mmap-在某些 FUSE 文件系统上添加一些伪文件.

Also, catching SIGSEGV on Linux is tricky (you'll need some processor specific code) and costly. Perhaps you want some external pager mechanism (which exists on GNU Hurd, but not on Linux). Or mmap-ing some pseudo-file on some FUSE filesystem.

注意:大多数x86-64处理器只有48位地址,但是我不建议使用该地址.

NB: most x86-64 processors have only 48 bits of addresses, but I don't recommend using that.

注2:处理器制造商记得 IBM/360 所做的事情:忽略了上层地址位(最初为24位).当IBM必须将地址扩展到31位时,这对于软件行业来说是一场噩梦.因此,硬件制造商了解了这一教训,并禁止今天(在硬件中)对未使用的地址位使用调皮的技巧.

Note 2: Processor makers remembered what IBM/360 did: ignoring the upper address bits (originally 24 bits). When IBM had to extend address to 31 bits it was a nightmare for the software industry. So hardware makers understood the lesson, and disallow today (in hardware) playing naughty tricks on unused address bits.

这篇关于用户空间中的虚拟内存地址范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆