Estamos buscando migrar una aplicación de rendimiento crítico a .Net y encontrar que la versión de C# es 30% a 100% más lenta que Win32/C dependiendo del procesador (diferencia más marcada en el procesador T7200 móvil). Tengo una muestra muy simple de código que demuestra esto. Por razones de brevedad me acaba de mostrar la versión C - C# es una traducción directa:¿Por qué la diferencia de rendimiento entre C# (bastante más lento) y Win32/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;
}
Si nos fijamos en el desmontaje de Win32 para la 'cosa' que tenemos:
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
(esto es en la depuración pero hay que tener conmigo)
el desmontaje de la versión optimizada C# utilizando el depurador de CLR en el exe optimizado:
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
Muchas más instrucciones, presumiblemente la causa de la diferencia de rendimiento.
SO3 preguntas realmente:
estoy mirando el desmontaje correcto para los 2 programas o me están engañando a las herramientas?
Si la diferencia en el número de instrucciones generadas no es la causa de la diferencia ¿cuál es?
¿Qué podemos hacer al respecto aparte de mantener nuestro código crítico de rendimiento en una DLL nativa?
Gracias de antemano Steve
PS Recibí una invitación recientemente a una articulación MS/Intel seminario titulado algo así como 'aplicaciones nativas de rendimiento crítico Edificio' Hmm ...
¿Podría eliminar todas las líneas nuevas entre las instrucciones de ensamblaje? –
Como siempre, perfílalo para ver exactamente cuánto cuesta el mayor rendimiento. (No hay forma de que podamos ver lo que toma tiempo en su código, así que no tiene sentido preguntarnos. Pregúntele a un generador de perfiles en su lugar) Aparte de eso, un truco simple podría ser ejecutar su código C# a través de NGen. Eso debería aumentar el rendimiento bastante. – jalf
¿Qué versión del CLR está comparando? Por lo que sé, el compilador .NET 3.5 SP1 JIT es más eficiente que los anteriores. Además, el optimizador x64 JIT es más agresivo que x86 one. –