58

複数のプロセスまたはスレッドを使用するプログラムを作成する方法を理解できます。新しいプロセスを fork() して IPC を使用するか、複数のスレッドを作成してそのような通信メカニズムを使用します。

コンテキストの切り替えも理解しています。つまり、CPU が 1 つしかない場合、オペレーティング システムは各プロセスの時間をスケジュールします (そして、スケジューリング アルゴリズムは無数にあります)。これにより、複数のプロセスを同時に実行することができます。

マルチコア プロセッサ (またはマルチプロセッサ コンピュータ) を使用できるようになったので、2 つの別々のコアで 2 つのプロセスを同時に実行できます。

私の質問は、最後のシナリオに関するものです。カーネルは、プロセスが実行されるコアをどのように制御しますか? 特定のコアでプロセスをスケジュールするシステム コール (Linux または Windows) はどれですか?

私が尋ねている理由: 私はコンピューティングの最近のトピックを調査する学校のプロジェクトに取り組んでおり、マルチコア アーキテクチャを選択しました。そのような環境でプログラミングする方法 (デッドロックや競合状態を監視する方法) に関する資料はたくさんあるようですが、個々のコア自体の制御に関する資料はあまりありません。いくつかのデモンストレーション プログラムを作成し、アセンブリ命令または C コードを提示して、「2 番目のコアで無限ループを実行しています。その特定のコアの CPU 使用率のスパイクを見てください。」 .

コード例はありますか? それともチュートリアル?

編集:明確にするために-これはOSの目的であり、OSにこれを任せるべきだと多くの人が言っています。同意します!しかし、私が求めている (または感触を得ようとしている) のは、オペレーティング システムがこれを行うために実際に行っていることです。スケジューリング アルゴリズムではありませんが、「コアが選択されたら、そのコアが命令のフェッチを開始するには、どの命令を実行する必要がありますか?」

4

9 に答える 9

40

他の人が述べているように、プロセッサ親和性はオペレーティングシステム固有です。オペレーティングシステムの範囲外でこれを実行したい場合は、多くの楽しみがあります。つまり、苦痛を意味します。

SetProcessAffinityMaskそうは言っても、他の人はWin32について言及しています。Linuxカーネルでプロセッサ親和性を設定する方法については誰も言及していないので、そうします。sched_setaffinity(2)システムコールを使用する必要があります。これがその方法に関する素晴らしいチュートリアルです。

このシステムコールのコマンドラインラッパーはですtaskset(1)。たとえば
taskset -c 2,3 perf stat awk 'BEGIN{for(i=0;i<100000000;i++){}}'、ビジーループのperf-statをコア2または3のいずれかで実行するように制限します(コア間での移行は許可されますが、これら2つの間でのみ可能です)。

于 2009-04-07T17:52:42.490 に答える
31

通常、アプリを実行するコアの決定はシステムによって行われます。ただし、アプリケーションの「アフィニティ」を特定のコアに設定して、そのコアでのみアプリを実行するようにOSに指示することができます。通常、これは良い考えではありませんが、それが理にかなっている場合があるまれなケースがあります。

Windowsでこれを行うには、タスクマネージャーを使用し、プロセスを右クリックして、[アフィニティの設定]を選択します。SetThreadAffinityMask、SetProcessAffinityMask、SetThreadIdealProcessorなどの関数を使用して、Windowsでプログラムで実行できます。

ETA:

OSが実際にスケジューリングを行う方法に興味がある場合は、次のリンクを確認してください。

コンテキストスイッチングに関するウィキペディアの記事

スケジューリングに関するウィキペディアの記事

Linuxカーネルでのスケジューリング

最新のOSのほとんどでは、OSはスレッドをスケジュールしてコア上で短時間実行します。タイムスライスが期限切れになるか、スレッドがIO操作を実行してコアを自発的に生成すると、OSは別のスレッドをコアで実行するようにスケジュールします(実行する準備ができているスレッドがある場合)。どのスレッドがスケジュールされるかは、OSのスケジューリングアルゴリズムによって異なります。

コンテキストスイッチがどのように発生するかについての実装の詳細は、CPUとOSに依存します。通常、カーネルモードへの切り替え、OSが前のスレッドの状態の保存、新しいスレッドの状態の読み込み、ユーザーモードへの切り替え、新しく読み込まれたスレッドの再開が含まれます。上記でリンクしたコンテキスト切り替えの記事には、これについてもう少し詳しく説明しています。

于 2009-03-19T20:42:26.067 に答える
4

OpenMPIプロジェクトには、Linuxでのプロセッサアフィニティを移植可能な方法で設定するためのライブラリがあります。

