gpt4 book ai didi

c# - C#中的线程池太慢了,有没有办法加快速度? Thread.Sleep(0)和QueueUserWorkItem问题

转载 作者:行者123 更新时间:2023-12-03 13:21:24 28 4
gpt4 key购买 nike

我在需要执行一些CPU密集型工作的C#应用​​程序中使用Threadpool。顺便说一句,它似乎太慢了(编辑:每10秒仅输出几次调试字符串"Calculating on "
+ lSubArea.X + ":" + lSubArea.Y + " "
+ lSubArea.Width + ":" + lSubArea.Height
,而我希望每隔几秒钟至少看到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函数只是一个 stub ,我用来知道每秒被调用多少次。当我定义了在这种情况下使用线程的最佳方法时,它将被占用大量CPU的工作所代替。

编辑:我删除了所有Thread.Sleep(0);我认为这可能是加快例程运行速度的一种方法,但似乎可能成为瓶颈。.新代码如下:

编辑:我使WorkEnd和VideoOn volatile ,以避免缓存的值,所以无休止的循环;我还添加了一个信号灯,以使每束工作项在上一束工作完成后开始..现在它工作得很好
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);

}

最佳答案

确实没有一种好方法可以准确地告诉您是什么让您的代码运行缓慢,但有几点值得注意:

  • Thread.Sleep(0)。当您执行此操作时,您将放弃操作系统中的其余时间片,并放慢所有操作,因为CreateDiffFrame()实际上只有在操作系统调度程序返回之前才能返回。
  • Rectangle的对象强制转换,它是一个结构。发生这种情况时,您会产生boxing的开销,这对于真正的计算密集型操作来说并不会是您想要的。
  • 您的锁定请求(this._state.AreaSync)。也可能是AreaSync也被锁定在其他位置,这可能会减慢速度。
  • 您可能对项目进行了太细粒度的排队-如果您将非常小的工作项目排队,那么与一次实际完成的工作量相比,一次将这些项目放入一个队列的开销可能会很大。您也许还可以考虑将内部循环的内容放入排队的工作项中,以减少这种开销。

  • 如果您要尝试并行计算,是否使用 PLINQ或其他类似框架进行了调查?

    关于c# - C#中的线程池太慢了,有没有办法加快速度? Thread.Sleep(0)和QueueUserWorkItem问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8457303/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com