Question

J'essaie d'apprendre la performance du cache de la CPU dans le monde de .NET. Spécifiquement, je travaille sur Igor Ostovsky's article sur les effets de cache de processeur .

J'ai parcouru les trois premiers exemples de son article et j'ai enregistré des résultats qui diffèrent largement de son. Je pense que je dois faire quelque chose de mal car la performance sur ma machine montre presque les résultats opposés exacts de ce qu'il montre dans son article. Je ne vois pas les grands effets des caches manquées que j'attendrais.

Qu'est-ce que je fais mal? (mauvais code, cadre du compilateur, etc.)

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

Entrez la description de l'image ici

Entrez la description de l'image ici

Entrez la description de l'image ici

Si cela aide, le processeur sur ma machine est un noyau Intel I7-2630QM. Voici des informations sur le cache de mon processeur:

Entrez la description de l'image ici

J'ai compilé en mode de sortie X64.

ci-dessous est 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();
        }

    }

Était-ce utile?

La solution

Pourquoi utilisez-vous i += 32 dans la deuxième boucle.Vous entrez sur les lignes de cache de cette manière.32 * 4= 128bytes de manière plus grande puis 64 Boites nécessaires.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top