最近、私は自分のプログラムを構築するときに、より健康志向になってきています。ほとんどのプログラムは実行に 2 ~ 3 分かかることに気付きました。この使用法をコードでプログラム的に制限しますか? これにより、特定の時間に複数のプログラムを実行できるようになります。
ありがとう、ニディ
最近、私は自分のプログラムを構築するときに、より健康志向になってきています。ほとんどのプログラムは実行に 2 ~ 3 分かかることに気付きました。この使用法をコードでプログラム的に制限しますか? これにより、特定の時間に複数のプログラムを実行できるようになります。
ありがとう、ニディ
このスレッドは 4 年以上前のものですが、受け入れられた回答が質問に答えるのではなく、質問を批判していることに今でも悩まされています。プログラムが使用する CPU 時間を制限したい正当な理由はたくさんありますが、思いついた理由をいくつか挙げることができます。
利用可能なすべての空き CPU サイクルを使用しないのはもったいないように思えるかもしれませんが、この考え方には欠陥があります。古い CPU とは異なり、最新の CPU のほとんどは固定のクロック速度で動作しません。多くの CPU には、負荷が低いときにクロック速度と CPU 電圧を下げる省電力モードがあります。また、CPU は、NOOP を実行するよりも計算を実行するときに多くの電力を消費します。これは特に、高負荷時に CPU を冷却するためにファンが必要なラップトップに関係します。短時間 100% でタスクを実行すると、25% でタスクを 4 倍長く実行するよりもはるかに多くのエネルギーを消費する可能性があります。
バックグラウンドで定期的にファイルのインデックスを作成するように設計されたバックグラウンド タスクを作成しているとします。インデックス作成タスクは、低い優先度でできるだけ多くの CPU を使用する必要がありますか、それとも 25% に調整して必要なだけ時間をかけて実行する必要がありますか? ラップトップの CPU を 100% 消費すると、CPU が過熱し、ファンが作動し、バッテリーがかなり早く消耗し、ユーザーはイライラします。インデックス サービスがそれ自体を抑制した場合、ラップトップは非常に低い CPU クロック速度と電圧で完全に受動的な冷却を使用して実行できる可能性があります。
ちなみに、Windows インデックス サービスは、新しいバージョンの Windows では抑制されますが、古いバージョンでは抑制されませんでした。まだ自分自身を調整せず、頻繁にユーザーを悩ませているサービスの例については、「Windows インストーラー モジュール」を参照してください。
C# でアプリケーションの一部を内部的に調整する方法の例:
public void ThrottledLoop(Action action, int cpuPercentageLimit) {
Stopwatch stopwatch = new Stopwatch();
while(true) {
stopwatch.Reset();
stopwatch.Start();
long actionStart = stopwatch.ElapsedTicks;
action.Invoke();
long actionEnd = stopwatch.ElapsedTicks;
long actionDuration = actionEnd - actionStart;
long relativeWaitTime = (int)(
(1/(double)cpuPercentageLimit) * actionDuration);
Thread.Sleep((int)((relativeWaitTime / (double)Stopwatch.Frequency) * 1000));
}
}
Governor
CPU 使用率を調整するクラスを作成できます。このクラスには、CPU バウンド関数によって定期的に呼び出されるユーティリティ メソッドが含まれます (たとえば、関数の while ループ内でこのユーティリティ関数を呼び出す)。ガバナーは、経過時間が特定のしきい値を超えたかどうかを確認し、CPU をすべて消費しないように一定期間スリープします。
シングル スレッドの CPU バウンド関数がある場合に、CPU 使用率を 50% に抑える、頭のてっぺんからの単純な Java 実装を次に示します (アイデアを理解するためだけに)。
public class Governor
{
long start_time;
public Governor()
{
this.start_time = System.currentTimeMillis();
}
public void throttle()
{
long time_elapsed = System.currentTimeMillis() - this.start_time;
if (time_elapsed > 100) //throttle whenever at least a 100 millis of work has been done
{
try { Thread.sleep(time_elapsed); } catch (InterruptedExceptione ie) {} //sleep the same amount of time
this.start_time = System.currentTimeMillis(); //reset after sleeping.
}
}
}
CPU バウンド関数は をインスタンス化し、関数内で定期的にGovernor
呼び出すだけです。throttle
マルチコア プロセッサを使用している場合は、各プロセスのアフィニティを設定して、使用するコアのみを使用することができます。これは私が知っている最も近い方法です。ただし、デュアル コアでは 50%、クアッド コアでは 25% の割合を割り当てることしかできません。
正直なところ、アプリによる CPU 使用率を制限しようとすることを心配するよりも、アプリケーションのプロファイリングにもっとエネルギーを集中して、存在する可能性のあるボトルネックや非効率性を発見して修正する必要があると思います。
コードがまったく実行されている場合、それは 100% です
いくつかの睡眠で滑ると効果があるかもしれません。
私はその 2、3 分の数字について疑問に思う必要があります。私もそれを見たことがありますが、おそらく実際には必要のない多くのものをロードして初期化していると思います。
他に実行中のタスクがない場合、アプリが使用可能なすべてのCPU容量を使用するのは間違っていますか?そこにあるように利用可能であり、無料で使用できます。だからそれを使ってください!
どういうわけかタスクのCPU使用率を制限すると、完了するまでに時間がかかります。ただし、同じ数のCPUサイクルが必要になるため、何も得られません。アプリケーションの速度を落とすだけです。
しないでください。試してはいけません。あなたがすべき理由はありません。
CPU 使用率に上限を設けようとするのではなく、アプリケーションのパフォーマンスの問題を理解する必要があると思います。Visual Studio プロファイラーを使用して、アプリケーションが最初に 2 ~ 3 分間 100% の CPU を使用している理由を確認できます。これにより、アプリのホット スポットが明らかになり、この問題に対処できるようになります。
Windows でリソースの調整を行う方法について一般的に質問している場合は、「タスク」オブジェクトを見ることができます。ジョブ オブジェクトを使用すると、ワーキング セット、プロセスの優先度などの制限を設定できます。
ここでジョブ オブジェクトのドキュメントを確認できます http://msdn.microsoft.com/en-ca/library/ms684161(VS.85).aspx これがお役に立てば幸いです。ありがとう