Espero que esta sea una publicación válida aquí, es una combinación de problemas de C# y hardware.Rendimiento de C# que varía debido a la memoria
Estoy evaluando nuestro servidor porque hemos encontrado problemas con el rendimiento de nuestra biblioteca cuantitativa (escrito en C#). Simulé los mismos problemas de rendimiento con un código simple de C#, realizando un uso de memoria muy intenso.
El siguiente código está en una función que se genera a partir de un subproceso, hasta un máximo de 32 subprocesos (porque nuestro servidor tiene 4x CPUs x 8 núcleos cada uno).
Esto es todo en .Net 3.5
El problema es que nos estamos tremendamente diferentes rendimiento. Ejecuto la siguiente función 1000 veces. El tiempo promedio que tarda el código en ejecutarse puede ser, por ejemplo, 3.5s, pero el más rápido solo será 1.2s y el más lento será 7s- ¡para la misma función!
he graficado el uso de memoria en contra de los tiempos y hay doesnt parece que haya ninguna correlación con la GC patadas en.
Una cosa que me di cuenta es que cuando se ejecuta en un solo hilo de los tiempos son idénticos y hay no es una desviación salvaje También probé algoritmos de CPU y los tiempos son idénticos también. Esto nos ha hecho preguntarnos si el bus de memoria simplemente no puede hacer frente.
Me preguntaba si este podría ser otro problema de .net o C#, ¿o es algo relacionado con nuestro hardware? ¿Esta sería la misma experiencia si hubiera usado C++ o Java? Estamos utilizando 4 x Intel x7550 con 32 GB de ram. ¿Hay alguna forma de evitar este problema en general?
Stopwatch watch = new Stopwatch();
watch.Start();
List<byte> list1 = new List<byte>();
List<byte> list2 = new List<byte>();
List<byte> list3 = new List<byte>();
int Size1 = 10000000;
int Size2 = 2 * Size1;
int Size3 = Size1;
for (int i = 0; i < Size1; i++)
{
list1.Add(57);
}
for (int i = 0; i < Size2; i = i + 2)
{
list2.Add(56);
}
for (int i = 0; i < Size3; i++)
{
byte temp = list1.ElementAt(i);
byte temp2 = list2.ElementAt(i);
list3.Add(temp);
list2[i] = temp;
list1[i] = temp2;
}
watch.Stop();
(el código es sólo la intención de subrayar la memoria)
me gustaría incluir el código de subprocesos, pero utilizó una biblioteca de subprocesos no estándar.
EDITAR: He reducido "size1" a 100000, que básicamente no utiliza mucha memoria y todavía tengo mucha inestabilidad. Esto sugiere que no es la cantidad de memoria que se transfiere, sino la frecuencia de captura de memoria.
¿Se están ejecutando otros procesos durante su punto de referencia? Incluso el sistema operativo necesita tiempo de CPU. Si está utilizando todos los núcleos virtuales durante su punto de referencia, está virtualmente (perdón por el juego de palabras) garantizado que los procesos no relacionados tomarán tiempo de CPU durante su prueba. –
No tenemos suficiente información para hacer otra cosa que especular. Dicho esto, mi dinero está en su "biblioteca de subprocesos no estándar" que no asigna suficientes subprocesos para ejecutar esto en paralelo. Si ejecuta 50 copias y solo asigna 20 hilos (por ejemplo), 10 iteraciones tendrán que esperar (en promedio) para que se completen otras 2 iteraciones para que se libere un hilo. Eso podría explicar las desviaciones que estás viendo. –
Solo una idea: dado que parece conocer el tamaño de la lista, debe pasar eso al constructor (o simplemente usar matrices). Luego evitas las reasignaciones si las matrices subyacentes. –