7

在针对 64 位操作系统时,我对何时使用 64 位整数存有疑问。

有没有人针对生成代码的速度进行了结论性研究?

  • 最好使用 64 位整数作为函数或方法的参数?(例如:uint64 myFunc(uint64 myVar))如果我们使用 64 位整数作为参数,它会占用更多内存,但可能会更有效率。如果我们知道某个值应该总是小于例如 10 会怎样。我们仍然继续使用 64 位整数作为这个参数?

  • 使用 64 位整数作为返回类型更好吗?使用 32 位作为返回值是否有一些惩罚?

  • 循环使用 64 位整数更好吗?(for(size_t i=0; i<...)) 在这种情况下,我想是这样。对循环使用 32 位变量是否有一些惩罚?

  • 使用 64 位整数作为指针索引更好吗?(例如:myMemory[index])在这种情况下,我想是的。对索引使用 32 位变量是否有一些惩罚?

  • 使用 64 位整数将数据存储在类或结构中更好吗?(我们不想保存到磁盘或类似的东西)

  • 布尔类型最好使用 64 位?

  • 64 位整数和浮点数之间的转换呢?现在使用双打会更好吗?到目前为止,双打比浮点慢。

  • 每次我们访问 32 位变量时都会受到一些惩罚吗?

问候!

4

3 回答 3

4

我同意@MarkB,但想提供有关某些主题的更多详细信息。

在 x64 上,可用的寄存器更多(两倍)。因此,标准调用约定被设计为默认情况下在寄存器中采用更多参数。所以只要参数的数量不过多(通常为 4 或更少),它们的类型不会有任何区别。 无论如何,它们将被提升为 64 位并传入寄存器。

即使它们是在寄存器中传递的,也会在堆栈上为这些 64 位寄存器分配空间。这是通过设计使它们的存储位置简单且与剩余参数的存储位置相邻。无论如何,多余的参数都将放在堆栈上,因此在这些情况下大小可能很重要。

这个问题对于内存数据结构尤为重要。在 32 位足够的情况下使用 64 位会浪费内存,更重要的是会占用缓存行中的空间。缓存的影响并不简单。 如果您的数据访问模式是顺序的,那么您将通过实质上使一半的缓存不可用来为此付出代价。(假设您只需要每个 64 位数量的一半。)

如果您的访问模式是随机的,则对缓存性能没有影响。这是因为每次访问都占用了一个完整的缓存行。

访问小于字长的整数可能会产生很小的影响。然而,流水线和指令的多次发布将使得额外的指令(零或符号扩展)几乎总是被完全隐藏并且不被观察到。

所有这一切的结果很简单:选择对您的问题很重要的整数大小。 对于参数,编译器可以根据需要提升它们。对于内存结构,通常越小越好。

于 2012-12-04T17:11:22.020 回答
3

您已经成功地将大量问题塞进了这里的一个问题中。在我看来,您的所有问题基本上都与微优化有关。因此,我将分两部分回答:

  • 不要从性能角度担心大小,而是使用指示它们将包含的数据的类型,并信任编译器的优化器来对其进行排序

  • 如果在开发过程中的某个时刻性能成为问题,请分析您的代码。然后您可以适当地进行算法调整,如果分析器显示整数运算导致问题,您可以并排比较不同的大小以进行比较。

于 2012-12-04T15:56:52.850 回答
0

使用int并信任平台和编译器作者,他们已经完成了工作并为其选择了最有效的表示。在大多数 64 位平台上,它是 32 位的,这意味着它的效率不低于 64 位类型。

于 2012-12-05T06:54:18.240 回答