CPUを集中的に使用する作業を行う必要があるC#アプリケーションでスレッドプールを使用しています。ちなみに、遅すぎるようです(編集:デバッグ文字列"Calculating on "
+ lSubArea.X + ":" + lSubArea.Y + " "
+ lSubArea.Width + ":" + lSubArea.Height
は10秒ごとに数回しか出力されませんが、少なくともNUM_ROWS_GRID ^ 2 =数秒ごとに16回表示されると予想されます)、SetMinThreads
メソッドを介してMinThreadsも変更します。カスタムスレッドに切り替えるかどうか、またはそれを高速化する方法があるかどうかはわかりません。Googleで検索すると結果が返されますが、何も機能しません。MSDNと同じ状況。
古いコードは次のとおりです。
private void StreamerRoutine()
{
if (this._state.Area.Width == 0 && this._state.Area.Height == 0)
this._state.Area = new Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
while (this._state.WorkEnd == false)
{
// Ends time slice if video is off
if (this._state.VideoOn == false)
Thread.Sleep(0);
else
{
lock(this._state.AreaSync)
{
Int32 lWidth = this._state.Area.Width / Constants.NUM_ROWS_GRID;
Int32 lHeight = this._state.Area.Height / Constants.NUM_ROWS_GRID;
for (Int32 lX = 0; lX + lWidth <= this._state.Area.Width; lX += lWidth)
for (Int32 lY = 0; lY + lHeight <= this._state.Area.Height; lY += lHeight)
ThreadPool.QueueUserWorkItem(CreateDiffFrame, (Object)new Rectangle(lX, lY, lWidth, lHeight));
}
}
}
}
private void CreateDiffFrame(Object pState)
{
Rectangle lSubArea = (Rectangle)pState;
SmartDebug.DWL("Calculating on "
+ lSubArea.X + ":" + lSubArea.Y + " "
+ lSubArea.Width + ":" + lSubArea.Height);
// TODO : calculate frame
Thread.Sleep(0);
}
編集:CreateDiffFrame関数は、1秒間に何回呼び出されるかを知るために使用したスタブにすぎません。この場合、スレッドを使用する最良の方法を定義するので、CPUを集中的に使用する作業に置き換えられます。
編集:私はすべてのThread.Sleep(0);を削除しました。ルーチンを高速化する方法かもしれないと思いましたが、ボトルネックになる可能性があります。新しいコードは次のとおりです。
編集:キャッシュされた値と無限のループを回避するために、WorkEndとVideoOnを揮発性にしました。セマフォも追加して、前のバンチが完了した後にすべてのワークアイテムのバンチを開始するようにしました。現在は非常にうまく機能しています。
private void StreamerRoutine()
{
if (this._state.Area.Width == 0 && this._state.Area.Height == 0)
this._state.Area = new Rectangle(0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
this._state.StreamingSem = new Semaphore(Constants.NUM_ROWS_GRID * Constants.NUM_ROWS_GRID, Constants.NUM_ROWS_GRID * Constants.NUM_ROWS_GRID);
while (this._state.WorkEnd == false)
{
if (this._state.VideoOn == true)
{
for (int i = 0; i < Constants.NUM_ROWS_GRID * Constants.NUM_ROWS_GRID; i++)
this._state.StreamingSem.WaitOne();
lock(this._state.AreaSync)
{
Int32 lWidth = this._state.Area.Width / Constants.NUM_ROWS_GRID;
Int32 lHeight = this._state.Area.Height / Constants.NUM_ROWS_GRID;
for (Int32 lX = 0; lX + lWidth <= this._state.Area.Width; lX += lWidth)
for (Int32 lY = 0; lY + lHeight <= this._state.Area.Height; lY += lHeight)
ThreadPool.QueueUserWorkItem(CreateDiffFrame, (Object)new Rectangle(lX, lY, lWidth, lHeight));
}
}
}
}
private void CreateDiffFrame(Object pState)
{
Rectangle lSubArea = (Rectangle)pState;
SmartDebug.DWL("Calculating on " + lSubArea.X + ":" + lSubArea.Y + " " + lSubArea.Width + ":" + lSubArea.Height);
// TODO : calculate frame
this._state.StreamingSem.Release(1);
}