27

新しい Intel Atom 330 のレビューを読んでいたところ、タスク マネージャーに 4 つのコア (2 つの物理コアと、ハイパースレッディングによってシミュレートされた 2 つのコア) が表示されることがわかりました。

2 つのスレッドを持つプログラムがあるとします。また、これらのスレッドだけが PC 上で何らかの作業を行っていると仮定します。それ以外はすべてアイドル状態です。OS が両方のスレッドを同じコアに配置する確率は? これは、プログラムのスループットに大きな影響を与えます。

答えが 0% 以外の場合、スレッドを増やす以外に軽減策はありますか?

Windows、Linux、および Mac OS X では、異なる答えがあると思います。


skの回答をGoogleの飼料として 使用し、リンクをたどると、WindowsでGetLogicalProcessorInformation関数が見つかりました。「リソースを共有する論理プロセッサ。このタイプのリソース共有の例は、ハイパースレッディング シナリオです。」これはjalfが正しいことを意味しますが、決定的な答えではありません。

4

8 に答える 8

8

Linux には、HT 対応の非常に洗練されたスレッド スケジューラがあります。その戦略のいくつかは次のとおりです。

パッシブ ロードバランシング: 物理 CPU が複数のタスクを実行している場合、スケジューラは 2 番目の物理プロセッサで新しいタスクを実行しようとします。

アクティブな負荷分散: 3 つのタスクがある場合、1 つの物理 CPU に 2 つ、もう 1 つの物理 CPU に 1 つある場合、2 番目の物理プロセッサがアイドル状態になると、スケジューラはタスクの 1 つをそれに移行しようとします。

これは、スレッド アフィニティを維持しようとするときに行われます。これは、スレッドが別の物理プロセッサに移行するときに、メイン メモリからすべてのレベルのキャッシュを補充する必要があり、タスクが停止するためです。

あなたの質問に答えるために(少なくともLinuxでは); デュアル コア ハイパースレッディング マシンに 2 つのスレッドがある場合、各スレッドは独自の物理コアで実行されます。

于 2008-12-11T19:04:10.750 に答える
5

Windows でのスレッド スケジューリングに関するいくつかの回答を探していましたが、将来この投稿に出くわす可能性のある人のためにここに投稿するいくつかの経験的な情報があります。

2 つのスレッドを起動する単純な C# プログラムを作成しました。クアッド コアの Windows 7 ボックスで、驚くべき結果が得られました。

アフィニティを強制しなかった場合、Windows は 2 つのスレッドのワークロードを 4 つのコアすべてに分散させました。コメント アウトされている 2 行のコードがあります。1 行はスレッドを CPU にバインドし、もう 1 行は理想的な CPU を提案します。この提案は効果がないように見えましたが、スレッド アフィニティを設定すると、Windows が各スレッドを独自のコアで実行するようになりました。

最適な結果を得るには、.NET Framework 4.0 クライアントに付属する無料で入手できるコンパイラ csc.exe を使用してこのコードをコンパイルし、複数のコアを備えたコンピューターで実行します。プロセッサ アフィニティの行をコメントアウトすると、タスク マネージャーは、スレッドが 4 つのコアすべてに分散し、それぞれが約 50% で実行されていることを示しました。アフィニティを設定すると、2 つのスレッドが 2 つのコアを 100% 使用し、残りの 2 つのコアはアイドル状態になります (これは、このテストを実行する前に予想していたことです)。

編集: 最初に、これら 2 つの構成でパフォーマンスにいくつかの違いがあることを発見しました。ただし、それらを再現できなかったので、それを反映するようにこの投稿を編集しました。スレッド アフィニティは、私が期待したものではなかったので、興味深いものでした。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

class Program
{
    [DllImport("kernel32")]
    static extern int GetCurrentThreadId();

    static void Main(string[] args)
    {
        Task task1 = Task.Factory.StartNew(() => ThreadFunc(1));
        Task task2 = Task.Factory.StartNew(() => ThreadFunc(2));
        Stopwatch time = Stopwatch.StartNew();
        Task.WaitAll(task1, task2);
        Console.WriteLine(time.Elapsed);
    }

    static void ThreadFunc(int cpu)
    {
        int cur = GetCurrentThreadId();
        var me = Process.GetCurrentProcess().Threads.Cast<ProcessThread>().Where(t => t.Id == cur).Single();
        //me.ProcessorAffinity = (IntPtr)cpu;     //using this line of code binds a thread to each core
        //me.IdealProcessor = cpu;                //seems to have no effect

        //do some CPU / memory bound work
        List<int> ls = new List<int>();
        ls.Add(10);
        for (int j = 1; j != 30000; ++j)
        {
            ls.Add((int)ls.Average());
        }
    }
}
于 2010-07-28T22:22:59.340 に答える
5