しばらく前に、私はこれをプロジェクトで使用しましたが、うまく機能しました。

警告:オペレーティングシステムがコアに番号を付ける方法を見つける際にいくつかの問題があったことをぼんやりと覚えています。これを、それぞれ4コアの2XeonCPUシステムで使用しました。

見てみるとcat /proc/cpuinfo役立つかもしれません。私が使った箱では、それはかなり奇妙です。煮詰めた出力は最後です。

明らかに、偶数番号のコアは最初のCPUにあり、奇数番号のコアは2番目のCPUにあります。しかし、私が正しく覚えていれば、キャッシュに問題がありました。これらのIntelXeonプロセッサでは、各CPUの2つのコアがL2キャッシュを共有します(プロセッサにL3キャッシュがあるかどうかは覚えていません)。仮想プロセッサ0と2は1つのL2キャッシュを共有し、1と3は1つを共有し、4と6は1つを共有し、5と7は1つを共有したと思います。

この奇妙さのために(1.5年前、Linuxでのプロセス番号付けに関するドキュメントが見つかりませんでした)、この種の低レベルの調整を慎重に行うことになります。ただし、明らかにいくつかの用途があります。コードが数種類のマシンで実行されている場合は、この種の調整を行う価値があるかもしれません。別のアプリケーションは、コンパイラがこの汚い仕事をしてスマートなスケジュールを計算できるStreamItのようなドメイン固有言語になります。

processor       : 0
physical id     : 0
siblings        : 4
core id         : 0
cpu cores       : 4

processor       : 1
physical id     : 1
siblings        : 4
core id         : 0
cpu cores       : 4

processor       : 2
physical id     : 0
siblings        : 4
core id         : 1
cpu cores       : 4

processor       : 3
physical id     : 1
siblings        : 4
core id         : 1
cpu cores       : 4

processor       : 4
physical id     : 0
siblings        : 4
core id         : 2
cpu cores       : 4

processor       : 5
physical id     : 1
siblings        : 4
core id         : 2
cpu cores       : 4

processor       : 6
physical id     : 0
siblings        : 4
core id         : 3
cpu cores       : 4

processor       : 7
physical id     : 1
siblings        : 4
core id         : 3
cpu cores       : 4
于 2009-04-09T21:59:10.017 に答える
2

他の人が述べているように、それはオペレーティングシステムによって制御されます。OSによっては、特定のプロセスが実行されるコアに影響を与えることができるシステムコールを提供する場合と提供しない場合があります。ただし、通常はOSにデフォルトの動作をさせるだけです。37個のプロセスが実行されている4コアシステムがあり、それらのプロセスのうち34個がスリープしている場合、残りの3つのアクティブなプロセスを別々のコアにスケジュールします。

非常に特殊なマルチスレッドアプリケーションでコアアフィニティを使用すると、速度が向上する可能性があります。たとえば、2つのデュアルコアプロセッサを搭載したシステムがあるとします。3つのスレッドを持つアプリケーションがあり、2つのスレッドが同じデータセットで頻繁に動作し、3番目のスレッドが異なるデータセットを使用するとします。この場合、同じプロセッサで相互作用する2つのスレッドと、他のプロセッサで相互作用する3番目のスレッドを使用すると、キャッシュを共有できるため、最もメリットがあります。OSは、各スレッドがアクセスする必要のあるメモリを認識していないため、スレッドをコアに適切に割り当てない可能性があります。

オペレーティングシステムに興味がある場合は、スケジューリングを読んでください。x86でのマルチプロセッシングの詳細については、Intel64およびIA-32アーキテクチャソフトウェア開発者マニュアルを参照してください。第3A巻、第7章および第8章には関連情報が含まれていますが、これらのマニュアルは非常に技術的であることに注意してください。

于 2009-03-19T21:14:00.347 に答える
1

OSはこれを行う方法を知っています。あなたがする必要はありません。実行するコアを指定すると、あらゆる種類の問題が発生する可能性があり、その中には実際にプロセスが遅くなるものもあります. OSに理解させてください。新しいスレッドを開始するだけです。

たとえば、プロセスにコア x で開始するように指示したが、コア x にすでに大きな負荷がかかっている場合は、OS に処理させた場合よりも悪い結果になります。

于 2009-03-19T20:39:45.700 に答える
1

組み立て説明書がわかりません。しかし、Windows API 関数はSetProcessAffinityMaskです。Picasa を 1 つのコアだけで実行するために、少し前にまとめたもののを見ることができます。

于 2009-03-19T21:00:45.260 に答える