2011-06-18 4 views
12

J'essaie d'en apprendre davantage sur les performances du cache CPU dans le monde de .NET. Plus précisément, je travaille à traversIgor Ostovsky.Performance lors de la génération de cache cache CPU

J'ai parcouru les trois premiers exemples dans son article et ai enregistré des résultats qui diffèrent largement de son. Je pense que je dois faire quelque chose de mal parce que la performance sur ma machine montre presque exactement les résultats opposés de ce qu'il montre dans son article. Je ne vois pas les effets importants des échecs de cache auxquels je m'attendrais.

Qu'est-ce que je fais mal? (Mauvais code, réglage du compilateur, etc.)

Voici les résultats de la performance sur ma machine:

enter image description here

enter image description here

enter image description here

Si elle aide, le processeur sur mon La machine est un Intel Core i7-2630QM. Voici les informations sur le cache de mon processeur:

enter image description here

J'ai compilé en mode de sortie x64.

Ci-dessous mon code source:

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

Quel processeur utilisez-vous? Combien cache-t-il? Niveau 1 et 2? – Oded

+0

Il s'agit d'un processeur Intel Core i7-2630QM. Les statistiques de cache sont dans l'image de ligne de commande ci-dessus. –

+0

En outre, vous avez assez de RAM dans le système? Vous ne battez pas sur le fichier d'échange pendant le test? –

Répondre

3

Pourquoi utilisez-vous + i = 32 dans la seconde boucle. Vous enjambez les lignes de cache de cette façon. 32 * 4 = 128 octets bien plus grand que 64 octets requis.

+1

... Je ne comprends pas cette réponse. Pourquoi cela tient-il compte de la différence d'ordre de grandeur, et qu'est-ce que cela a à voir avec le deuxième ou le troisième test? –

+0

Même en sachant que c'est assez ancien, juste pour quelqu'un d'autre, les lignes de cache sont généralement récupérées en morceaux de 64 octets, donc DiVan montre que dans un tableau ** int ** (4 bytes), que vous le traversiez en passant par 32 vous finirez par sauter sur plus d'une ligne de cache, ce qui bien sûr rendra la boucle 2 plus rapide, si vous utilisiez 16 au lieu de 32 (16x4 = 64), alors vous ne passerez pas les lignes de cache et la boucle 1 et 2 auront un résultat similaire, même la boucle 2 itératra moins de fois que la boucle 1. – DenninDalke