正常な OS は、独自のコアで計算集約型のタスクをスケジュールしようとしますが、コンテキスト切り替えを開始すると問題が発生します。最新の OS では、スケジューリング時に作業がないコアで物事をスケジュールする傾向がまだありますが、これにより、並列アプリケーションのプロセスがコアからコアへかなり自由にスワップされる可能性があります。並列アプリの場合、プロセスがコアのキャッシュで使用していた可能性のあるデータが失われるため、これは望ましくありません。人々はこれを制御するためにプロセッサ アフィニティを使用しますが、Linux では、sched_affinity() のセマンティクスはディストリビューション/カーネル/ベンダーなどによって大きく異なる場合があります。

Linux を使用している場合は、Portable Linux Processor Affinity Library (PLPA)を使用してプロセッサ アフィニティを移植可能に制御できます。これは、OpenMPIが内部的に使用して、プロセスがマルチコアおよびマルチソケット システムの独自のコアに確実にスケジューリングされるようにするためのものです。モジュールをスタンドアロン プロジェクトとしてスピンオフしたところです。OpenMPI は Los Alamos で他の多くの場所で使用されているため、これは十分にテストされたコードです。Windows でこれに相当するものがあるかどうかはわかりません。

于 2008-12-11T19:10:26.387 に答える
3

OS が可能な限り多くの物理コアを使用しない可能性は、本質的に 0% です。あなたのOSは愚かではありません。その仕事はすべてをスケジュールすることであり、利用可能なコアを完全に認識しています。CPU を集中的に使用するスレッドが 2 つある場合は、それらが 2 つの物理コアで実行されていることを確認します。

編集 少し詳しく説明すると、高性能のものについては、MPI やその他の本格的な並列化フレームワークに入ると、各コアで実行されるものを確実に制御する必要があります。

