【发布时间】:2009-06-29 19:29:00
【问题描述】:
我们正在寻求将性能关键应用程序迁移到 .Net 并发现 c# 版本比 Win32/C 慢 30% 到 100%,具体取决于处理器(移动 T7200 处理器上的差异更明显)。我有一个非常简单的代码示例来演示这一点。为简洁起见,我将只显示 C 版本 - c# 是直接翻译:
#include "stdafx.h"
#include "Windows.h"
int array1[100000];
int array2[100000];
int Test();
int main(int argc, char* argv[])
{
int res = Test();
return 0;
}
int Test()
{
int calc,i,k;
calc = 0;
for (i = 0; i < 50000; i++) array1[i] = i + 2;
for (i = 0; i < 50000; i++) array2[i] = 2 * i - 2;
for (i = 0; i < 50000; i++)
{
for (k = 0; k < 50000; k++)
{
if (array1[i] == array2[k]) calc = calc - array2[i] + array1[k];
else calc = calc + array1[i] - array2[k];
}
}
return calc;
}
如果我们看一下 Win32 中的反汇编,我们有 'else':
35: else calc = calc + array1[i] - array2[k];
004011A0 jmp Test+0FCh (004011bc)
004011A2 mov eax,dword ptr [ebp-8]
004011A5 mov ecx,dword ptr [ebp-4]
004011A8 add ecx,dword ptr [eax*4+48DA70h]
004011AF mov edx,dword ptr [ebp-0Ch]
004011B2 sub ecx,dword ptr [edx*4+42BFF0h]
004011B9 mov dword ptr [ebp-4],ecx
(这是在调试中,但请耐心等待)
在优化后的 exe 上使用 CLR 调试器对优化后的 c# 版本进行反汇编:
else calc = calc + pev_tmp[i] - gat_tmp[k];
000000a7 mov eax,dword ptr [ebp-4]
000000aa mov edx,dword ptr [ebp-8]
000000ad mov ecx,dword ptr [ebp-10h]
000000b0 mov ecx,dword ptr [ecx]
000000b2 cmp edx,dword ptr [ecx+4]
000000b5 jb 000000BC
000000b7 call 792BC16C
000000bc add eax,dword ptr [ecx+edx*4+8]
000000c0 mov edx,dword ptr [ebp-0Ch]
000000c3 mov ecx,dword ptr [ebp-14h]
000000c6 mov ecx,dword ptr [ecx]
000000c8 cmp edx,dword ptr [ecx+4]
000000cb jb 000000D2
000000cd call 792BC16C
000000d2 sub eax,dword ptr [ecx+edx*4+8]
000000d6 mov dword ptr [ebp-4],eax
更多指令,大概是性能差异的原因。
真的有 3 个问题:
我查看的是 2 个程序的正确反汇编还是工具误导了我?
如果生成指令数的差异不是造成差异的原因是什么?
除了将所有性能关键代码保存在本机 DLL 中之外,我们还能做些什么。
提前致谢 史蒂夫
PS 我最近确实收到了参加 MS/Intel 联合研讨会的邀请,主题是“构建性能关键的原生应用程序”嗯...
【问题讨论】:
-
你能去掉汇编指令之间的所有换行符吗?
-
与往常一样,对其进行分析,以准确了解对性能影响最大的成本。 (我们无法看到您的代码中花费了哪些时间,所以问我们没有意义。请改为询问分析器)除此之外,一个简单的技巧可能是通过 NGen 运行您的 C# 代码。这应该会大大提高性能。
-
您要比较的 CLR 版本。据我所知,.NET 3.5 SP1 JIT 编译器比旧的更高效。 x64 JIT 优化器也比 x86 更激进。
-
顺便说一句,“直接”C# 翻译很重要。您确定要检查启用优化的 JIT 生成的程序集吗?
-
另请参阅此相关问题:stackoverflow.com/questions/883642/…
标签: c# .net c performance winapi