Я использую Threadpool в приложении на C #, которое должно выполнять некоторую нагрузку на процессор.Кстати, он кажется слишком медленным (РЕДАКТИРОВАТЬ: он выводит отладочную строку "Calculating on "
+ lSubArea.X + ":" + lSubArea.Y + " "
+ lSubArea.Width + ":" + lSubArea.Height
только несколько раз каждые 10 секунд, хотя я ожидаю увидеть, что по крайней мере NUM_ROWS_GRID ^ 2 = 16 раз каждые несколько секунд), также изменяя MinThreads черезSetMinThreads
метод.Я не знаю, переходить ли на пользовательские темы или есть ли способ ускорить его.Поиск в 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 - всего лишь заглушка, которую я использовал, чтобы знать, сколько раз она вызывается в секунду.Он будет заменен на интенсивную работу процессора, так как в этом случае я определю лучший способ использования потока.
РЕДАКТИРОВАТЬ: я удалил все 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);
}