我正在尝试了解在x64与x86中运行本地C# / .Net 4.0应用程序时存在的性能差异。我理解内存方面的考虑(x64可以寻址所有内存,而x86限制为2/4GB),以及x64应用程序将使用更多内存(所有指针都是8个字节而不是4个字节)。据我所知,这些都不应影响按照指令进行时钟对时钟操作的任何内容,因为x64管道足够宽以处理更宽的指令。
由于每个线程的堆栈更大,是否会有上下文切换的性能损失?我在评估两者时漏掉了哪些性能考虑?
我正在尝试了解在x64与x86中运行本地C# / .Net 4.0应用程序时存在的性能差异。我理解内存方面的考虑(x64可以寻址所有内存,而x86限制为2/4GB),以及x64应用程序将使用更多内存(所有指针都是8个字节而不是4个字节)。据我所知,这些都不应影响按照指令进行时钟对时钟操作的任何内容,因为x64管道足够宽以处理更宽的指令。
由于每个线程的堆栈更大,是否会有上下文切换的性能损失?我在评估两者时漏掉了哪些性能考虑?
乔·怀特(Joe White)列举了一些可能导致应用程序变慢的好原因。较大的指针(因此在.NET中引用也更大)将占用更多的内存空间,这意味着你的代码和数据将无法全部适应缓存。
然而,使用x64有很多好处:
x64默认使用AMD64调用约定,可以比标准的cdecl或stdcall快得多,在其中许多参数通过寄存器传递,并使用XMM寄存器进行浮点运算。
CLR会发出标量SSE指令来处理64位浮点运算。在x86中,它会退回到使用标准的x87 FP堆栈,这相当慢,尤其是在整数和浮点数之间转换时。
拥有更多的寄存器意味着JIT将不太可能因为寄存器压力而不得不溢出它们。对于快速内部循环,溢出寄存器可能代价相当高,尤其是如果函数被内联并引入其他寄存器压力。
任何64位整数操作都可以通过能够适合单个寄存器而不是被分成两个独立部分而获得极大的好处。
这可能是显而易见的,但你的进程可以访问更多的内存,如果你的应用程序是内存密集型的话,即使没有达到理论极限,这也会非常有用。碎片化可能导致你在达到那个标记之前就遇到“内存不足”的情况。
x64中的RIP相对寻址可以在某些情况下减少可执行映像的大小。虽然这并不适用于.NET应用程序,但它可以影响DLL的共享,否则这些DLL可能必须重新定位。我很想知道是否有任何关于这方面的具体信息涉及.NET和托管应用程序。
除此之外,至少在目前版本中,.NET运行时的x64版本似乎比x86版本执行更多的优化,例如内联和内存对齐等操作发生的频率更高。实际上,有一段时间出现了一个bug,阻止了任何带有值类型参数或返回值类型的方法进行内联优化;我记得这个问题已在x64版本中解决,而x86版本没有。
实际上,你能够判断哪种架构更适合你的应用程序的唯一方法是在两种架构上进行性能分析和测试,并比较实际结果。但是,个人而言,我只要可能就使用Any CPU,避免使用任何内在依赖于架构的东西。这使构建和部署变得容易,并且当大多数用户开始完全切换到x64时,它也更具有未来性。
与“x64应用程序将使用更多内存”密切相关的是,使用64位应用程序时,你的引用局部性较小(因为所有指针大小都加倍),因此你从CPU的板载(超快)缓存中获得的效益更少。你必须更频繁地从系统RAM中检索数据,这比L2甚至L1芯片上的缓存要慢得多。