5

スレッドの優先度を設定することは、スタックオーバーフローのタブーの対象になることは知っていますが、私のアプリケーションは優先度を上げるための良い候補であると確信しています。それを正当化するために、私は以下の文脈を説明しました。問題は、それを効果的に行う方法です。

アプリケーションは、約5時間の実行時間で複雑なアルゴリズムを実行する.NET 4(C#)コンソールアプリケーションです。このアルゴリズムは、メモリを大量に消費するのではなく、プロセッサを集中的に使用するだけです。数値計算を実行し、ディスクI / O、データベース接続、ネットワーク接続などを実行しません。アプリケーションの出力は、最後にコンソールに書き込む1つの数値です。つまり、アルゴリズムは完全に自己完結型であり、依存関係はありません。

このアプリケーションは、必要以上の空きRAM(8GB)を備えたWindowsServerを実行する専用の16コア64ビットマシンで実行されます。専用とは、このアプリケーションを排他的に実行するためにサーバーが調達されたことを意味します。

広範囲にわたるプロファイリング、派手な数学のショートカット、ちょっとしたハックを使って、コードを可能な限り最適化しました。

擬似コードの全体的な構造は次のとおりです。

public static void Main ()
{
    Process.GetCurrentProcess().PriorityBoostEnabled = true;
    Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;

    // Of course this only affects the main thread rather than child threads.
    Thread.CurrentThread.Priority = ThreadPriority.Highest;

    BigInteger seed = SomeExtremelyLargeNumber; // Millions of digits.

    // The following loop takes [seed] and processes some numbers.
    result1 = Parallel.For(/* With thread-static variables. */);

    while (true) // Main loop that cannot be parallelized.
    {
        // Processes result1.
        result2 = Parallel.For(/* With thread-static variables. */);

        // Processes result2.
        result1 = Parallel.For(/* With thread-static variables. */);

        if (result1 == criteria)
            break;

        // Note: This loop does not need to sleep or care about system responsiveness.
    }
}

SOに関するスレッドの優先度に関連する質問に基づいて、ThreadPoolを使用するものは優先度の点で混乱してはならないことを収集します。したがって、手動スレッドに切り替える必要がある場合は、そうしてください。

質問:

  • スレッドの優先度を上げる(スレッドプールなどを使用しない)ために、上記のコードを手動スレッドに変更するにはどうすればよいですか?
  • すべての子スレッドで優先度を最高に設定することも役立ちますか?つまり、子スレッドは互いに戦っているだけなのか、それとも外部OSタスクよりも優位に立つのでしょうか。
  • 16コアがあることを考えると、16スレッドまたは15スレッドを実行する必要がありますか?これに対する一般的なガイドラインはありますか?
  • プロセスの優先順位をリアルタイムのヘルプにも設定しますか?
4

4 に答える 4

2

このようなアプリでは、優先順位を変更して、実行時間全体に0%の違いをもたらすことを期待しています。16コアすべてが100%で実際の作業を行っている状態で、CPUの使用量がすでに限界に達している場合、できることはこれ以上ありません。

于 2012-08-21T09:20:02.050 に答える
1

ほとんどのスレッドは明らかに重要な作業を行っているため、個々のスレッドの優先順位を設定する必要はありません。プロセス全体に対して優先順位を設定するだけです。

ただし、あなたのようなCPUを集中的に使用するアプリに違いが生じるとは思いません。独自のプロセスを強制的にプリエンプトできる唯一のプロセスは、従来ほとんどのOSで好まれてきたI / O集約型アプリですが、専用のマシンがあるため、問題にはなりません(また、WindowsServerは私の経験ではかなり軽量です、したがって、アプリが実行されている唯一のアプリである場合でも干渉しません)。

補足として:

このアルゴリズムは、メモリを大量に消費するのではなく、プロセッサを集中的に使用するだけです。数の計算を行い、ディスクI / O、データベース接続、ネットワーク接続などを実行しません。

「明らかな」I/O操作を実行しないという事実は、メモリを大量に消費できないことを意味するものではありません。大規模な配列やその他のデータ構造を処理している場合、CPUは常にメインメモリに読み取り/書き込み操作を送信し、さまざまなメモリレベル間でデータを移動するために多くの作業が行われています。数字だけで作業する場合でも、正しく行わないと、プログラムのパフォーマンスに悪影響を与える可能性があります。

于 2012-08-21T10:37:06.867 に答える
1

私のコードは、プロセスとスレッドの優先順位を変更できます。

public void SetPriorityProcessAndTheards(string nameProcess,ProcessPriorityClass processPriority, ThreadPriorityLevel threadPriorityLevel)
{
    foreach(Process a in Process.GetProcessesByName(nameProcess))
    {
        a.PriorityBoostEnabled = true;
        a.PriorityClass = processPriority;

        foreach(ProcessThread processThread in a.Threads)
        {
            processThread.PriorityLevel = threadPriorityLevel;
            processThread.PriorityBoostEnabled = true;
        }
    }
}
于 2019-02-18T18:43:21.393 に答える
0

スレッドの数をコア/スレッドの数に制限することを期待します。ParallelTask​​Libraryが使用するスレッドが多すぎる場合があります。cpumaxedプロセスには、corecountまたはthreadcount(ハイパースレッディングフェイクコアが追加されている)のいずれかが最適であるため、threadcountを指定して修正します。

 // Create a ParallelOptions object and supply this to the Parallel.For() 

 var po = new ParallelOptions {MaxDegreeOfParallelism = Environment.ProcessorCount}
 Parallel.For(,,po,);

 // Environment.ProcessorCount gives number of Cores (NOT processors)
 // Never found out how to detect fake cores or hyperthreads, check Task Monitor ;-)

すべてのparallel.For()ステートメントにpoオブジェクトを再利用できます。CPUにバインドされたスレッド化されたアプリであっても、優先順位をいじることで実際に恩恵を受けたことはありません。

于 2012-08-21T11:02:49.973 に答える