12

.NETの世界でのCPUキャッシュのパフォーマンスについて学ぼうとしています。具体的には、プロセッサキャッシュ効果に関するIgorOstovskyの記事を読んでいます。

私は彼の記事の最初の3つの例を調べ、彼とは大きく異なる結果を記録しました。私のマシンのパフォーマンスは、彼の記事に示されているものとほぼ正反対の結果を示しているので、私は何か間違ったことをしているに違いないと思います。キャッシュミスによる大きな影響は期待できません。

私は何が間違っているのですか?(不正なコード、コンパイラ設定など)

これが私のマシンでのパフォーマンス結果です。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

ここに画像の説明を入力してください

それが役に立ったら、私のマシンのプロセッサはIntelCorei7-2630QMです。これが私のプロセッサのキャッシュに関する情報です:

ここに画像の説明を入力してください

x64リリースモードでコンパイルしました。

以下は私のソースコードです:

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

    }
4

1 に答える 1

3

2番目のループでi+=32を使用しているのはなぜですか。この方法でキャッシュラインをステップオーバーしています。32 * 4=128バイトは必要な64バイトよりはるかに大きい。

于 2011-06-22T15:57:17.530 に答える