C# x64与x86性能注意事项.Net

C# x64与x86性能注意事项.Net,c#,performance,64-bit,C#,Performance,64 Bit,我试图了解在x64和x86中运行本机C#/.Net 4.0应用程序时存在哪些性能差异。我了解内存方面的考虑(x64寻址所有内存,x86限制为2/4gb),以及x64应用程序将使用更多内存(所有指针都是8字节而不是4字节)的事实。据我所知,所有这些都不会影响任何时钟对时钟指令,因为x64管道足够宽,可以处理更宽的指令 由于每个线程的堆栈较大,上下文切换是否会影响性能?在评估这两个应用程序时,我遗漏了哪些性能方面的考虑因素?与“x64应用程序将使用更多内存”密切相关的是,对于64位应用程序,您的引用

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


由于每个线程的堆栈较大,上下文切换是否会影响性能?在评估这两个应用程序时,我遗漏了哪些性能方面的考虑因素?

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

乔·怀特给了您一些很好的理由,说明您的应用程序可能会慢一些。更大的指针(因此扩展为.NET中更大的引用)将占用更多内存空间,这意味着缓存中的代码和数据将更少

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

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

  • CLR将发出标量SSE指令,用于处理64位浮点运算。在x86中,它依赖于使用标准的x87 FP堆栈,这相当慢,特别是对于int和float之间的转换

  • 拥有更多寄存器意味着JIT由于寄存器压力而溢出寄存器的可能性要小得多。对于快速内部循环,溢出寄存器的成本可能相当高,特别是当函数内联并在其中引入额外的寄存器压力时

  • 任何对64位整数的操作都可以通过装入一个寄存器而不是分成两半而受益匪浅

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

  • 在某些情况下,x64中的RIP相对寻址可以。虽然这并不直接适用于.NET应用程序,但它可能会对DLL的共享产生影响,否则可能需要重新定位DLL。我很想知道是否有人有任何关于.NET和托管应用程序的具体信息

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


事实上,你能够判断哪一个更适合你的应用程序的唯一方法是在两种架构上进行分析和测试,并比较实际结果。然而,我个人只是尽可能地使用任何CPU,并避免任何固有的依赖于体系结构的事情。这使得它的构建和部署变得容易,而且当大多数用户开始以独占方式切换到x64时,希望它能更加经得起未来的考验。

您是否对这两者都进行了基准测试,或者这是一个思想实验?如果进行基准测试,结果是什么?在现代CPU中,寄存器的数量不会改变任何东西,因为asm代码被转换为微操作。在处理整数和内存时,通用代码上的x64往往比x86慢。另一方面,SSE2 FPU比x87快。但和往常一样,更快的可能是更改所使用的算法(例如,使用缓存或查找表),而不是CPU目标。拥有更多的寄存器供您使用肯定会改变情况。即使使用x86处理器执行的寄存器重命名,它也无法处理有限寄存器集强制编译器生成的显式依赖项。此外,“改变算法”不是这个问题的核心,这就是为什么没有人愿意提及它。