【问题标题】:x64 vs x86 Performance Considerations .Netx64 与 x86 性能注意事项 .Net
【发布时间】:2011-06-28 20:32:50
【问题描述】:

我试图了解在 x64 与 x86 中运行本机 C#/.Net 4.0 应用程序时存在哪些性能差异。我了解内存注意事项(x64 寻址所有内存,x86 限制为 2/4gb),以及 x64 应用程序将使用更多内存的事实(所有指针都是 8 字节而不是 4 字节)。据我所知,这些都不应该影响时钟指令的任何时钟,因为 x64 管道足够宽,可以处理更宽的指令。

由于每个线程的堆栈大小较大,上下文切换是否会影响性能?在评估这两者时我遗漏了哪些性能注意事项?

【问题讨论】:

  • 您是否对两者都进行了基准测试,或者这是一个思想实验?如果您进行基准测试,结果如何?

标签: c# performance 64-bit


【解决方案1】:

Joe White 为您提供了一些很好的理由说明您的应用程序可能会变慢。更大的指针(因此在 .NET 中通过扩展更大的引用)将占用更多的内存空间,这意味着更少的代码和数据将适合缓存。

但是,您可能希望使用 x64 有很多有益的原因:

  • 在 x64 中默认使用 AMD64 调用约定,它比标准的 cdecl 或 stdcall 快很多,许多参数在寄存器中传递并使用 XMM 寄存器进行浮点。

  • CLR 将发出标量 SSE 指令以处理 64 位浮点运算。在 x86 中,它依赖于使用标准的 x87 FP 堆栈,这要慢一些,尤其是对于诸如在整数和浮点数之间转换之类的事情。

  • 拥有更多寄存器意味着 JIT 由于寄存器压力而不得不溢出它们的可能性要小得多。对于快速内部循环来说,溢出寄存器的代价可能相当高,尤其是当函数被内联并在那里引入额外的寄存器压力时。

  • 对 64 位整数的任何操作都可以通过能够放入单个寄存器而不是被分成两个单独的部分而受益匪浅。

  • 这可能很明显,但是如果您的应用程序是内存密集型的,即使它没有达到理论限制,您的进程可以访问的额外内存也会非常有用。碎片化可能会导致您在达到该标记之前很久就遇到“内存不足”的情况。

  • 在某些情况下,x64 中的 RIP 相对寻址可以reduce the size of an executable image。尽管这并不真正直接适用于 .NET 应用程序,但它会影响 DLL 的共享,否则可能不得不重新定位。我很想知道是否有人对此有任何关于 .NET 和托管应用程序的具体信息。

除此之外,至少在当前版本中,.NET 运行时的 x64 版本似乎比 x86 等效版本执行了更多优化。内联和内存对齐之类的事情似乎更频繁地发生。事实上,不久前有一个错误阻止了任何采用或返回值类型的方法的内联。我记得看到它在 x64 中修复,而不是 x86 版本。

确实,您能够判断哪个更适合您的应用的唯一方法是对两种架构进行分析和测试并比较实际结果。但是,我个人只是尽可能使用 Any CPU,并避免任何本质上依赖于架构的东西。这使得构建和部署变得容易,并且有望在大多数用户开始专门切换到 x64 时提供更多的未来证明。

【讨论】:

  • 寄存器的数量不会改变任何东西,在现代 CPU 中,因为 asm 代码被翻译成微操作。在使用整数和内存时,通用代码上的 x64 往往比 x86 慢。另一方面,SSE2 FPU 比 x87 更快。但与往常一样,更快的可能是更改所使用的算法(例如,使用缓存或查找表),而不是 CPU 目标。
  • 拥有更多可供您使用的寄存器肯定会改变一些事情。即使 x86 处理器执行的寄存器重命名,它也无法对有限的寄存器集强制编译器产生的显式依赖做任何事情。此外,“改变算法”不是这个问题的主题,这就是为什么没有人费心提及它的原因。
【解决方案2】:

与“x64 应用程序将使用更多内存”密切相关的事实是,对于 64 位应用程序,您的引用位置更小(因为您的所有指针大小都加倍),因此您从CPU 的板载(超快)缓存。您必须更频繁地从系统 RAM 中检索数据,这比 L2 甚至 L1 片上缓存要慢得多。

【讨论】:

    猜你喜欢
    • 2012-05-06
    • 2012-08-22
    • 2010-11-01
    • 2011-07-09
    • 2017-01-24
    • 1970-01-01
    • 2016-07-21
    • 2017-11-03
    • 1970-01-01
    相关资源
    最近更新 更多