这是不可否认的:多核计算机就在这里.
这就是:高效的多核编程非常困难.这不仅仅是了解pthreads的情况.
这是有争议的:"街头开发者"需要关注他/她自己的这些发展.
您在多大程度上担心必须扩展多核技能?您正在编写的软件是并行化的候选者,如果是,您是否正在做任何教育自己的事情(如果您还不知道这些技术)?或者您是否相信操作系统会处理大部分操作系统,语言运行时会做到这一点,您的应用程序将很乐意坐在一个核心上并让其他人做他们的事情?
是你的程序通常CPU的约束?
如果没有,请忘掉它.它与您无关,为您的用户提供更流畅的体验,而不会对您提出任何要求.
很酷,嗯?
如果您受CPU限制,并且您的问题可以并行化,那么您可以利用多个核心.现在是开始担心它的时候了.
来自评论:
建议改进答案:粗略解释如何判断您的程序是否受CPU限制. - Earwicker
CPU限制意味着阻止程序运行得更快的事情是缺乏计算能力.与IO绑定(或有时网络绑定)进行比较.主板和处理器选择不当可能会导致机器受到内存限制(是的,我正在看着你,alpha).
所以你需要知道你的程序在做什么(不管机器有多忙......)要找出类似unix的系统运行top
.在Windows上使用taskmanager(感谢Roboprog).
在每个核心负载小于1的计算机上(即当您没有做任何事情时,您的桌面计算机),CPU绑定进程将始终拥有超过50%的处理器(通常超过90%).当负载平均值高于该值时(即,您有三个编译,SETI @ home和后台运行的两个对等网络),CPU绑定进程将占很大比例(# of cores)/(load average)
.
只是旁注:如果您的应用程序具有GUI并且进行了大量计算,请始终在单独的线程上进行强烈的计算.忘记这样做是为什么GUI冻结了.
我不同意目前接受的答案.
多核机器最重要的方面是CPU和主内存相距甚远.这意味着除非应用程序"令人尴尬地并行"或易于并行化,否则很可能是内存绑定而不是CPU绑定.浮点乘法大约需要4个时钟周期,而从主存储器中取出存储器需要数百个时钟周期.因此,利用缓存局部性变得很重要.
对于难以并行化的应用程序,如果在单核上实现的性能足够(大多数应用程序属于此类),则无需并行化.但如果不是(或者你的竞争对手的应用程序因并行化而响应更快),那么你最好重构你的应用程序以更好地利用并行性和缓存局部性.模糊地说,重构的应用程序将由相对独立(或通信较少)的子模块组成,这些子模块并行运行(参见本例中的一个).
请参阅http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-183.html,以获得有关多核以及前进方向的详细信息.他们说的主要观点是:
时钟速度不再像以前那样增加.与少量快速处理器相比,制造更多数量更慢,更简单的内核更具成本效益.
内存(越来越)远离CPU
几年后,Web服务器中将有1000个核心,桌面上将有100个核心.因此,计划将您的应用程序(可能是自动扩展)扩展到100或1000个核心.这意味着您应该创建几个独立的任务.
线程难以使用,因此更好地处理"任务".
这是开始学习函数式语言的一个很好的论据,这些函数语言更容易针对并行执行进行优化.
我认为这通常值得关注,温和地说.
几乎不需要说过去几十年来CPU速度的大幅提升是非常有价值的,而且进一步的收益也同样有价值.
但是,从现在开始,这些收益主要包括核心数量的定期增加.因此,要从这些收益中获益,软件需要可并行化.
许多应用程序的许多计算密集型部分实际上是用SQL编写的,因此它们已经可以运行并且能够被RDBMS分解为并行任务.那些人可以放松一下.
但是我们这些人主要用C#编写,即使我们正在编写GUI,我们也需要密切关注这些东西.GUI经常必须对它呈现给用户的任何模型执行一些有用的操作,并且当用户必须坐下并等待它完成时,用户会感到烦恼.几年后他们会更加恼火,当他们看到任务管理器时,他们看到大约3%的花哨的新32核机器正在被使用.
是的,我也一直用线程编程.但是,我并没有足够的自虐来爱他们.无论你是多么超级男人,加上你从同事那里得到的任何帮助,在线程之间进行交谈仍然太容易了.线程很容易做,但很难做到正确,所以当然Joe-Schmoe很喜欢它,而且,它们很快!(当然这一切都很重要)
在*nix上,好的旧fork()仍然是很好的方法.开销并不算太糟糕(是的,我需要在某天测量它来备份我的BS),特别是如果你要求翻译,然后在子进程中生成一堆任务特定数据.
也就是说,据我所知,在Windoze上,儿童流程非常昂贵.所以Erlang方法看起来非常好:迫使Joe Schmoe编写纯函数并使用消息传递而不是他看似无限状态的自动机全局(实例)变量whack-fest与奖励线程串扰盛会.
但我不痛苦:-)
修订/评论:
关于距离记忆的其他地方的优秀评论.最近我也一直在考虑这个问题.标记和清除垃圾收集确实会损害运行进程的"局部性"方面.旧的80286上的M/S GC on 0等待状态RAM似乎无害,但它在多级缓存架构上确实很痛.在某些情况下,引用count + fork/exit可能不像GC实现那么糟糕吗?
编辑:我付出了一些努力来支持我的演讲(结果各不相同):http: //roboprogs.com/devel/2009.04.html