OS は、すべてのコアを利用するための一種の最善の努力を試みますが、「このスレッドは非常に長い間実行される」、または「私たちはこれだけ多くのスレッドが並行して実行されます。」したがって、完全な決定を下すことはできません。つまり、スレッドが時々新しいコアに割り当てられることを意味します。つまり、キャッシュ ミスなどに遭遇することになり、少し時間がかかります。ほとんどの場合、これで十分であり、パフォーマンスの違いに気付くことさえありません。また、それが重要な場合は、システムの残りの部分ともうまく機能します。(誰かのデスクトップ システムでは、これはおそらくかなり重要です。このタスク専用の数千の CPU を持つグリッドでは、特にうまくやりたいとは思わないでしょう。

したがって、大規模な HPC の場合、はい、各スレッドを 1 つのコアに固定する必要があります。しかし、ほとんどの小規模なタスクの場合は、それほど問題にはならず、OS のスケジューラを信頼できます。

于 2008-12-11T18:31:34.687 に答える
3

これは非常に適切で適切な質問です。ご存知のように、ハイパースレッド コアは実際の CPU/コアではありません。代わりに、これは仮想 CPU/コア (以降、コアと呼びます) です。Windows XP の Windows CPU スケジューラは、ハイパースレッディング (仮想) コアと実際のコアを区別できるはずです。この完璧な世界では、それは「ちょうどいい」ものであり、問​​題ではないと想像するかもしれません。あなたは間違っているでしょう。

Windows 2008 BizTalk サーバーを最適化するための Microsoft 独自の推奨事項では、HyperThreading を無効にすることを推奨しています。これは、ハイパースレッド コアの処理が完全ではなく、スレッドがハイパースレッド コアでタイム スライスを取得し、ペナルティ (実際のコアのパフォーマンスの一部、10% I' d が推測し、Microsoft は 20 ~ 30% を推測します)。

サーバーの効率を向上させるためにハイパースレッディングを無効にすることを提案している Microsoft の記事参照: http://msdn.microsoft.com/en-us/library/cc615012(BTS.10).aspx

これは、BIOS の更新後の 2 番目の推奨事項であり、彼らがそれをどれほど重要視しているかです。彼らが言うには:

マイクロソフトから:

" BizTalk Server および SQL Server コンピューターでハイパースレッディングを無効にする

BizTalk Server コンピューターでは、ハイパースレッディングを無効にすることが重要です。これは BIOS 設定であり、通常は BIOS セットアップのプロセッサ設定にあります。ハイパースレッディングにより、サーバーは実際よりも多くのプロセッサ/プロセッサ コアを搭載しているように見えます。ただし、ハイパースレッド プロセッサは通常、物理プロセッサ/プロセッサ コアのパフォーマンスの 20 ~ 30% を提供します。BizTalk Server がプロセッサの数をカウントして、自己調整アルゴリズムを調整するとき。ハイパースレッド プロセッサにより、これらの調整が歪められ、全体的なパフォーマンスに悪影響を及ぼします。"

現在、彼らはそれが自己調整アルゴリズムを放棄したためだと言っていますが、競合の問題についても言及しています(少なくとも私にとっては、より大きなスケジューリングの問題であることを示唆しています). 好きなように読んでください。ハイパースレッディングは、単一の CPU システムを使用していたときは優れたアイデアでしたが、現在では、このマルチコアの世界でパフォーマンスを損なう可能性がある複雑な問題に過ぎません。

ハイパースレッディングを完全に無効にする代わりに、Process Lasso (無料) などのプログラムを使用して、重要なプロセスのデフォルトの CPU アフィニティを設定し、それらのスレッドが仮想 CPU に割り当てられないようにすることができます。

Windows CPU スケジューラが仮想 CPU をどれだけうまく処理できるかを本当に知っている人はいないと思いますが、XP の処理が最悪であると言っても過言ではなく、それ以来徐々に改善されてきましたが、まだ完璧ではありません。実際、OS はこれらの低速の仮想コアに配置するのに最適なスレッドを認識していないため、完璧ではない可能性があります。それが問題である可能性があり、Microsoft がサーバー環境でハイパースレッディングを無効にすることを推奨している理由です。

また、HyperThreading がなくても、「コア スラッシング」の問題があることに注意してください。単一のコアでスレッドを維持できる場合、コア変更のペナルティが軽減されるため、それは良いことです。

于 2010-11-26T03:17:04.320 に答える
2

両方のスレッドにプロセッサ アフィニティを与えることで、両方のスレッドが同じ実行ユニットに対して確実にスケジュールされるようにすることができます。これは、Windows または UNIX のいずれかで、API (プログラムが要求できるようにするため) または管理インターフェース (管理者が設定できるようにするため) を介して行うことができます。たとえば、WinXP では、タスク マネージャを使用して、プロセスが実行できる論理プロセッサを制限できます。

それ以外の場合、スケジューリングは基本的にランダムになり、各論理プロセッサで 25% の使用率が予想されます。

于 2008-12-11T18:14:01.990 に答える
1

他のプラットフォームについては知りませんが、Intel の場合、Intel Software Networkでスレッドに関する多くの情報を公開しています。また、電子メールで購読できる無料のニュースレター (The Intel Software Dispatch) もあり、最近はそのような記事がたくさんあります。

于 2008-12-11T18:32:32.483 に答える
0

スレッドが特定のコアに関連付けられていない限り (スレッド アフィニティ) 、OS が 2 つのアクティブなスレッドを同じコアにディスパッチする可能性はゼロです。

この背後にある理由は、主にハードウェア関連です。

  • OS (および CPU) はできるだけ消費電力を抑えたいと考えているため、できるだけ効率的にタスクを実行して、できるだけ早く低電力状態に移行します。
  • すべてを同じコアで実行すると、はるかに速く加熱されます。異常な状態では、プロセッサが過熱し、クロックを下げて冷却することがあります。また、過度の熱は、CPU ファンの回転を速め (ラップトップを考えてください)、より多くの騒音を発生させます。
  • システムが実際にアイドル状態になることはありません。ISR と DPC はミリ秒ごとに実行されます (ほとんどの最新の OS では)。
  • コアからコアへのスレッド ホッピングによるパフォーマンスの低下は、ワークロードの 99.99% で無視できます。
  • 最新のすべてのプロセッサでは、最終レベルのキャッシュが共有されているため、コアの切り替えはそれほど悪くありません。
  • マルチソケット システム (Numa) の場合、OS はソケットからソケットへのホッピングを最小限に抑えるため、プロセスはメモリ コントローラーの「近く」に留まります。このようなシステム (数十または数百のコア) を最適化する場合、これは複雑なドメインです。

ところで、OS が CPU トポロジを認識する方法は、ACPI (BIOS によって提供されるインターフェイス) を介して行われます。

要約すると、システムの電源に関する考慮事項 (バッテリーの寿命、電力料金、冷却ソリューションからのノイズ) に帰着します。

于 2014-01-06T22:39:49.740 に答える