3

毎秒ビットを false に設定する bitarray を列挙します。

ここで、これを 2 つのスレッドに分割して速度を上げたいと思います..何らかの奇妙な理由で、半分の量の作業を行うスレッドあたりの時間64% 以上の時間を要しますが、なぜでしょうか?

これは、ある種の CPU キャッシュ効果によるものでしょうか? これを正しく行うにはどうすればよいですか?

以前にラムダ式で8スレッドも試しましたが、常に約1400ミリ秒でしたが、シングルスレッドでは一貫して850ミリ秒になりました。また、1 つのスレッドにすべての作業を任せると、830 ミリ秒かかりました。よく分からないんだけど、ここの原因わかる人いますか?

コード:

    class Program
    {
        static int count = 0x10000000;
        static int half = count / 2;
        static BitArray bitArray = new BitArray(count);

        static unsafe void Main(string[] args)
        {
            Stopwatch sw = Stopwatch.StartNew();

#if SINGLE
            for (int i = 0; i < bitArray.Count; i += 2)
                bitArray.Set(i, true);
#else
            Thread thread1 = new Thread(Thread1);
            Thread thread2 = new Thread(Thread2);
            thread1.Start();
            thread2.Start();
            thread1.Join();
            thread2.Join();
#endif
            sw.Stop();

            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadLine();
        }

        static void Thread1()
        {
            Stopwatch sw = Stopwatch.StartNew();
            for (int i = 0; i < half; i += 2)
                bitArray.Set(i, true);
            sw.Stop();
            Console.WriteLine("Thread1: {0}", sw.ElapsedMilliseconds);
        }

        static void Thread2()
        {
            Stopwatch sw = Stopwatch.StartNew();
            for (int i = half; i < count; i += 2)
                bitArray.Set(i, true);
            sw.Stop();
            Console.WriteLine("Thread2: {0}", sw.ElapsedMilliseconds);
        }
    }
4

3 に答える 3

1

テストが 10 回実行され、結果が報告されるようにコードを修正しました。あなたのコードを使用すると、シングルスレッドとマルチスレッドのテストで同様のタイミングが見られます (各スレッドは約 1200 ミリ秒かかります)。

ただし、他の人が言っているように、複数のスレッドから単一の BitArray を使用しても、スレッド間で競合が発生しないとは限りません。

これは、共有の静的 BitArray を使用する代わりに、各スレッドに独自の BitArray を与えることによって最も簡単に示されます。このアプローチでは、通常、各スレッドに約 450 ミリ秒かかりますが、それでもさらに長い時間がかかることがあります。

Thread2: 415
Thread1: 420
447
Thread2: 414
Thread1: 420
496
Thread1: 1185
Thread2: 1198
1249
Thread1: 417
Thread2: 421
455
Thread1: 420
Thread2: 415
455
Thread2: 413
Thread1: 417
491
Thread2: 413
Thread1: 417
508
Thread2: 417
Thread1: 441
526
Thread1: 420
Thread2: 415
465
Thread1: 940
Thread2: 1005
1087

最終的に、これが示していることは次のことだと思います。

  • コードの設計にもかかわらず、スレッド間の BitArray にはまだ競合の影響があります。
  • スレッドごとに個々のビット配列を使用しても、コードのタイミングには「ランダムな」影響が依然としてあります。これは、このようなマイクロベンチマークを使用すると、作成したコードだけでなく、常に効果的にベンチマークを行っていることを示しています。また、GC、CPU キャッシュ、コンテキストの切り替え、コア ホッピング、ストップウォッチの不正確さなどの影響もあります。
  • あなたが書こうとしているコードの本当の目的がビット配列をできるだけ早く詰め込むことである場合、おそらく別の言語で、ワイヤーに近い、より手動のアプローチが必要になる可能性があります。
于 2013-08-08T01:21:35.887 に答える