2011-06-18 41 views
12

Estoy tratando de conocer el rendimiento de la memoria caché de la CPU en el mundo de .NET. Específicamente estoy trabajando con Igor Ostovsky's article about Processor Cache Effects.Rendimiento al generar falta de memoria caché de la CPU

He leído los primeros tres ejemplos en su artículo y he registrado resultados que difieren ampliamente de los suyos. Creo que debo estar haciendo algo mal porque el rendimiento de mi máquina muestra resultados casi opuestos a los que muestra en su artículo. No veo los grandes efectos de errores de caché que esperaría.

¿Qué estoy haciendo mal? (Mal código, configuración del compilador, etc.)

Éstos son los resultados de rendimiento en mi máquina:

enter image description here

enter image description here

enter image description here

Si ayuda, el procesador en mi la máquina es un Intel Core i7-2630QM. Aquí es información en la caché de mi procesador:

enter image description here

he compilado en modo de 64 bits de salida.

A continuación se muestra el código fuente:

class Program 
    { 

     static Stopwatch watch = new Stopwatch(); 

     static int[] arr = new int[64 * 1024 * 1024]; 

     static void Main(string[] args) 
     { 
      Example1(); 
      Example2(); 
      Example3(); 


      Console.ReadLine(); 
     } 

     static void Example1() 
     { 
      Console.WriteLine("Example 1:"); 

      // Loop 1 
      watch.Restart(); 
      for (int i = 0; i < arr.Length; i++) arr[i] *= 3; 
      watch.Stop(); 
      Console.WriteLine("  Loop 1: " + watch.ElapsedMilliseconds.ToString() + " ms"); 

      // Loop 2 
      watch.Restart(); 
      for (int i = 0; i < arr.Length; i += 32) arr[i] *= 3; 
      watch.Stop(); 
      Console.WriteLine("  Loop 2: " + watch.ElapsedMilliseconds.ToString() + " ms"); 

      Console.WriteLine(); 
     } 

     static void Example2() 
     { 

      Console.WriteLine("Example 2:"); 

      for (int k = 1; k <= 1024; k *= 2) 
      { 

       watch.Restart(); 
       for (int i = 0; i < arr.Length; i += k) arr[i] *= 3; 
       watch.Stop(); 
       Console.WriteLine("  K = "+ k + ": " + watch.ElapsedMilliseconds.ToString() + " ms"); 

      } 
      Console.WriteLine(); 
     } 

     static void Example3() 
     { 

      Console.WriteLine("Example 3:"); 

      for (int k = 1; k <= 1024*1024; k *= 2) 
      { 

       //256* 4bytes per 32 bit int * k = k Kilobytes 
       arr = new int[256*k]; 



       int steps = 64 * 1024 * 1024; // Arbitrary number of steps 
       int lengthMod = arr.Length - 1; 

       watch.Restart(); 
       for (int i = 0; i < steps; i++) 
       { 
        arr[(i * 16) & lengthMod]++; // (x & lengthMod) is equal to (x % arr.Length) 
       } 

       watch.Stop(); 
       Console.WriteLine("  Array size = " + arr.Length * 4 + " bytes: " + (int)(watch.Elapsed.TotalMilliseconds * 1000000.0/arr.Length) + " nanoseconds per element"); 

      } 
      Console.WriteLine(); 
     } 

    } 
+0

¿Qué CPU estás usando? ¿Cuánto caché tiene? Nivel1 y 2? – Oded

+0

Es un Intel Core i7-2630QM. Las estadísticas de caché se encuentran en la imagen de línea de comando anterior. –

+0

Además, ¿tienes suficiente RAM en el sistema? ¿No estás golpeando el archivo de paginación durante la prueba? –

Respuesta

3

¿Por qué se utiliza i + = 32 en el segundo bucle. Está pasando por líneas de caché de esta manera. 32 * 4 = 128bytes más grande que 64bytes necesarios.

+1

... No entiendo esta respuesta. ¿Por qué eso explica la diferencia de orden de magnitud y qué tiene eso que ver con la segunda o tercera prueba? –

+0

Incluso sabiendo que esto es bastante viejo, solo para referencia de otra persona, las líneas de caché generalmente se captan en fragmentos de 64 bytes, por lo que lo que DiVan muestra es que en una matriz ** int ** (4 bytes), ya sea que lo atraviese al pasar por 32 terminarás saltando sobre más de una línea de caché, lo que por supuesto hará que el loop 2 sea más rápido, si estuvieras usando 16 en vez de 32 (16x4 = 64), entonces no saltaras ninguna línea de caché y bucle 1 y 2 tendrán un resultado similar, incluso el bucle 2 iterando menos veces que el bucle 1. – DenninDalke

Cuestiones relacionadas