主 题: 摩尔定律的末日-软硬件性能提升的历史和未来 [加为收藏] 第 1 篇 - 第 7 篇 共 7 篇 返回 作者:imissunow 时间: 2006.08.30 13:03 :0 朵 :0 个 免费大餐不久就将结束。对此,你有何打算,做好下一步准备了么? 对主要的处理器厂商以及架构,包括Intel、AMD和Sparc、PowerPC[译注1]来说,改善CPU性能的传统方法, 如提升时钟速度和指令吞吐量,基本已走到尽头,现在开始向超线程和多核架构靠拢。而且这两个特性(特别 是多核)已经在部分芯片实现,如PowerPC和Sparc IV;Intel和AMD也将在2005年内赶上。2004年In- Stat/MDR秋季处理器论坛[译注2]的主题就是多核设备,很多公司都展示了改进和新研发的多核处理器。不 过,要将2004年称为多核年,显然还不够理直气壮。 多核将引领软件研发发生基础性变化,特别对接下来几年里那些面向一般应用、运行在PC和低端服务器上的应 用软件(在今天已经销售出去的软件里占有很大比例)而言。在这篇文章里,我想就多核为何突然对软件产生 重要影响,以及并发巨变如何影响我们和我们未来编写软件方式的问题展开讨论。 我可以这么说:免费大餐已经结束一两年了,但我们现在才开始意识到这个问题。 免费的性能大餐 业界存在一个有趣的现象:“安迪送,比尔取。”[译注3]无论处理器性能提升多少,软件都有办法迅速吞 噬。CPU速度十倍于前,软件就有十倍于前的活要干(或者肆无忌惮猛增软件的工作量,导致性能下降)。在 过去几十年里,由于CPU、内存和硬盘特别是CPU厂商强力推进主流系统向更新更快的方向发展,大多数软件不 做版本升级,甚至原封不动,就可轻松而持续地享受处理器性能提升的成果。尽管时钟速度不是衡量系统性能 的唯一和最好的标尺,但其重要意义不容忽视。我们见证了CPU的发展历史:从500MHz到1GHz,然后再到 2GHz,不断提高。今天,主流计算机已经进入3GHz时代。 不过,有一个很关键的问题:这种提升模式什么时候会走到尽头?尽管莫尔定律预言了历史上的指数式增长, 但我们很清楚指数式增长不可能永远维持,因为硬件毕竟受物理极限约束;光速是不可能更快的[译注4]。所 以增长必然放缓,最后停滞。顺便说明一点,莫尔定律的主要描述对象是晶体管集成密度,但在一些相关的领 域,如时钟速度方面,也出现了类似的指数式增长;甚至在别的领域有更快的增长速度,例如著名的数据存储 量爆炸。不过这些重要趋势需要另一篇文章来分析了。 如果你是一个软件开发人员,那么你可能一直在免费享受桌面计算机性能提升的大餐。某些操作会成为应用程 序性能的瓶颈?“你过虑了”,我们对这样的回答耳熟能详,“未来处理器将更为强劲,而现在的应用程序速 度倒是日益被非CPU吞吐量和内存速度因素扼杀,比如I/O、网络和数据库等等。”真的是这样么? 要在过去,这的确没错。但在以后,就完全不对了。 我有两个消息要告诉大家。第一个是好消息,处理器性能仍然会不断提高。第二个则是坏消息,至少在短时间 内,处理器性能的提升,不再能像以往那样让现在的应用程序继续免费获益。 过去30年里,CPU设计者主要从三个方面提高CPU性能,头两个就是从线性执行流程上考虑的: 1、时钟速度 2、执行优化 3、缓存 提升时钟速度将增大单位时间的时钟周期数。让CPU跑得更快,就意味着能让同样工作或多或少更快完成。 优化指令执行,可以在每个时钟周期内完成更多工作。目前的CPU中,一些指令被不同程度地做了优化,如管 线、分支预测、同一时钟周期内执行更多指令,甚至指令流再排序支持乱序执行等[译注5]。引入这些技术的 目的是让指令流更好、更快执行,降低延迟时间,挖掘每一时钟周期内芯片的工作潜能。 在这里,有必要对指令再排序作个简单说明。我刚才提到的部分指令优化手段,其实已远非普通意义上的优 化。这些优化可能改变程序原意,造成程序不响应程序员的正常要求。这可是个大问题。CUP设计师都是心智 健全且经过严格训练的好同志,正常情况下,他们连苍蝇都不愿伤害,自然也无意破坏你的程序。而在最近几 年里,尽管知道指令重组有破坏程序语义的风险,但为了提升每个时钟周期内的工作效率,他们已经习惯于积 极开展这类有风险的优化工作。难道海德先生[译注6]复活了?当然不是。这种积极性清楚表明,芯片设计师 承受了交付速度更快CPU的巨大压力;在这种压力下,为了让软件跑得更快,他们不得不冒改变程序意思,甚 至应用崩溃的风险。拿两个有名的例子来说——写操作再排序和读操作再排序[译注7]。允许处理器对写操作 再排序是非常令人吃惊的,让大多数程序员意外,一般来说这个特性必须关闭,因为在写操作被处理器武断地 再排序条件下,程序员很难保证程序正确执行。读操作再排序也有明显的问题,但大多数情况下这个特性是开 启的;因为相对来说它更容易把握一些,而且人们对性能的要求,让操作系统和操作环境设计师只能选择让程 序员在一定程度吃点苦头,毕竟,这比直接放弃性能优化机会的罪责小一些。 第三个是增大与RAM分离的片内高速缓存。RAM一直比CPU慢很多,因此让数据近可能靠近处理器就很重要—— 当然那就是片内了[译注8]。片内缓存持续飚升了很多年,现在的主流芯片商出售的CPU都带有2M甚至更高的二 级缓存。值得一提的是,今后,三种提升CPU性能的传统手段里,增加缓存将硕果仅存。我会在后面更详细说 明缓存的重要性。 我写这么多的意思是什么呢? 最重要的是我们必须认识到,传统性能提升方法与并发没有直接关系。过去任何方法带来的速度提升,无论是 顺序(非并行的单线程或单进程)、还是并发执行的程序,都能直接受益。这点很重要,我们目前大量的程序 都是单线程的,而且在未来仍然有重要的存在价值。 当然,适当时候,我们重新编译程序,可以利用CPU的新指令(如MMX、SSE[译注9])和新特性提升系统性能。 但总的来说,即使放弃使用新指令和新特性,不做任何更改,老程序在新CPU也会跑得更快,让人心花怒放。 曾经的世界是这般美好,可如今,她就要变了颜色。 为什么我们今天没有10GHz芯片 其实,CPU性能提升在两年前就开始碰壁,但大多数人到了最近才有所觉察。 我这里有份来自Intel的数据(当然你可以从其他厂商得到类似数据): 图中反映了Intel芯片的时钟速度和晶体管集成规模演变历史。晶体管集成数至少就目前而言仍在继续上升, 但时钟速度的情况就不同了。我们从图中可以看到,大概在2003年初,一路高歌猛进的CPU时钟速度突然急刹 车。受制于一些物理学问题,如散热(发热量太大且难以驱散)、功耗(太高)以及泄漏问题[译注10]等,时 钟速度的提升已经越来越难。 你目前在工作站上用的CPU时钟速度是多少?10GHz么? 2001年8月Intel芯片就达到2GHz,按照2003年前的 CPU发展趋势推算,到2005年初,我们就能拥有第一块10GHz的Pentium芯片。但实际上没办到。而且情况好像 越来越糟——我们根本就不知道到底在什么时候这样的芯片可以出现。 那么放低期望,4GHz又如何呢?目前我们已到3.4GHz——那么4GHz已经不远了吧?唉,好像4GHz也遥不可 及。可能你知道,Intel首先于2004年中将4GHz芯片的发布时间推迟到2005年,而到了2004年秋季,则彻底取 消了4GHz计划[译注11]。在本文写作的同时,Intel宣布计划到2005年早期,实现到3.73GHz(即图中的右上 最高处)的微量提升。所以,至少就目前来说,时钟速度的竞赛实际上结束了,Intel和其他大多数处理器厂 商将把旺盛的精力投入到多核等方向去。 也许,我们某天在主流PC里能装上4Ghz的CPU,但2005年别想。Intel实验室里的确已经有运行在更高速度的 芯片——不过代价是惊人的,比如庞大数量的冷却装置。你想不久在你的办公室里就有这样的冷却设备,坐飞 机的时候,就把它们放在你膝盖上?别做梦了! 莫尔定律与新一代处理器 “没有免费的午餐。”——摘自R. A. Heinlein的小说《The Moon Is a Harsh Mistress》 莫尔定律玩完了?这个问题很有趣,严格地讲,还不能这么说。尽管和所有的指数式增长方式一样,莫尔定律 总有一天会走到尽头,但最近这些年,还没有这样的危险。芯片工程师在榨取时钟周期内剩余价值时的确碰了 壁,不过晶体管集成量仍在暴涨,所以从这个角度说,CPU近期仍将遵循莫尔定律,系统吞吐量继续提高。 关键的变化,即本文的中心,是今后几代处理器性能提升所走的道路将完全不同。同时,大多数现在的应用软 件将不再可能不作大规模重构,就能像过去那样从处理器免费获益。 接下来数年里,新型芯片的性能提升将主要从三个方面入手,其中仅有一个沿袭是过去的: 1、超线程 2、多核 3、缓存 超线程,是指在单个CPU内,并行两个或多个线程。超线程CPU已经发布了,支持并行执行一些指令。不过这种 CPU还是存在短板,虽然给它增加了部分硬件如寄存器,但它和绝大多数普通CPU一样,但缓存、整数和浮点运 算器仍然是唯一的。有资料表明,写得较好的多线程应用,在超线程CPU上能获得5%-15%的性能提升;假设趋 于理想状态,即多线程程序写得好到极点,那么性能可以提高40%。不错了,不过还是做不到成倍提升,而且 对单线程应用毫无帮助。 多核,主要是指在一块芯片上运行两个或多个处理器。部分芯片如Sparc和PowerPC目前已经推出了多核版本。 Intel和AMD也计划在2005年内初步实现,具体时间取决于它们的系统集成水平,功能则是一样的。AMD初期在 性能设计可能更具优势,如更好的支持功能同片内集成,而Intel基本上就打算将两颗Xeon胶合在一块芯片上 了事。所以刚开始的时候,这种双核芯片与一个真正的双CPU系统在性能几乎没有差别,仅仅在价格上前者更 为便宜,毕竟它的主板上不需要两个插槽和额外胶合件;另外,即便理想状态,这种架构也无法达到双倍速 度,且无益于单线程应用,而只有写得较好的多线程应用能得到好处。 最后一个是片内缓存,还能像预期那样在近期继续上升。三个方法中,仅有这个可以让现有应用全面受益。片 内缓存有令人难以置信的重要性和对大多数现有应用的超高价值,原因很简单,那就是空间就是速度。CPU和 主存交互的代价是巨大的,如果能避免,那就尽量不要和它打交道。在目前的系统里,从主存获取数据所花时 间,通常是从缓存获得数据的10到50倍。很让人吃惊吧,因为很多人都以为内存已经足够快。其实这不过是与 硬盘和网络相比,而不是运行在更高速度的片内缓存。应用程序的工作与缓存间的适配程度,和我们是荣辱与 共的。很多年来,不重构程序,仅仅提高缓存大小就拯救了现有应用,给它们带来新生。软件操纵的数据和为 新增功能而加入的代码越来越多,性能敏感的操作必须继续与缓存适配。套用经济大萧条时期老人常念叨的一 句话:“缓存为王。” 顺带说件发生在我的编译器小组的趣事,算是“空间就是速度”的一个佐证。32位和64位编译器将同样的代码 分别编译成32位和64位程序。64位CPU有多得多的寄存器和其他代码优化特性,因此运行其上的64位编译器先 天的获得极大性能提升。这当然很好。而数据的情况又如何呢?换到64位平台上,内存中绝大部分数据的大小 并未发生变化,唯一例外的就是指针,指针占用了两倍于以前的空间。因此,我们的编译器和绝大多数32位应 用相比,挥舞指针就费力得多。现在的指针耗用8个而不是4个字节,空间净增加,结果我们发现64位编译器的 工作集[译注12]大小显著增加。工作集增大导致性能下降,差不多抵消了更快的CPU和更多寄存器带来的性能 优势。就在我写这篇文章的时候,64和32位编译器正以同样的速度运行,尽管程序代码完全一样而且64位处理 器先天能力更强。这就是“空间就是速度”。 缓存能,但超线程和多核CPU对现在的绝大多数应用,几乎不会有任何影响。 综上所述,硬件的变化到底会给软件开发方式带来怎样的影响呢?你可能已经有了初步答案了。让我们更深入 研究,明白其厉害所在。 对软件来说,这意味一次巨变 上世纪90年代初,我们开始学着理解对象。在主流软件开发领域里,从结构化到面向对象编程是过去20甚至可 以说30年来最重要的变革。这期间也发生了其他一些变化,例如近来诞生的的确让人着迷的WebServices,但 我们中绝大多数人在职业生涯里从未有过见识像面向对象那样基础而深刻改变软件开发方式的机会。 现在,机会来了。 也从现在开始,性能大餐就不再免费了。虽然托缓存增大的福,我们还能在半路上捡到普通的应用性能提升 丸,但如果你希望你的应用程序在新的处理器里能继续获得爆炸性的性能提升,那就需要你好好编写并发程序 了(通常是多线程的)。说比做容易啊,也不是所有问题都天生可以通过并行解决,而且并发编程的难度也是 很大的。 肯定有人嚷嚷开了:“并发?并不是什么新鲜玩意嘛!人们不就已经在写这样的程序了么。”是的,小部分程 序员的确写过。 别忘了,至少从上世纪60年代晚期的Simula开始,人们就在写面向对象程序。但到了90年代,面向对象才成功 发动革命并夺取统治地位。为什么呢?工业是受现实需求驱动的,为了解决越来越大的问题,必须编写越来越 大的系统,这样的系统也需要越来越强劲的CPU和存储设备支持,正好硬件系统也逐步提供了这样的支持。面 向对象编程擅长抽象和依赖管理,所以成为了开发经济、可靠和可重用的大型软件的必备利器。 并发编程差不多也有同样漫长的历史可以追溯,很早的时候,我们就开始编写协程、管程[译注13]以及其他与 并发相关的东西。近10年来,我们也发现有越来越多的程序员在编写并发应用(有多线程的,也有多进程的) 系统。但是发生整体转向性的巨变,目前还不具备条件,需假以时日。现有大量的单线程应用,仍然有巨大的 存在价值,这点我会在后面说明。 说点题外话,当前“下一次软件开发革命”这样的词语多如牛毛,总让大家眼花缭乱,其实这是商家宣传自己 新技术所作的广告,不要理睬它。新技术通常都很吸引人,有时候也很有用,但软件开发方式的重大变革必然 来源于在真正得到爆发式广泛应用前就存在并经过多年缓慢成长、先进而稳定的技术。这个过程是绕不掉的。 变革所依赖的基础技术必须足够成熟(包括有固定的厂商和工具支持);通常,这个成熟稳定过程至少要花费 7年的时间,新技术在广泛应用时才不会有潜在的性能悬崖和陷阱。所以,像面向对象这样的软件开发变革, 也必须在各项技术经过多年甚至几十年磨砺后才能发生。即便在好莱坞,绝大多数的一夜成名,也仍然是多年 努力后发生重大突破的表面象征。 并发将是软件开发史上的又一个重大变革。很多专家仍然在这个变革是否比面向对象还大的问题上争论不休。 这样的争论最好还是留给学问家吧。技术工作者最感兴趣的是和面向对象一样,编程方式的变化程度、编程技 术的复杂性和学习曲线问题。 并发之正反二面 并发技术(特别是多线程)在主流软件里大多应用在两个方面。第一类是天然就彼此独立的、逻辑上分离的控 制流程,比如在我设计的数据库复制服务器里,每个复制Session都放在各自的线程里,彼此完全独立的,不 会工作于同一条数据记录上。第二类不像第一类那么常见。为了系统提升性能,像利用多CPU平台的能力,挖 掘应用程序其他部分的潜能等,我们也会编写并发代码。在我的数据库复制服务器里,多个独立的线程在多 CPU平台上就工作得很好。 然而,并发编程也是要付出代价的。一些很明显的问题相对来说无关紧要,比如锁定。对资源的锁定降低了系 统的性能,但如果你能找到办法最小化甚至消除资源共享,让操作真正并行,从而明智得当地使用锁,那么从 并发执行得到的收益,要远大于在同步上蒙受的损失。 更重要的问题,大概就是并非所有应用都适用并行。这点我会在后面说明。 应该说,最大的问题,就是并发编程本身的难度了。程序员必须将脑子里的编程模型转化为可靠的程序,这比 实现顺序执行的传统程序难得多。 任何学习过并发的人都认为自己已经理解并发,早早结束寻找他们认为不可能但实际潜在的竞争冲突和他们其 实仍没闹明白的问题。如果开发人员认真学习和思考并发编程,就会发现通过合理组织的内部测试能发现大多 数的竞争冲突问题,这个时候,无论是在知识水平还是心情愉悦度上,他们都能达到一个新的高度。不过,除 了经过理解为什么和怎么进行真正压力测试的行家测试过的、已经正式发布的软件,都会存在部分在普通测试 中无法捕获的潜伏并发问题。这些问题只有在真正的多处理器系统上才会暴露出来,因为在这样的环境里,多 个线程不是在单处理器上切换,而是真正的并发运行,大量新问题就会涌现。而偏偏又有很多人自以为已经真 正理解如何编写并发程序,真是让人忐忑不安啊。我见过不少项目组,他们的程序在很多用户那里即便施以极 端苛刻的压力测试,都能出色工作,但某天一个用户部署了真正的多处理器机器后,深层次的竞争冲突甚至程 序崩溃问题马上出现。CPU发展到今天,重构你的应用,让它们多线程运行在真正的多核计算机上,的确像逼 迫初学游泳的人一下子跳入深水——直达终点,似乎有点残忍,但只有真正并行的环境,才非常容易暴露出你 的问题。而且,即使你组织了一个能真正编写可靠并行代码的团队,也不能说就不会出现问题。例如,并发代 码运行可能非常安全,但(在多核的机子上)却不比在单核的机子上跑得快。其典型原因就是线程未被合理分 离,共享了单一资源,造成程序执行顺序化。这类问题是相当微妙而复杂的。 结构化程序员学习面向对象(什么是对象?什么是虚函数?我如何使用继承?知道“是什么”和“怎么办” 外,还得问一句“如何保证理论上正确的设计在实践中的正确性”)是一个飞跃,同样的,顺序思维的程序员 学习并发(什么是竞争冲突?什么是死锁?它是怎么出现的,我如何避免它?什么样的构造在我看来是并行的 但实际上顺序化了程序?在“是什么”和“怎么办”外,还要回答同样的问题“如何保证理论上正确的设计在 实践中的正确性”)也是一个飞跃。 现在的大量程序员并没有真正理解并发,就像15年前大量程序员没有真正理解对象一样。但并发编程模式是可 以学习的,尤其是我们要坚持基于消息和锁的编程;一旦真正理解了并发,就会发现它并不比面向对象难多 少,很容易觉得那是自然而然的。我们需要为我们自己和我们的团队做好训练投资和时间的准备。 有必要说明一点,我在上面故意将并发编程模式限定在消息和锁基础上。其实也有在语言级就直接支持的无锁 编程,比如Java5和很流行的C++编译器。但对于程序员来说,无锁比有锁并发编程难得多。大多数情况下,只 需要系统和库编写者理解无锁编程就行了,虽然事实上每个人都可以从无锁系统和库获益。老实说,即便有锁 编程,也有点碰运气的味道呢。 对我们来说这到底意味着什么 好了,回到正题,将问题归纳一下。 1、我们已经讨论清楚的、最重要结论是:如果应用程序想充分利用CPU吞吐增加量,那它们就必然日益需要并 发,这种形势逐渐明朗,并将在接下来的数年里深入发展。Intel已经扬言未来他们会推出集成100颗内核的芯 片,那么单线程应用最多就只能利用这种芯片1/100的潜在生产力。“哦,性能没那么重要吧,计算机总是跑 得越来越快”的论调已经变得天真而可疑,甚至在未来不久将完全错误。 目前,并不是所有的应用都需要(或者更准确的说,只有应用中重要的作业才需要)并行。像编译这类的问 题,是必须要考虑并行的,而其他则不一定。请看这个有趣的例子:一个女人需要九个月才能生产一个小孩, 并不代表九个女人能花一个月生出一个孩子。你以前可能接触过类似的推导,但又没感觉这个问题意犹未尽 呢?如果有人再和你就此讨论,我向你推荐一个刁钻的问题:从这个命题你能断定“女人-小孩”是一个非并 行问题么?通常,人们会下意识地认为它天然就不是一个并行问题,但实际上并不完全是这样。如果目的是生 一个小孩,它的确是一个非并行问题;但如果是生产多个小孩,那么它就是一个标准的并行问题了!所以说, 目标不同,结论就大相径庭。在考虑你的软件是否和如何使用并行时,千万别忘了面向目标原则。 2、可能不那么明显的结论是:CPU将很可能日益成为应用程序性能的瓶颈。当然,不是所有应用都会这样,那 么目前还未明显受制于CPU能力的应用在未来虽然可能受到CPU影响,CPU也不会一夜之间成为它们的镣铐。但 “I/O、网络和数据库瓶颈”似乎快走到谷底,因为在这些领域,条件仍然在迅速得到改善(如GB硬盘、WiFi 网络等等);而与此形成对比的是,CPU性能提升技术已走到峰点。请注意,我们的CPU目前在3GHz徘徊。所 以,除了指望缓存在未来继续扩大(这可真是一个大好消息),现在的单线程应用不太可能跑得更快。其他方 面的性能提升手段,虽然未来还可能继续发挥作用,不过已经无法和过去相提并论了。芯片设计师正在拼命寻 找新办法提高管线利用率,降低数据加载延迟,但在这些领域,长在低枝的果子早已被摘光。而应用程序新需 求的增加不但不稍事休息,反而神经质地加速猛冲。我们只好逼迫程序做更多的事情,而程序则只有威逼 CPU,压垮它,除非程序能并发执行。 应对如此巨变,我们现在有两条路可以走。一是面向并发重构应用,二是勤俭持家,小心规划代码,让它吃更 少的食,干更多的活。这就引出了第三个有趣的话题。 3、提升程序效率、优化其性能将越来越重要,而不是相反。已经高度重视性能优化的语言将获得新生,其他 的语言赶紧奋起直追,朝着效率和优化努力吧。面对长期增长的需求,希望面向性能努力的语言和系统能为我 们分忧。 4、最后一点,编程语言和系统将不得不尽快做好面向并发的准备。Java语言从一开始就支持并发编程,虽然 还存在不少问题以致不得不发布多个后续版本提升并发程序的正确性和效率。C++长期以来被用于编写大型多 线程系统,但它却没有对并发的标准支持(ISO C++标准甚至有意未提及线程[译注14] ),因此,并发目前只 能在一些不可移植的特定平台和库基础上实现(而且实现还不够完善,比如静态变量只能初始化一次,这就要 求编译器自动加锁,但很多C++的实现里并不生成锁)。另外,目前存在多种并行编程标准,比如pthreads和 OpenMP[译注15] ,其中一些支持隐式并行,另一些显式支持。让编译器分析单线程程序并自动生成并行代码 的隐式并行方式当然美妙而优雅,不过这类自动转化工具的结果代码质量还无法与人工编写的显式并行代码媲 美。目前的并发编程主要以锁为基础,这种方式也很难把握,常常要赌几分运气。总之,我们迫切需要一个比 目前语言提供的更高抽象层次的、统一的并发编程模式。关于这点,以后我还有更多的话要说。 总结 如果你以前对并发未加注意,那么现在是时候了,仔细分析应用的设计,挑出现在和不久就可能过于依赖CPU 能力的操作,研究这些部分如何从并发得益。你和你的团队,现在也该深入学习和了解并发编程的要求、不 足、风格和专业概念了。 少部分应用天然适用于并行,但大多数不是的。即便你知道程序受制于CPU的位置,可能也很难找到将这部分 操作并行化的办法。所有这些问题,要求我们赶紧对并行多加思考和研究。隐式并行编译器能帮点小忙,但不 能指望太多,它不可能比得上尽你所能将顺序化程序转化为显式并行和多线程版本后的效果的。 感谢仍未停止的缓存扩大和管线少量优化,免费饭菜在今后还能有一点,不过从今天开始,餐馆无偿提供的只 有小菜和饭后小点心了。菜谱上仍然有优质可口的鱼片,但现在要享受它就得付费——设计精细化、代码更复 杂,而且要加倍测试。对于多数应用来说,这是个好消息,尽管要辛勤耕耘,但回报是丰厚的,因为并发可以 让应用继续从处理器能力暴增中充分受益。 译注1 处理器发展历史上,精简指令集(RISC,Reduced Instruction Set Computer)阵营曾向微特尔 (Wintel,Microsoft+Intel)阵营发动过三波声势浩大的微电脑盟主争霸战。 上世纪70年代以来,对处理器的要求更为全面,不单是提升速度就能满足,比如低耗能、小体积,加强数值运 算、支持多媒体功能等。复杂指令集(CISC,Complex Reduced Instruction Set Computer)的微指令多 且长度不统一,造成解码器线路复杂;加上受当时制造工艺的限制,如果在芯片上直接集成高速缓存和其他部 件,体积和价格都将变得难以想象。 RISC应运而生。因为RISC指令精简、线路精简,所以芯片体积和能耗降低,腾出空间也可容纳更多寄存器;另 外指令定长,通过硬件加速,还可提升效能。RISC学术界从一开始就分为两派:Berkeley RISC(伯克利大学 RISC计划)和Stanford MIPS(斯坦福大学MIPS计划。MIPS,Microprocessor without Interlocked Pipeline Stages,无内部互锁流水级的微处理器。我国龙芯即MIPS架构)。 Sun公司引进了RISC技术,在此基础上制定了Sparc(Scalable Processor Architecture,可扩展处理器体 系结构)微处理器体系结构规范,并于1985年推出了相应处理器。1988年,Sun领头组建了Sparc联盟,口号 是“RISC + UNIX vs CISC + DOS”,藉此发动第一次争霸冲击。后因市场迟迟未见销量,加上Sun在技术上 又留了一手,导致联盟最后只剩Sun自己和德州仪器。 1990年,MIPS研究开花结果,开发团队成立了同名公司MIPS,并于1991年建立了ACE(Advanced Computing Environment)联盟,主要成员有Digital(迪吉多)、SGI(Silicon Graphics,视算科技)和Compaq(康 柏)。Compaq当时市场低迷,且Intel对Compaq展开了游说,因此Compaq最先退出了联盟;而Digital又忙于 Alpha芯片的开发。主要成员离心离德,1992年,第二次联盟以SGI收购MIPS草草收场。 IBM从1975年开始精简指令集芯片研究,也就是后来的PowerPC。1992年,IBM与Motorola(摩托罗拉)、 Apple Computer(苹果)宣布合组Power联盟。刚开始,Power联盟引用学界评比论文,直指x86复杂指令 集结构无法应付未来信息需求,而媒体也纷纷发难斥责x86电脑效能低劣,操作介面不便,都表示支持大胆 改革的Power联盟。形势危机,当时Intel的总裁葛洛夫甚至认为Intel已陷入死亡之谷,如果应对失措, “Intel”将成为历史名词。Power联盟洋洋得意。 但在接下来的三年里,Power联盟迟迟不能统一平台标准,操作系统开发进度也严重滞后。到1994年,Intel 推出了Pentium芯片,微软的Windows 95也大功告成。尽管当时的Pentium逊于PowerPC,Windows 95界面也 不如Macintosh,但前二者相互支援,前后兼容,不断改进,而后二者却不够统一,用户没有安全感。形势急 转直下,Power联盟大跌眼镜。 第一波攻击,Sun退回到工作站;第二波攻击,SGI退回绘图工作站;第三波攻击至今,IBM还在服务端处理器 领域靠PowerPC苦撑。 顺带说一句,Intel和AMD主要走的都是CISC路线。但处理器发展到现在,各方面技术已经相互融合,不存在绝 对CISC或者RISC的芯片了。 译注2 In-Stat:www.instat.com,全球著名的行业研究机构,Reed Business Information出版集团成员公司之 一,Reed Elsevier的战略组成部分;涉及半导体、电信和电子消费品等领域的研究、评估与预测。 MDR:MicroDesign Resources,原属美国Ziff-Davis电子出版集团,1999年被Reed Elsevier收购。 In-Stat/MDR主办《Microprocessor Report》(《微处理器报告》)杂志,三周刊;Microprocessor Forum(微处理器论坛)每年10月在加利福尼亚州San Jose举行。 译注3 原句为:Andy giveth, and Bill taketh away. Andy:Andy Grove,安迪·格鲁夫,1968年和罗伯特·诺宜斯(Robert Noyce)、戈登·摩尔(Gordon Moore)共同创立Intel。 Bill:Bill Gates,比尔·盖茨,1975年和保罗·艾伦(Paul Allen)创立Microsoft。 译注4 大概是2001年看到过一则新闻,到网上搜了一下,内容大致如下: 澳大利亚教授韦伯领导的研究小组利用位于夏威夷的世界最大的天文望远镜“凯克”观测17颗不同的类星体。 由于这些类星体距离地球120亿光年,它们在宇宙形成初期发出的光线到今天才抵达地球。在长途旅行中,部 分光线被星系间的气云吸收。光线的吸收情况既能反映星系气云的性质,也能反映出光的变化情况,这其中就 包括光的速度以及决定光速的光谱线精细结构常数。结果,韦伯等人发现,精细结构常数发生了微小的变化。 从理论上说,这意味着光速有可能发生过改变。消息公布后,不少物理学家对此发现持谨慎态度。韦伯及同事 希望用位于智利的另一个大型天文望远镜来证实他们的结果,据称要得出最终结论尚需2至3年的时间。 不过到目前为止,似乎还没看到他们的最终结论。 译注5 管线:pipelining,或流水线。CPU的管线并不是数据输入输出使用的物理线路,而是指指令执行的流程。一 条指令必须被分解为多个执行步骤,每个步骤占用一个时钟周期。例如最基础的管线是5级的:(1)取指令, (2)对指令译码,(3)演算出操作数,(4)执行指令,(5)将结果存储到高速缓存。前三步由指令控制器 (ICU)完成,后两步由运算器(ALU或FPU)完成。管线可以细化,例如苹果的G4处理器采用了7级管线, AMD 2500+处理器10级,Intel公司的P3到10级,P4到20级,P4-E甚至高达31级。管线加长,则每级任务量减 小,执行所需时间缩短,因此时钟周期可以缩短,即时钟速度加快。设管线为N级,时钟速度为TMIPS(T百万 次/秒),那么平均完成一条指令所花费时间为N/T(当然要求芯片的确在每个周期内能完成各管线级的任 务),因此理论上只要时钟速度加快,则芯片处理能力上升。但问题是管线执行时总有出错(如分支预测失 败)的可能,一旦出错,整个管线就要全部清空,然后从第一级重新执行,在这种情况下,长管线的全部花费 时间通常比短管线多。这就是部分AMD部分芯片比Intel相同甚至更高主频的芯片实际速度要快的原因。 分支预测:branch prediction。解决管线中条件转移引起管线停顿的问题。例如第一条指令是条件转移,那 么需要等其判断结果出来后才能执行下一条指令,分支预测可预测判断结果,然后尽快执行其他指令,从而不 致管线停顿。当然预测也有出错的时候,预测失败将导致管线清空,从头执行。目前预测准确度可达90%,进 一步提高分支预测准确率是正在研究的重要课题。 乱序执行:out-of-order execution。解决管线中指令相关引起管线停顿的问题。后序指令需要正在执行指 令的结果,因此无法立即处理后序指令,这叫做指令相关,造成其他处理单元的停顿,白白损失时钟周期。解 决办法是立即找出其他不相关指令来执行,最后由重新排列单元将各执行单元的结果按原来指令顺序重新排 列。很显然,乱序执行是有风险的。 译注6 出自美国电影《化身博士》(Dr. Jekyll and Mr. Hyde,有1931和1941两个版本)。故事讲述哲基尔医生相 信每个人都同时拥有两极化的个性——好的一面与邪恶的一面。如果将这两种个性分开成为截然不同的两个 人,这两个灵魂都将获得释放。他随后成功地用化学实验将自身邪恶的一面转化成为海德先生,此先生犯下了 可怕的罪行。但当他想要停止用药时,却惊恐的发现一切为时已晚…… 译注7 读/写操作再排序都属乱序执行。看下面一段原始指令代码: (p1)br label //分支判断。若为true则跳转到label,否则继续执行 ld8 r9 r5 //从r5所指地址空间读取8个字节到r9 add r2 r9 r3 //将r9和r3中值求和,并存入r2 其中ld,load;r,register。 因为load操作较耗时间,通常花费几个时钟周期才能完成。因此从提高效率的角度看,应该在处理器空闲的情 况下,尽早加载此操作。比如简单再排序优化后: ld8 r9 r5 (p1)br label add r2 r9 r3 如果分支判断结果为false,流程发生跳转,那么可以直接舍弃r9的结果值,即ld8白做了;但如果未发生跳 转,则ld尽早执行,提高了流程整体效率。 当然,CPU实际工作远比上面例子复杂。比如将ld提前,但如果ld失败怎么办?有依赖关系的指令呢,能否乱 序?在多线程应用里,乱序还可能引起其他一些问题,比如Java中的Double-Checked Locking失败。 不光CPU支持乱序执行,现在的很多编译器也开始做乱序优化,而且重心有逐渐从硬件转到软件的趋势。 有两篇资料可以参看:Scaling Itanium® Architecture for Higher Performance(特别是其中的如何处 理指令依赖值得了解)和Verified Optimizations for the Intel IA-64 Architecture。 译注8 片内,英文为on the die或On-Die。Die:裸芯;Chip:包装后的芯片。类似有On-Chip、Off-Die/Chip。 译注9 MMX:MultiMedia eXtension,多媒体扩展。Intel在1996年3月份正式公布了MMX技术的细节,并于1997年1 月正式向全球推出基于MMX技术的166MHz和200MHz Pentium芯片,AMD也几乎在同时推出了支持MMX技术的第 六代处理器AMD K6。 MMX技术是Intel针对×86体系的一次重大扩充,使计算机同多媒体相关任务的综合处理能力提高了1.5~2 倍。它不仅是Intel自 i386面世以来对CPU体系结构的一次显著改进,同时也是IT界对多媒体数据处理等专用 芯片及功能板卡的一次成功挑战。 SSE:Streaming SIMD(单指令多数据) Extensions,是Intel针对AMD K6-2引入的“3D NOW!”技术,于 l999年在Pentium3中引入的SIMD扩展指令集,业界也称为MMX2,在多媒体数据处理(特别是3D)和浮点运算 等能力上全面加强。 译注10 目前频率最高的处理器是Intel P4 570J,3.8GHz,上升非常缓慢。 CPU频率越高,所需电能和发热量越多;而晶体管越小,耗电和热量越低。制造工艺进步,可能让晶体管更 小,从而让CPU在相同或一定程度内提高的能耗下达到更高频率。从这个角度说,提升CPU频率的瓶颈是制造工 艺。 于是,Intel推出了了90nm工艺的Prescott核心Pentium4,其理论频率将能达到6GHz!然而世事难料,在 90nm工艺晶体管里,由于电介质厚度太低无法阻挡电子的穿越,造成了严重的电流泄漏问题,随之带来的就是 大量的电能消耗和废热。如果强行提升频率,则发热激增,CPU经不起如此的高烧。 泄漏电流问题并非不可解决,但绝不能在短时间办到。至此,芯片厂商提升系统性能的思路开始发生重大变 化,即转向多核。 有关电流泄漏和应对策略的详情,可参看:NetBurst的继承者 Core微处理器架构技术解析。 译注11 在IDF05(Intel Developer Forum 2005)上。Intel首席执行官Craig Barrett就取消4GHz芯片计划一 事,半开玩笑当众单膝下跪致歉 译注12 Working Set,记录了操作系统为进程提交的内存的总量。 译注13 并发编程语言(Concurrent Language)中的术语。 协同程序(coroutines),或协程。用以实现协作式多任务,于上世纪60年代提出。同属一个协程的多个进 程,在同一时刻只能有一个处于运行状态。协程属于一种并发进程创建方式,其他方式还有Fork/join、 Cobegin/coend和进程显式申明(Process declarations)等。 并发进程之间的通信方式主要有两种方式:变量共享(shared variables)和消息传递(message passing)。其他还包括抽象于更高层次的远程过程调用(remote procedure call,RPC)等。 通信就离不开同步。同步方法主要包括:信号量(semaphores)、条件临界区(conditional critical regions)、管程(monitors)、互斥(mutual exclusion)、路径表达式(path expressions)、原子事 务(atomic transactions)和汇集(rendezvous)等。 其中的管程是位于低级同步控制手段之上的一种对象化管理工具。信号量的使用是无结构的,很不方便;条件 临界区相对于信号量更结构化,但同步控制代码仍然非常分散,不利于管理。因此引入了管程,它实现了共享 资源的集中管理,封装了共享资源以及施于其上的操作。 译注14 因为某些原因(如竞争条件下静态变量初始化问题),线程还未被列入ISO C++标准。目前在不同的平台上, 都有线程的专门实现,短时间内难以完全统一。 不过Boost线程库目前差不多具有准标准身份。 译注15 并行编程中必须考虑的两个问题是被处理数据和任务间通讯。经过用户的选择与市场的淘汰,现在的并行编程 标准基本上趋向以下三种: 1、数据并行。特点,各任务处理的数据彼此分离,任务间通过消息传递进行通讯;数据分离和消息传递工作 由编译器完成。 HPF(High Performance Fortran,高性能Fortran)是典型的数据并行编程语言。因为目前的编译器技术对 实际应用中各种不规则问题的解决方案仍不够理想,加上专注于数据并行,因此HPF未获广泛应用。 2、消息传递。特点,各任务处理的数据彼此分离,任务间通过消息传递进行通讯;数据分离和消息传递工作 由程序员和用户完成,因此对程序员要求很高。这种模式非常适用于消息传递的体系结构(如机群系统),用 户和程序员主要需考虑的是通讯同步和通讯性能问题。 并行虚拟机(PVM,Parallel Virtual Machine)和消息传递接口(MPI,Message Passing Interface) 是两种广泛使用的消息传递并行编程标准。其中PVM侧重异构环境下的可移植性和互操作性;MPI更强调性能, 但在异构环境下有不同的实现。几乎所有的高性能计算系统都支持PVM和MPI。 3、共享内存。特点,各任务处理的数据实现内存共享,任务间也通过共享数据实现通讯;数据共享可由程序 员或编译器完成。共享内存并行编程主要应用在对称多处理器(SMP ,Symmetric Multi Processors)系统 上。 OpenMP(Open MultiProcessing由X3H5发展而来)和PThread(POSIX Thread)都是共享内存并行编程的实 现。 OpenMP由1993年建立的X3H5标准发展而来,目前已成共享内存并行编程的实际工业标准,得到DEC、Intel、 IBM和Sun等厂商广泛支持。它在Forthan、C/C++得到了实现,主要支持隐式并行编程,即编译器实现并行。 PThread主要在Unix系统上使用。Unix的实现系统很多,比如Linux、FreeBSD、Solaris、Mac OS X等。要 在众多“类UNIX”上开发跨平台的多线程应用,绝非易事,因此制定了POSIX Thread标准。Addison Wesley (Boost库发起者之一,ISO C++标准委员会成员)的《Programming with POSIX Threads》这本书,可以 说是Unix上编写多线程应用的必备参考书。对其他平台并行程序开发也有很高参考价值。 总的来说,共享内存并行编程与目前大多数的多线程程序员思维习惯最为接近,是程序员从单核转向多核系统 需付代价最小的方案。但专家仍有不同意见,比如Herb Sutter就不看好OpenMP,因为共享内存并行编程本质 上并没有太多改进,仍然依赖数据资源的锁定,这会带来性能问题。消息传递并行有性能优势,但对程序员的 要求又太高了。所有这些难题,还需要研究并行和各种标准、库的专家继续努力解决。 --- ※ 来源: 齐鲁热线虚拟社区 http://club. [FROM .*] 作者:imissunow 时间: 2006.08.30 13:04 :0 朵 :0 个 回复【 imissunow 】: 原文于2005年3月发表在Dr. Dobbs Journal,被Rickard Oberg(J2EE奇才,JBoss作者)认为是 2005年度世界最重要技术文章之一。文章深刻分析了处理器性能提升技术的发展历史与未来趋势、并发的重要 性及其与软件的关系,以及现阶段并发编程中存在的主要问题。文章特别强调:软件开发史上,自面向对象降 生以来的又一个巨变已经叩向我们的房门,那就是并发。 --- ※ 来源: 齐鲁热线虚拟社区 http://club. [FROM .*] 作者:imissunow 时间: 2006.08.30 18:02 :0 朵 :0 个 回复【 imissunow 】: 译文叙述深刻而生动、分析到位、不失风趣。实为揭示“后摩尔时代”软硬件相辅相成发展趋势的精彩 好文! “安迪送,比尔取”=“Intel送、微软取”——指我们大家购买的PC机处理速度越来越快,更快的CPU 价格却更便宜,这就是摩尔定律带给我们的实惠。而微软操作系统从95到XP、longhorn越来越大、越来越占用 资源,更庞大的操作系统得以运转的基础就是更快的CPU。显然微软也从摩尔定律得到了实惠。 文中指出按照CPU主频从几百M达到1G、2G、3G的跨越速度(大概是2002年-2003年间的事情),2006 年的今天我们应该已经得到接近10G速率的CPU,而事实是从4年前CPU达到1G,今天我们常见的CPU速率顶多3G 左右,CPU主频提升速度确实几乎停滞! 文章也揭示了今后软件效率提升之道,那就是并发:多线程编程或者说多进程编程!SUN的J2EE有与生具 来的天赋,最常见的JSP实际上就是多线程运行的,只是很多编程新手并没有注意到这一点。 --- ※ 来源: 齐鲁热线虚拟社区 http://club. [FROM .*] 作者:imissunow 时间: 2006.10.12 16:06 :0 朵 :0 个 回复【 imissunow 】: ABCNews.com报道,众所周知的摩尔定律被英特尔验证是有效的,并被人们认为能在半导体行业里继续 存在下去。而摩尔第二定律则成为软件厂商最大的隐患,因为按照摩尔的这两条定律可以发现,软件更新的速 度很难赶上硬件。 几乎每一个生活在这个现代社会里的人都听说过摩尔定律(Moores Law),它甚至成为了这个数字时代的基 础,也成了我们日常生活中的节拍器。 但是肯定很少有人听说过摩尔的“第二”定律。在接下来的几年里它将会被证明比第一个定理还要重要。 事实上,如果这两个定律继续继续存在,那么它们将会给微软这样软件巨头带来灾难。 摩尔定律是硬件革新步伐当中的重要主题,并陪伴着落后的软件行业继续前进。这大概就是微软一再推后 发布新系统并带来众多麻烦的原因之一。 展望未来,革新步伐的不一致不仅仅会影响软件和电脑市场,同时一些一科技为基础的产品比如飞机、手 机、电视甚至MP3播放器,这些人们每天需要的东西都会受到或多或少的影响。 根据行业分析机构Venture Development Corp.的估计,所有目前正在正在进行着的项目当中,大约有一 半都要落后与预定的时间,超出的时间平均为四个月。同时更糟的是,我们目前新产品的革新速度已经开始逐 渐变的慢下来,这些都是以我们舒适的生活、娱乐甚至健康为代价的。 40岁的“定律” 我们把摩尔定律称为摩尔的第一定律。你肯定还记得它的内容,就是半导体芯片的精度将会以18到24个月 为周期翻倍。这个定律是由高登·摩尔(Gordon Moore)于1965年提出的,他是Fairchild公司和英特尔公司 的联合创始人。摩尔的预言因为65纳米芯片的出现而被证明是继续有效的,同时摩尔定律还被认为至少能在半 导体领域里存在20年甚至更长的时间。这个定律不仅适用于存储芯片,在微处理器方面也表现的相当好,从手 机到个人电脑甚至到遗传学,几乎所有的领域都要用到它。 这将真正地告诉了我们摩尔定律在我们的生活中的重要地位,无论我们是不是知道它。 那么第二定律到底是怎么一回事呢? 几乎没有人知道摩尔在写有第一定律的那张纸上的另一个定律,它只是一个很短的段落,尽管描述的不是 很清楚甚至很深奥,但是他仍然有力地向我们形容了什么是第二定律。它是这样说的:“我们可以花更小的代 价建立出更大的系统,而且它的功能也会很庞大,它由很多相关联的部分组成。它能实现非常庞大的功能,而 且这种功能会和设计和结构紧密地结合在一起,它可以让这些巨型系统的制造商快速并经济地设计和构造出各 种各样的设备。” 大概一年前,我在《连线》杂志上再次重新看到了这段话,给我的感觉就是一段关于电子设备效率的晦涩 难懂的话。而且正像摩尔第一定律还不是一个真正正确的定律,但是芯片制造商们向消费者允诺,称他们会尽 可能地保持技术发展的速度,所以摩尔第二定律也要被提倡做出类似的允诺:任何电子系统的整体效率每24个 月翻一番。 尽管《连线》杂志的这篇文章称这些电子设备需要更好的电池来提供能量,不过我认识到了对于这个高科 技的世界里的一些其他东西,摩尔第二定律对它们的意义将更加深远。 软件必须要赶上硬件的步伐 单凭经验来考虑,芯片的性能翻倍,软件就需要以四倍的速度增长。而且根据摩尔第一定律,芯片的性能 每隔两年都会发生飞跃性的改善,那么代码的数量将会每隔一年就增加一倍。不幸的是,这种事情不会成为现 实。 环顾周围,你会发现任何一个地方都会有这种问题出现。目前手机使用的代码平均为200万行,到2010年 会增加到1000万行。如果根据摩尔定律来看,电视所需要的代码将是这一数字的两倍。而目前的汽车需要的代 码数量平均为3500万行,到2010年这个数字会突破1亿行。 而现在这些数不清的科技产品将得不到足够的发展,因为根据摩尔定律,硬件的发展速度远远跟不上软 件。这当然会对去年那些堂吉诃德式的商业行为产生影响:为什么微软这个依靠开发和销售操作系统的软件巨 头,在它的下一代操作系统Vista上屡屡受挫。Vista的延期发布就像是抛锚了一般,尤其是戴尔。但是微软还 是一次又一次的推迟发布。 硬件和软件之间的这种差距在继续拉大,它让人们越来越觉得不安,同时它的恶化速度也会越来越快。 尽管这样,但是我们没有浪费一丁点时间。摩尔定律会继续影响着整个行业,有力并无情地要求更多科技 行业不断创造奇迹。 --- ※ 来源: 齐鲁热线虚拟社区 http://club. [FROM .*] 作者:imissunow 时间: 2006.10.29 21:58 :0 朵 :0 个 回复【 imissunow 】: 单纯提高频率来提高性能,已经被证明是错误的想法 X86通用处理器走到今天,已经面临一个分水岭了,INTEL彻底抛弃Netburst架构和摩尔定律,全面转向 Core架构,INTEL重新迎来了一个光明的未来。 2年内,Netburst完全输给了HAMMER,Pentium 4虽然有极高的频率,但是并没有带来高性能,相反,却 带来了高功耗和高发热,在零售市场一败再败。INTEL宣称Netburst架构可以发展到10G主频成为一个笑话。 那接下来怎么办?既然单纯提高频率已经被彻底否定,接下来的发展方向在哪里呢?INTEL对外界的回答 是多核。那让我们来看看多核吧。 最早出现的双核处理器,是AMD是X2系列。INTEL为了对抗AMD的双核,早早推出了Pentium D805和820, 可惜这个早产的Pentium D8XX系列架构同样非常糟糕,INTEL只是简单的将2个Netburst架构的Pentium 4简 单的整合在一起,2个核心之间的二级缓存没有共享,2个核心工作的时候,必须通过拥挤的北桥来交换数据, 这样无疑大大的拖累了系统的运行速度。而且Netburst架构的高能耗,高发热再一次得到体现,Pentium D820的TDP高达110W,而AMD推出的双核处理器Athlon X2系列则在设计时就考虑了这个问题,2个核心共享二 级缓存,这样在效率上大大超过了Pentium D,而且基于HAMMER的优秀架构,Athlon3800+ X2的最高TDP仅为 89W,更有低功耗的65W版本,同功耗的效率,几乎比Pentium D性能要高30%。即使是最近发布的Pentium D915,65NM的工艺,性能也不过和AMD的Athlon3600+ X2相当,在浮点运算方面仍然落后于Athlon3600+ X2 5-10%。 Conroe系列处理器的发布,为INTEL在X86处理器市场挽回了一丝面子。2年来,一直被AMD的大锤 (HAMMER)架构压制着的INTEL,在DIY市场,份额不断降低,OEM市场,AMD已经得到了广大集成商的青睐, DELL,HP,LENOVO,这三家世界上最大的集成商,均生产了基于AMD处理器的电脑,在中低端服务器市场, Opteron让ITNEL的XEON相形见拙。这一切,随着Core架构系列处理器的发布,INTEL终于重新巩固了业界霸 主的地位。 Core核心,抛弃了Netburst架构,直接从P6(Pentium 3时代的架构)基础上重新设计,并借鉴了INTEL 位于以色列海尔法实验室(著名的Pentium M就是这里设计的)的经验,采取了较短的14级流水线,并使用了 5个新技术:宽区动态执行(相比以前的X86处理器增加了一组解码器,解码器总数达到了4组,AMD以前尝试过 没有成功放弃了),高级智能告诉缓存(双核心共享二级缓存,加宽了每个内核的带宽),高级数字媒体增 强,智能内存访问,智能功率特性。以上努力使得到目前为止,Conroe成为地球上最强的X86处理器。INTEL 进一步宣称,将在未来几年内发布多核,甚至百核的处理器。试图以多核来提高处理器的性能,同时有不致让 处理器功耗和发热成倍增长。 AMD对付Conroe的利器,是降价,但是降价毕竟不是长久手段,这是损人不利己的办法,没得办法的办 法。AMD基于K8L新架构的处理器,得等到明年2季度才能发布,根据目前的解密信息K8L的浮点运算单元将比 目前的HAMMER增加一倍,并且将采取模块化设计,原生4核,和65NM工艺。但是从目前看,似乎仍然无法超越 Conroe,顶多是打个平手。为此,AMD祭出了大旗——HT3和协处理器。 HT,即HyperTransport,是AMD 1999年提出的一种总线技术,是一种为主板上的集成电路互连而设计的 端到端总线技术,目前市面上销售的AMD的处理器,都是基于HT2连接的。目前的HT,类似于INTEL的FSB (Front Side Bus前端总线)。以前这一点,只有InfiniBand和光纤通道做得到,但是这2者都需要通过独 立的控制器实现,而且CPU和CPU之间是无法直接沟通的。而HT2时代AMD的Opteron处理器在服务器领域高速发 展的原因之一就是因为在一个服务器内不管有多少个处理器,通过HT2,总能保持高效工作和卓越的协作效 率。 而HT3,则不仅仅是主板上各部件的端到端总线技术和各个处理器之间的连接,HT3可以扩展到多个处理器 连接的同时,还扩展到多个服务器系统之间的连接,即多部服务器可以HT3标准的线缆联结在一起,,由于HT3 控制器由CPU提供,这意味着无论集群内有多少枚处理器,彼此都是通过HT3来直接沟通,这样就确保了优良的 协作效率,从而非常简单的构建服务器集群。而且,HT3是弹性的,OEM厂商可以迅速的调整集群内服务器的数 量,而不必考虑更多的技术问题,这就让哪些技术实力不强的PC厂商也有能力开发销售自己的服务器集群产 品。而大型的基于HT3技术连接服务器,还可以用于大规模科学运算,模拟核实验,气象预测等等领域,这些 领域到目前为止都是RISC处理器的天下,X86无法插足。HT3的出现将改变这个现象。AMD的HT3的出现,将是 计算机领域的一次革命,他不仅仅威胁到INTEL,而且还威胁到了IBM,SUN,HP等公司在该领域的存在。计算 机领域将重新洗牌的可能性非常大。 协处理器,则是AMD在收购了ATI公司以后提出来的一个概念,代号为Torrenza。 关于AMD Torrenza平台技术:该新平台允许两颗处理器(CPU或GPU)以协处理器架构同时运行,将把下 一代多核心64位处理器的效用再次提升。Torrentza的设计为开放式架构,它以Opteron处理器为基础,支持 使用“Accelerators(加速芯片组)技术。可缩短CPU、芯片组、内存之间的通信延迟,实现系统的提速,并 向第三方芯片组厂商开放。而协处理器可以通过HT3总线连接,换句话说,以后的电脑,如果你觉得性能不 足,你可以如同插入USB设备一般,加一个CPU或GPU,而不必要重新购买主板等等,让你的整机性能获得质的 飞跃。 写在最后: INTEL和AMD是目前世界上2大半导体巨头,控制着世界上90%以上的X86处理器的生产和销售。 INTEL在Conroe发布后,在2006秋季IDF上公布了新的4核处理器,代号为Kentsfield,该处理器是将2颗 Conroe封装在一起,每个双核的Conroe单独享用4M的二级缓存,在某些方面,性能比Conroe提高了30-40%, 而TDP仅仅为130W而已。跟Pentium D可以看平。这里足以看出Conore的架构之优秀。 AMD则没有仅仅关注处理器本身,他把目光放得更远,力图构建一个基于HT3.0为核心的新的计算机体系。 如果INTEL不拿出及时有效的对付方案,仅仅关注处理器本身的发展,在未来新一波的计算机技术发展过程 中,不免将再次落入下风。 引用资料:微型计算机10月上期硬派讲堂,10月下期产品与评测。 --- ※ 来源: 齐鲁热线虚拟社区 http://club. [FROM .*] 作者:imissunow 时间: 2006.10.31 20:45 :0 朵 :0 个 回复【 imissunow 】: 通过堆栈调用解析多线程 首先说明一下,堆是进程的全局数据内存存储区,栈是函数的局部数据内存存储区。由于大多数书籍在介 绍堆或栈时,皆以堆栈泛指,因此,题目标题亦如此表述,希望读者不要混淆就是了。 初见标题,也许有人觉得奇怪,多线程和堆栈有关系吗?初学多线程,很多概念难以辨清。要全面深入理 解多线程,必须对栈有十分清楚的理解。个人感觉在Windows编程中,栈的概念犹如C/C++中的指针,非常重 要,但难于全面理解。市面上的书籍对堆栈的介绍或是蜻蜓点水、浮于表面;或是过于理论化,不够具体,不 易理解。在这里,我以示例的形式将自己的一点学习体会写出来与大家分享。为了便于表述清楚,文章分为两 部分:第一部分介绍栈的调用,这是此篇文章的核心。第二部分解析多线程的概念。 一、栈的调用 众所周知,在函数调用过程中,参数的传递是通过栈完成的,具体到机器码是什么样子呢?不同的调用约 定(PASCAL约定或STDCALL约定等)将导致不同的参数压栈顺序,这些细节就略去不讲了,有兴趣的读者可以 参考相关书目。为了把栈的概念表述清楚,这里将涉及到一些简单的汇编语言方面的知识,一点点而已。然后 以一个简单的C++控制台程序为示例来进一步详细说明。先把代码列出来,够简单吧。 #include int fn(int n) { n+=1; return n; } void main() { int i=1,j=10; i=fn(i); // A j=fn(j); // B cout< 在A处,进程的主线程调用了函数fn并传递了参数。其汇编代码如下: 004010B6 mov eax,dword ptr [ebp-4] //此时ebp=0x0012ff80,&i=0x12ff7c,ebp-4为i的地址 004010B9 push eax 004010BA call @ILT+20(fn) (00401019) 再明显不过了,第一行汇编代码将变量i的数值放入寄存器eax中。第二行汇编代码将变量i的数值压入栈 中,对应前面(1)。第三行汇编代码执行call指令,此条指令自动将返回地址压入栈中,然后,跳转到函数 体内部,准备执行函数内部的代码,对应前面(2)。 现在我们再来看看函数内部的代码是什么样子。这里只截取部分相关代码。 2: int fn(int n) 3: { 00401050 push ebp 00401051 mov ebp,esp … … … … 4: n+=1; 00401068 mov eax,dword ptr [ebp+8] //此时ebp=0x12ff20 &n=0x12ff28 eax=1 0040106B add eax,1 0040106E mov dword ptr [ebp+8],eax 第一行汇编代码对应前面(3)。第二行汇编代码对应前面(4)。第三行汇编代码将变量n的数值放入寄 存器eax中。第四行汇编代码将其加一。第五行汇编代码将结果放回变量n。这里可以十分清楚地看到,EBP寄 存器用于参数的寻址。 现在我们再看看B处函数调用的情况。 004010C5 mov ecx,dword ptr [ebp-8] //此时ebp=0x12ff80,&j=0x12ff78 ,ebp-8为j的地址 004010C8 push ecx 004010C9 call @ILT+20(fn) (00401019) 可以看到,除了压栈数值变化以外,没有其它不同了。A处压栈i,B处压栈j。 下面使用VC单步调试,再来看函数体内部,汇编代码没有任何不同,不同的只是栈。当然了,函数体的代 码是编译器一次性编译的。即使被多次调用,去完成不同的工作,不同的只是参数(调用栈),函数内部使用 间接寻址,只是相同的机器码操作不同的内存存储区而已。 2: int fn(int n) 3: { 00401050 push ebp 00401051 mov ebp,esp … … … … 4: n+=1; 00401068 mov eax,dword ptr [ebp+8] //此时ebp=0x12ff20 &n=0x12ff28 eax=10 0040106B add eax,1 0040106E mov dword ptr [ebp+8],eax 到了这里,栈的概念就讲完了。 二、解析多线程 这里首先要明确一点:每一个线程都独立拥有一个栈。 我们知道,Windows系统是一个多任务操作系统,多个线程可以“同时”执行。前面讲到,CPU执行程序 代码完全依靠各种寄存器。当一个线程将被挂起时,当前的各种寄存器的数值就被存储在了线程的栈中。当 CPU重新执行此线程时,将从栈中取出寄存器的数值,接着运行,好像这个线程从来就没有被打断过一样。正 是因为每个线程都有一个独立的栈,使线程拥有了可以“闭门造车”的能力。只要将参数传递给线程的栈, CPU将担负起这块内存存储区的管理工作,并适时地执行线程函数代码对其进行操作,所有这一切与前面所讲 述的没有不同。当系统在多个线程间切换时,CPU将执行相同的代码操作不同的栈。 下面举一个例子来加深理解。 随着面向对象编程方法的普及,我们很乐意将任何操作都包装成为一个类。线程函数也不例外,以静态函 数的形式将线程函数放在类中是C++编程普遍使用的一种方法。通常情况下对象包括属性(类变量)与方法 (类函数)。属性指明对象自身的性质,方法用于操作对象,改变它的属性。现在有一个小问题要注意了。类 的静态函数只能访问类的静态变量,而静态变量是不属于单个对象的,他存放在进程的全局数据存储区。一般 情况下,我们希望每个对象能够“独立”,也就是说,多个对象能够各自干各自的工作,不要相互打扰。如果 以通常的方法,以类(静态)变量存储对象的属性,可就要出问题了,因为类(静态)变量不属于单个对象。 现在怎么办呢?如何继续保持每个对象的“独立性”。解决的方法就是使用栈,将参数传递给线程函数的局部 变量(栈存储区),以单个对象管理每个线程,问题就解决了。当然了,解决方法是多种多样的,这里只是为 了进一步解释多线程与对象的关系。 由于Windows的内部实现实在是太复杂了,这里只是在应用的层面上对栈给出解释。若深入到Windows内 部,栈的定位首先需要依据寄存器SS经由(全局或局部)段描述符表得到相应的线性地址(虚拟地址)基址, 此基址与EIP相加,然后再经由分页机制寻址物理内存。有兴趣的读者可以参阅文章后面的参考书目。一点学 习体会写出来与大家分享,有不对的地方,欢迎指正。 参考书目: 《Intel汇编语言程序设计》(第四版),作者:Kip R.Irvine,电子工业出版社翻译出版。 《Windows环境下32位汇编语言程序设计》,作者:罗云彬,电子工业出版社出版。 |
|