【解決方法】コマンドの反復回数をどのように確認できますか "並列用" 設定された反復回数と一致しますか?


こんにちは、みんな、
私の記事では、いろいろな条件で逐次処理と並列処理の速度を比較したいので、一例として、以下の逐次コマンドを並列化したいのですが、並列化してからループが回らないようです。指定された回数だけ繰り返されます。 使用する必要があるかもしれません 同時収集 または「ロック」ステートメントですが、これは通常、順次処理と比較して並列処理の速度を低下させます。

変数が複数のスレッド間で共有されていることは承知しています。 これは、複数のスレッドがこの変数に対して同時に読み書きできることを意味し、競合状態やその他の予期しない動作が発生する可能性があります。

比較する私の記事の例(できれば簡単な例)が欲しい forParallel.For. この例には、次の機能が必要です。
• の実行 Parallel.For ブロックコードは、の実行よりも高速である必要があります for ブロックコード。
• フラグ、変数、またはその他のメカニズムを使用して、 Parallel.For ループは定義された回数実行されます。

次のツールを使用します。

• .NET フレームワーク 4.5

• コンソール アプリ

• Windows 7

お時間をいただきありがとうございます。
よろしく

私が試したこと:

C#
static long Counter = 0;
public static long Calcute()
{
    int Total = 0;
    for (int i = 0; i < 30; i++)
    {
        Total = 20 / 4;
        Total = 20 * 4;
        Total = 20 ^ 4;
        Total = 20 - 4;
        Total = 20 % 4;
    }
    Counter += 30;
    return Counter;
}

一連:

C#
static void Main(string[] args)
{
    Stopwatch SW = new Stopwatch();
    Console.ReadKey();
    SW.Start();
    for (int i = 0; i < 50000000; i++)
    {
        Calcute();
        Calcute();
        Calcute();
        Calcute();
        Calcute();
    }
    SW.Stop();
    Console.WriteLine("Total seconds: " + SW.Elapsed.TotalSeconds + ", Counter: " + Counter);
    Console.ReadKey();
}

結果 (ここをクリックしてご覧ください):
Counter 値=50000000*30*5=7,500,000,000

平行:

C#
static void Main(string[] args)
{
    Stopwatch SW = new Stopwatch();
    Console.ReadKey();
    SW.Start();
    Parallel.For(0, 50000000, (int i) =>
    {
        Calcute();
        Calcute();
        Calcute();
        Calcute();
        Calcute();
    });
    SW.Stop();
    Console.WriteLine("Total seconds: " + SW.Elapsed.TotalSeconds + ", Counter: " + Counter);
    Console.ReadKey();
}

結果の 1 つ (ここをクリックしてご覧ください):
Counter value=50000000*30*5= 異なる値が表示されます

解決策 1

マルチスレッドは特効薬ではありません。コードを高速化して大幅な速度向上を実現できるわけではなく、毎回再現可能な結果が得られるわけではありません。

理由は単純です。プロセッサに N 個のコアがあるためです: 1、2、4、8、16、または 64 の可能性もあります。
各スレッドには、実行するための予備のコアが必要です。コアが使用できない場合、スレッドは使用可能になるまで待機キューに入ります。 作成するスレッドが多いほど、空きコアを待機するスレッドが多くなります。
残りのアプリケーション (および OS) はこれらのコアを共有するため、特定のマイクロ秒での負荷は、すべてのコアとそれらを待機しているすべてのスレッドに依存します。

また、各スレッドにはスタックが必要です。通常、64 ビット プロセスの場合は 4MB です。

さらに悪いことに、スレッドの設定と切り替えにはプロセッサ (したがってコア) の時間がかかります! スレッドのランタイムが短いほど、これは顕著になります。

スレッド数の読み込みを開始すると、アプリの合計処理時間が増加する可能性があります。特に、他のスレッドが実行できるようにディスク (仮想メモリ) にページングされるときにメモリが少なくなり始める場合はそうです。

これらすべてが非決定論的なシステムになります。完了するまでにかかる時間を予測することはできません。これは、誰にも制御できない外部要因に大きく依存するためです (Windows はリアルタイム OS ではなく、かつてもそうでした)。

そして、50,000,000 スレッドを開始しようとしていますか? どんなに頑張っても安定した結果は得られません!

コメント

タイトルとURLをコピーしました