c# - Parallel.For 与常规线程

标签 c# multithreading performance

我试图理解为什么 Parallel.For 能够在以下场景中胜过多个线程:考虑一批可以并行处理的作业。在处理这些作业时,可能会添加新的工作,然后也需要对其进行处理。 Parallel.For 解决方案如下所示:

var jobs = new List<Job> { firstJob };
int startIdx = 0, endIdx = jobs.Count;
while (startIdx < endIdx) {
  Parallel.For(startIdx, endIdx, i => WorkJob(jobs[i]));
  startIdx = endIdx; endIdx = jobs.Count;
}

这意味着 Parallel.For 需要同步的地方有多次。考虑一个以面包为先的图算法算法;同步的数量会非常大。浪费时间,不是吗?

在老式的线程方法中尝试相同的方法:

var queue = new ConcurrentQueue<Job> { firstJob };
var threads = new List<Thread>();
var waitHandle = new AutoResetEvent(false);
int numBusy = 0;
for (int i = 0; i < maxThreads; i++) 
  threads.Add(new Thread(new ThreadStart(delegate {
    while (!queue.IsEmpty || numBusy > 0) {
      if (queue.IsEmpty)
        // numbusy > 0 implies more data may arrive
        waitHandle.WaitOne();

      Job job;
      if (queue.TryDequeue(out job)) {
        Interlocked.Increment(ref numBusy);
        WorkJob(job); // WorkJob does a waitHandle.Set() when more work was found
        Interlocked.Decrement(ref numBusy);
      }
    }
    // others are possibly waiting for us to enable more work which won't happen
    waitHandle.Set(); 
})));
threads.ForEach(t => t.Start());
threads.ForEach(t => t.Join());

Parallel.For 代码当然更简洁,但我无法理解的是,它甚至更快!任务调度程序就那么好吗?消除了同步,没有忙等待,但线程方法始终较慢(对我而言)。这是怎么回事?线程方法可以更快吗?

编辑:感谢所有的答案,我希望我可以选择多个。我选择了那个也显示出实际可能改进的那个。

最佳答案

这两个代码示例并不完全相同。

Parallel.ForEach() 将使用有限数量的线程并重新使用它们。第二个示例已经开始落后了,必须创建多个线程。这需要时间。

maxThreads 的值是多少?非常关键,在 Parallel.ForEach() 中它是动态的。

Is the task scheduler just that good?

还不错。 TPL 使用工作窃取和其他自适应技术。您将很难做得更好。

关于c# - Parallel.For 与常规线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13070339/

相关文章:

c# - 样式与文件位置 bundle

c# - Silverlight:访问企业数据的最佳实践

c# - Windows Azure 中的.Net 4.0 线程池

c++ - 如何使序列化并行运行

performance - 多次修改后的SVN性能

c# - 密码字段的水印文本

c# -++运算符线程安全吗?

c++ - Log4cxx 日志语句挂起

mysql - 优化Mysql查询Left Join

c# - StreamReader 和 StreamWriter 的性能问题