justep 2010-03-28
随着我们向众核(many-core)处理器时代的迈进,对并行方法的有效使用已成为提升应用性能的关键。为了与新一代编码人员分享宝贵的专业知识,来自英特尔并行编程领域的三位资深工程师将向大家传授他们的亲身经验。
发掘并行性的核心
传统编程常陷于其顺序序列中,而对于并行编程人员而言,这一点必须改变。在串行代码开发中,程序控制有一个清晰的流程。编码人员知道数据被访问和更改的方式,并了解其中的依赖关系。对此,英特尔软件与服务事业部首席工程师HenryGabb谈到:“在并行开发中这些完全被抛之脑后,你现在需要考虑一个临时组件。你必须思考如何同时执行多个指令,以及这些指令会对你的数据结构、变量、算法及其它一切产生什么影响。
同样,英特尔微处理器技术实验室首席工程师TimMattson也表示:“在并行开发中,有多个状态会同时发生和改变。依赖关系也会发生变化。你必须清楚地掌握这些情况。在Tim看来,这一方面正是“在理解并行程序的过程中你必须经历的改变的核心。”
Henry的建议是,改变你的模式。他说:“需要考虑的关键问题是数据访问,你必须高度注意避免发生数据损坏的情况。线程执行和访问数据的时间没有确定的顺序。操作系统负责对线程进行调度,而它对于数据访问模式一无所知。并行程序中唯一的顺序是程序员利用同步方法明确创建的。”
对此,英特尔®课程设计师ClayBreshears补充说:“我认为首先用共享内存并行编程来挑战分布式内存应用并不是一个大的进步。如果你有一条线程,你可以考虑添加另一条线程来分享一些内容,这相当于两名工人分担一项工作,这并不算是一种进步。”
并行化处理
选择合适的代码进行并行处理对编程人员来说可能是一个挑战。就Clay而言,做出决定有时候非常简单:“通常在遇到新项目时,我的经理就说‘并行化处理’。当然,实际工作就不像说起来那么简单了。”
那么什么时候值得我们付出精力对程序进行并行化处理呢?Henry会首先考虑阿姆达尔定律和客户的要求。他表示:“如果我觉得我能达到理论增速值,且对于客户来说已经足够的话,(我就会考虑并行化处理)随后我会考虑负载平衡问题。并行工作在多条线程中能在多大程度上得到平均分配呢?如果负载平衡比较合理,接下来我会考虑粒度。每条线程是否分配有足够的工作来证明线程创建成本并没有浪费?任何此类测试都可以淘汰不合格的项目。如果顺利通过所有测试,那么它就可以得到并行化处理。”
依靠在科学计算领域积累了多年的经验,Tim指出:“通常,对于我研究的问题,我能确定程序正在进行的操作、并发的位置以及代码的计算密集型部分的位置。如果不能对这些部分进行并行化处理,那么就没有必要继续下去。”
用于完成3D叠前深度偏移的算法就是一个很好的例子。Tim说:“我知道会有一个快速傅立叶变换(FFT),也了解FFT的数学原理。我还知道数据在加载和处理记录集时的结构。因此,我可以推断出在哪个位置需要对代码进行并行处理。”
如果是不熟悉的应用,你仍然需要了解你尝试进行并行化处理的算法。Clay说:“你需要在他人的引导下了解一下并行化处理。了解之后,你就可以独立操作并知道在哪儿进行并行化处理。”
发掘独特的编程方法
独立程序员在并行编程时通常会独辟蹊径。例如,Henry常常会借助英特尔®线程工具,Tim则不常使用这些工具(除英特尔®线程检查器外)。
Clay也有自己独特的方法。他说:“我认为,在共享内存模式下进行并行化处理时,就可以共享的人员和工作而言,如果我说‘这里有一些东西和一些任务’,我可以设想会有两个人来分担这项工作,然后我可以带着算法走上前去解决问题。如果我可以把它看成是两个人的工作,那么我就也可以把它看成是4个、8个、16个或32个人的工作。”
在对代码进行线程处理并确保其正常运行后,Clay通常会集中精力主要使用英特尔®线程分析器和英特尔®集群工具对代码进行优化。
识别并行模式
Tim指出:“最重要的是要牢牢记住所有并发线程,这样,程序员才能够创建更简单更有约束性的结构来限制并发情况。这些结构将成为利用并发优势的循环并行模式。”这一主题在Tim的专著《并行编程模式》中有详述。
“最重要的是要牢牢记住所有并发线程,这样,程序员才能够创建更简单更有约束性的结构来限制并发情况。”
英特尔微处理器技术实验室首席工程师TimMattson
Tim说:“久而久之,程序员已在脑中建立了一个解决方案目录。在计算机科学中我们称之为模式。专家级程序员在不断研究问题的过程中会获得足够的信息来使某种模式匹配问题的某个部分。并行编程新手和专家的区别就在于专家的脑子里有一个更大更丰富的模式目录。”
专家级并行编程人员首先会将问题分解,找到并揭示出并发性,然后开始标记并发情况。新手程序员通常会跳过最初几步,但最后常常不得不加班加点或得不到正常运行的代码。对此,Henry表示:“在引入线程之前,我通常会做大量基础工作。有的工程师会先得到代码,对其进行分析然后开始线程处理,丝毫不考虑一些基本的算法,这样的例子我见过很多。如果你这样做并且得到了一个可扩充的并行代码,那只能说是运气好。”
绕开编程陷阱
新手并行编程人员面临着大量陷阱。其中之一正如Henry所说,就是“程序员花费大量时间优化的串行算法可能不是最佳的并行算法。”
Tim认为缺乏经验,即他所谓的“湿件”(理解问题并揭示并发性的脑力劳动)也是一项重要挑战。他说:“有大量知识需要我们花时间去学习和应用,程序员需要自如地运用基本的术语和算法,了解各种模式,战胜挑战。标记工作相对简单,比较困难的是理解并行算法。”他建议可以阅读他的专著,熟悉并行模式并学习如何有效利用这些模式。
Henry表示:“我建议从熟悉openmp*规范开始。该规范内容不是很长,但抓住了并行计算的所有相关问题,还举出了大量例子。”Clay也认为openmp是一个最好的起点。然而,无论从哪里开始,新手并行编程人员都需要积极地利用学到的技能解决各种并发问题,以识别各种模式——并行性正是通过这些模式带来业绩或效率盈利。
掌握这门艺术
在并行编程领域,通向成功的最佳路径是什么?Clay称:“编程是一门艺术。并行编程则是另一门艺术。您需要学习工具的用法,但最终需要回到实践,凭着直觉独立完成工作。”
Henry断言:“如果不考虑应用没有人会学习并行编程。你可以博览群书,但如果不应用到实践中,你就不能真正地学到东西。”
三位资深工程师一致认为:掌握并行编程这门艺术的最佳途径就是实践。
三位英特尔工程师简介
HenryGabb是英特尔软件与服务事业部首席工程师。他已在并行应用领域工作了15年之久。Henry拥有路易斯安那州立大学生物化学学士学位和美国阿拉巴马大学伯明翰分校医学院分子遗传学博士学位。
Claybreshears现任英特尔®软件学院的课程设计师,专门致力于多核与多线程的编程与培训。他拥有位于诺克斯维尔的田纳西大学的计算机科学专业博士学位(1996年),在并行计算和编程领域已工作了20余年。
TimothyMattson是英特尔微处理器技术实验室首席工程师。早在1985年在加州理工学院攻读博士后期间他就开始编写并行软件,同时参与了CosmicCube(第一批超立方体并行计算机之一)的研究工作。此后,他利用并行计算机解决了大量科学难题。