外部 DLL を 1 つの CPU に制限するにはどうすればよいですか?
-
22-08-2019 - |
質問
システム リソースをあまり消費しないように、1 つの CPU だけで実行したいプログラムがあります。問題は、利用可能なすべての CPU コアを自動的に使用する外部 DLL を呼び出すことです。外部 DLL のソース コードがありません。DLL が 1 つの CPU のみを使用するように制限するにはどうすればよいですか?
編集:助けてくれてありがとう。1 つの CPU (Windows) に制限するために使用したコードは次のとおりです。
// Limit the process to only 1 thread so we don't chew up system resources
HANDLE ProcessHandle = GetCurrentProcess();
DWORD ProcessAffinityMask;
DWORD SystemAffinityMask;
if(GetProcessAffinityMask(ProcessHandle,&ProcessAffinityMask,&SystemAffinityMask)
&& SystemAffinityMask != 0)
{
// Limit to 1 thread by masking all but 1 bit of the system affinity mask
DWORD NewProcessAffinityMask = ((SystemAffinityMask-1) ^ SystemAffinityMask) & SystemAffinityMask;
SetProcessAffinityMask(ProcessHandle,NewProcessAffinityMask);
}
編集:プロセスの優先順位を設定するという Brannon のアプローチは、プロセスがリソースを使い果たさないようにするという、私が望んでいることに対してさらにうまく機能することがわかりました。そのコードは次のとおりです (Windows)。
// Make the process low priority so we don't chew up system resources
HANDLE ProcessHandle = GetCurrentProcess();
SetPriorityClass(ProcessHandle,BELOW_NORMAL_PRIORITY_CLASS);
解決
設定プロセッサ親和性は間違ったアプローチです。 OSハンドルスケジューリングをしてみましょう。
マシンがアイドル状態に座っている場合は、、あなたはできる限り多くのプロセッサを使用します。そうしないと、理由もなく少ない作業をやっています。マシンがビジー状態の場合は、「自由」のサイクルを利用すると悪影響他のプロセスに影響を与えないようにしたい。
Windowsはこの機能がビルトインされています。このための適切な解決策は、プロセスの基本優先順位を設定することである。
http://msdn.microsoft.comを参照してください。 SetPriorityClass()
の詳細については/en-us/library/ms686219(VS.85).aspxするます。
、あなたのプロセスの優先順位を変更するには、タスクマネージャを使用します。
他のヒント
プログラムの CPU アフィニティを設定できます。試してみてください SetProcessAffinityMask Windows 上の機能または sched_setaffinity Linux 上で。
通常、DLLはそれを呼び出すコードと同じスレッド/メモリ空間に住んでいます。 DLL自体を呼び出すの行為は、スレッドを作成するべきではありません。 DLLを呼び出すと、多くのスレッドを作成するようであれば、それはDLL自体はどこか、それはコードです内のスレッドを作成していることを意味します。あなたはDLLのための任意のソースコードやドキュメントを持っていない場合は、あまりありません、あなたはそれについて行うことができます(あなたはDLLがその仕事をしたい場合は、ずっとあなたがこのことについて行う必要はありません)。
あなたはあなたのアプリケーションの優先順位で遊んでみてください - それが作成されたものをスレッド変化していない場合でも、低に設定すると、CPU使用率を変更する場合があります。しかし、あなたが本当にしたいでしょうが、この獣のドキュメントを取得することであると思われます。コードがどのように機能するかを知らなくても、一般的に、あなたはそれがどのように動作するか変更するために行うことができます多くはありません。いいえ、超天才はそれを変更することはできません。
のEr ......なぜ?真剣に、なぜあなたはあなたのような方法で追加の性能を与えることができるのライブラリを制限するのでしょうか?あなたは、共有リソースか何かにアクセスしようとしていますか?一つは、マルチスレッドライブラリが安全にこれを扱うことができるだろうと思うだろう。
あなたが言及していない何かがありますがない限り、私もを単一のスレッドにマルチスレッドライブラリを制限するを試みるための任意の有効な理由を見ることができません。
プログラムでは 1 つのスレッドを使用しますが、外部 DLL では複数のスレッドを使用したくないということですか?外部 DLL の動作をあまり制御することはできませんが、次のようなアプローチが考えられます。
- 使用 「半同期/半非同期:効率的で適切に構造化された同時 I/O のためのアーキテクチャ パターン」 1 つのスレッドから外部 DLL への作業項目をキューに入れる設計パターン。
- または、他の DLL がプロセスにロードされるため、プロセスまたはスレッドのプロセッサ アフィニティを 1 つの CPU だけに設定できる場合があります。レイモンド・チェンの作品を参照 「心霊デバッグ:高価な 4 プロセッサ マシンが 3 つのプロセッサを無視するのはなぜですか。」.
あなたはこれが何のためにあるのかプラットフォーム言いませんでした。私はここに窓を仮定するつもりです。
子プロセスを作成し、ジョブに関連付けますのオブジェクト。そのジョブオブジェクトが使用可能なCPUコアを1つだけ含まれるようにするためにあなたはその後、プロセッサアフィニティを設定することができます。子プロセスは、ジョブオブジェクトのためのプロセッサアフィニティのサブセットではありません何にでもアフィニティマスクを変更することができません。また、あなたが制限JOB_OBJECT_LIMIT_BREAKAWAY_OK
またはジョブまたは他の子プロセスが仕事から抜け出すことができるようになります上の拡張制限JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK
を設定しないように覚えておく必要があります。
また、あなたが仕事の優先順位とスケジューリングクラスを設定することができます。おそらく下のCPUおよび/またはIOの優先レベルで子プロセスを作成するのに十分だろうか?