.NET中如何最有效地利用多核进行短计算?上下文如下:我正在用C#为一种名为Heron的小型编程语言编写解释器,它具有一些可以并行执行的原始列表操作。我面临的最大挑战之一是,每当遇到可并行操作时,将评估人员完成的工作有效地分配到不同的核心。这可以是短线操作,也可以是长线操作,事先很难确定。我不必担心的一件事是同步数据:并行操作显然不允许修改数据。所以我的主要问题是:我也对一个相关问题感兴趣:如果您想对并行操作进行大量操作,那么您将需要从.Net4.0开始。这是.Net文档中的并行编程。你想从这里开始。.Net4.0在多核利用率方面增加了很多。这是一个简单的示例:当前3.5串行方法:for(inti=0;iNew.Net4.0并行方法:Parallel.For(0,30000,(i)=>doSomething(i));Parallel.For方法自动缩放可用核心的数量,你可以看到你可以多快开始利用它。框架中有许多支持完整线程/任务管理的新库,例如你的示例(包括所有管道)。有ParallelLINQ(PLINQ)、TaskFactory、TaskScheduler和其他一些库。简而言之,对于您提出的特定任务,.Net4.0将对您大有裨益,我将继续获取免费测试版2(RC即将推出)并开始使用。(不,我不为Microsoft工作......但我很少看到即将推出的版本如此完美地满足需求,所以我强烈建议使用.Net4.0)因为我没有想使用VS2010进行开发,我发现ThreadPool没有最佳性能来跨内核分配工作(我认为是因为它启动/停止了太多线程)我最终推出了自己的。希望其他人认为这个有用:usingSystem;使用System.Collections.Generic;使用System.Linq;使用系统文本;使用系统线程;namespaceHeronEngine{//////代表一个工作项。///公共委托voidTask();//////此类旨在有效地分配///多个核心的工作。///publicstaticclassParallelizer{//////线程尚未获取的任务列表///staticListallTask??s=newList();//////线程列表。应该是每个核心一个。///静态列表线程=newList();//////当设置信号表明还有更多工作要做时///staticManualResetEventsignal=newManualResetEvent(false);//////用于告诉线程停止工作。///staticboolshuttingDown=false;//////创建一些高优先级线程来执行///工作。希望操作系统将每个线程分配给///一个单独的核心。//////publicstaticvoidInitialize(intcores){for(inti=0;i///向所有线程表明有工作///要完成。///publicstaticvoidReleaseThreads(){signal.Set();}//////使用通过取消设置信号来表明没有更多的工作///要完成。注意:///如果关闭将不起作用。///publicstaticvoidBlockThreads(){if(!shuttingDown)signal.Reset();}//////返回任何排队等待执行的任务,///如果没有工作则返回NULL。如果没有更多任务,它将重置///有效阻塞所有线程的全局信号///要完成的工作。//////publicstaticTaskGetTask(){lock(allTask??s){if(allTask??s.Count==0){BlockThreads();returnnull;}Taskt=allTask??s.Peek();allTask??s.Pop();returnt;}}//////每个线程的主要函数///publicstaticvoidThreadMain(){while(!shuttingDown){//等待工作可用signal.WaitOne();//获取一个可用的任务Tasktask=GetTask();//注意任务可能仍然是nullbecaue//另一个线程可能先得到它while(task!=null){//完成工作task();//获取下一个任务task=GetTask();}}}//////将工作分配给与///核心数相等的多个线程。所有任务都将在可用内核上运行。//////publicstaticvoidDistributeWork(ListlocalTask??s){//创建一个句柄列表,指示主线程应该等待什么WaitHandle[]handles=newWaitHandle[localTask??s.Count];lock(allTask??s){//遍历localTask??s列表,创建一个新任务//将在完成时发出信号。for(inti=0;i{t();e.Set();};allTask??s.Add(signalingTask);//设置相应的等待处理程序handles[i]=e;}}//向等待线程发送信号ReleaseThreads();//Waituntilallthedesignatedworkitemsarecompleted.Semaphore.WaitAll(handles);}//////向系统指示线程应该终止///并解除阻塞t下摆。///publicstaticvoidCleanUp(){shuttingDown=true;释放线程();我会选择线程池,即使它有问题,MS正在投资改进它,看起来.NET4会有改进在这一点上,我认为最好的方法是使用线程池包装在你自己的对象中等待决定你自己的实现以上是C#学习教程:如何最有效地利用.NET中的多核进行短计算?如果分享的所有内容对您有用,需要了解更多C#学习教程,希望您多多关注---本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
