如何在 64 位应用程序中使用 32 位指针?

Posted

技术标签:

【中文标题】如何在 64 位应用程序中使用 32 位指针?【英文标题】:How to use 32-bit pointers in 64-bit application? 【发布时间】:2012-04-22 10:45:02 【问题描述】:

我们学校的项目只允许我们将 c 程序编译成 64 位应用程序,他们会测试我们的程序的速度和内存使用情况。但是,如果我能够使用 32 位指针,那么我的程序消耗的内存将比 64 位少得多,也可能运行得更快(比 malloc 更快?)

我想知道是否可以在 64 位应用程序中使用 32 位指针?

感谢您的帮助

【问题讨论】:

您如何确定 32 位指针会明显快于 64 位指针(如果有的话)? 至少它消耗更少的内存。我不确定更快的运行速度 你确定它甚至会很重要吗?你有大量的基于指针的数据结构吗?另请注意,开销或重复的指针零扩展操作实际上可能会导致性能下降 使用 GCC? -mx32 选项将 int、long 和指针类型设置为 32 位,并为 x86-64 体系结构生成代码。 (Intel 386 和 AMD x86-64 选项):gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html 其他目标:gcc.gnu.org/onlinedocs/gcc/… - 然后是基准测试 :) @user120115:这应该是一个答案,而不是评论。然后我就可以投票了:-) 【参考方案1】:

使用 GCC?

-mx32 选项将 int、long 和指针类型设置为 32 位,并为 x86-64 架构生成代码。 (英特尔 386 和 AMD x86-64 选项):

i386-and-x86_64-Options

Other targets, GCC

然后进行基准测试:)

【讨论】:

这几乎是要走的路。请注意,您需要一个相当新的 gcc 版本(4.7,或带有各种补丁的 4.6)和一个相当新的 binutils。 为什么不在一开始就指定呢?无论如何,对于真正的问题(尽管有任意的教学限制),这仍然是比被接受的可怕黑客更好的答案。 @kevin: -m32 是与-mx32 完全不同的模式。 x32 生成完全 64 位代码,恰好只使用 64 位地址。 (如果这是家庭作业,那么 -mx32 也不会被允许。但是在 C 中手动编写它可能不会优化为仅使用地址大小前缀来忽略地址寄存器的高位。) 偶然有 llvm equiv 吗?【参考方案2】:

你可以“滚动你自己”。以下内容可能会稍微减少内存使用量,但可能不会提高速度,因为您必须将短指针转换为绝对指针,这会增加开销,而且您也会失去类型检查的大部分好处。

看起来像这样:

typedef unsigned short ptr;
...

// pre-allocate all memory you'd ever need
char* offset = malloc(256); // make sure this size is less than max unsigned int

// these "pointers" are 16-bit short integer, assuming sizeof(int) == 4
ptr var1 = 0, var2 = 4, var3 = 8;

// how to read and write to those "pointer", you can hide these with macros
*((int*) &offset[var1]) = ((int) 1) << 16;
printf("%i", *((int*) &offset[var1]));

使用更多技巧,您可以发明自己的 brk() 来帮助从偏移量分配内存。

值得吗?国际海事组织编号。

【讨论】:

严格来说,这段代码依赖于未定义的行为,尽管在实践中它可能不会在大多数系统上引起对齐问题(?)。 抱歉,但是...呃。这永远不会是一个好主意...但是当提出一个非常不明智的建议时,您至少可以 将 UB 的可能性降到最低:使用 std::aligned_storage 存储最严格的类型,使用适当的 C++ 强制转换和函数等。 它会提高速度。如果您的程序遇到许多数据缓存未命中,例如二进制搜索、遍历二叉树、遍历链表等,使用较小的指针可以节省大量时间。更小的指针意味着更好的数据缓存命中率和更好的性能。我做了一个二叉树遍历的实验,32位版本的运行时间是64位版本的0.85倍:johnysswlab.com/the-price-of-dynamic-memory-memory-access

以上是关于如何在 64 位应用程序中使用 32 位指针?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 64 位 void 指针转换为 32 位 void 指针?

64位驱动开发及驱动签名

如何在 64 位 RHEL 上编译 32 位应用程序?

32 位和 64 位之间的指针增量差异

32位或64位系统中的指针算术长短

从 32 位 C# 到 64 位 C++ 的 PostMessage 参数