大多数程序都适合<4GB地址空间,但需要使用x64架构上提供的新功能。
是否有编译器/平台可以使用x64寄存器和特定指令但保留32位指针以节省内存?
是否可以在遗留代码上透明地执行此操作?有什么转变呢?
OR
在保持32位指针的同时获取64位功能需要对代码进行哪些更改?
答案 0 :(得分:16)
一种避免这种情况的简单方法是,如果你所指向的结构只有几种类型。然后,您可以为数据分配大数组,并使用uint32_t
进行索引。
因此,这种模型中的“指针”只是全局数组中的索引。通常用一个合适的编译器进行寻址应该足够有效,并且它可以节省一些空间。你可能会放弃其他你可能感兴趣的东西,比如动态分配。
实现类似功能的另一种方法是编码一个与其实际位置不同的指针。如果你能确保这种差异总是适合32位,你也可以获益。
答案 1 :(得分:4)
从技术上讲,编译器可以这样做。 AFAIK,实际上还没有完成。它已被提议用于gcc(即使在这里有一个补丁:http://gcc.gnu.org/ml/gcc/2007-10/msg00156.html)但从未集成(至少,我最后一次检查没有记录)。我的理解是它还需要来自内核和标准库的支持才能工作(即内核需要以当前不可能的方式设置事物并且使用现有的32或64位ABI与内核通信是不可能的)。
答案 2 :(得分:4)
值得注意的是,Linux,X32开发中的ABI,可以让你构建一个使用32位索引和地址的x86_64二进制文件。
只是相对较新,但有趣。
答案 3 :(得分:3)
你需要的“64位功能”到底有多模糊?
在搜索自己的答案时找到了这个: http://www.codeproject.com/KB/cpp/smallptr.aspx
也请在底部进行讨论......
从来没有必要考虑过这个问题,但很有意思的是,人们可以关注空间指针需要多少......
答案 4 :(得分:2)
在x86上,没有。在其他处理器上,例如PowerPC,它很常见 - 64位寄存器和指令在32位模式下可用,而对于x86,它往往是“全有或全无”。
答案 5 :(得分:1)
这取决于平台。在Mac OS X上,64位进程的前4 GB地址空间是保留和未映射的,可能是一个安全功能,所以没有 32位值是错误的指针。如果你尝试,可能有办法打败这个。我通过编写一个C ++“指针”类来解决这个问题,该类将0x100000000添加到存储的值中。 (这比索引到数组要快得多,这也需要在添加之前找到基于数组的地址并进行相乘。)
在ISA级别上,您当然可以选择加载和零扩展32位值,然后将其用作64位指针。对于平台而言,这是一个很好的功能。
除非您希望同时使用64位和32位指针,否则不需要对程序进行任何更改。在这种情况下,您将回到过去near
和far
指针的糟糕时期。
此外,您肯定会破坏与指向指针的API的ABI兼容性。
答案 6 :(得分:1)
您问题的第二部分很容易回答。实际上很多C实现都支持使用32位代码的64位操作。通常用于此的C类型是long long
(但请查看您的编译器和架构)。
据我所知,在64位本机代码中不可能有32位指针。
答案 7 :(得分:1)
我担心如果你担心指针的大小,你可能会遇到更大的问题。如果指针的数量将达到数百万或数十亿,那么在实际耗尽物理或虚拟内存之前,您可能会在Windows操作系统中遇到限制。
Mark Russinovich撰写了一篇与此相关的精彩文章,名为Pushing the Limits of Windows: Virtual Memory。
答案 8 :(得分:1)
我认为这类似于MIPS n32 ABI:带有32位指针的64位寄存器。
在n32 ABI中,所有寄存器都是64位(因此需要MIPS64处理器)。但地址和指针只有32位(存储在内存中时),从而减少了内存占用。将32位值(例如指针)加载到寄存器时,会将其符号扩展为64位。当处理器使用指针/地址进行加载或存储时,使用所有64位(处理器不知道SW的n32-ess)。如果你的操作系统支持n32程序(也许操作系统也遵循n32模型,或者它可能是一个适当的64位操作系统,并添加了n32支持),它可以将n32应用程序使用的所有内存定位在合适的内存中(例如,较低的2GB和更高的2GB,虚拟地址)。这个模型唯一的故障是当寄存器保存在堆栈上(函数调用等)时,使用所有64位,n32 ABI中没有32位数据模型。
也可以为x86-64实现这样的ABI。
答案 9 :(得分:0)
Linux现在对X32 ABI提供了相当全面的支持,它完全符合提问者的要求,实际上它部分支持作为Gentoo操作系统下的配置。我认为这个问题需要根据反复的发展进行审查。