<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>并行实验室 &#124; Parallel Labs</title>
	<atom:link href="http://www.parallellabs.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.parallellabs.com</link>
	<description>关注并行计算与多核多线程编程</description>
	<lastBuildDate>Sun, 05 Feb 2012 05:33:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>云计算时代的多核开发</title>
		<link>http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/</link>
		<comments>http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/#comments</comments>
		<pubDate>Sat, 21 Jan 2012 17:24:54 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[业界评论]]></category>
		<category><![CDATA[并行编程]]></category>
		<category><![CDATA[Big Data]]></category>
		<category><![CDATA[互联网]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[多线程编程]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=1179</guid>
		<description><![CDATA[注：原文发表于《程序员》杂志2011年第12期，略有删改。

云计算和多核这两大趋势正对软件开发者产生重大影响。近几年，多核逐渐成为主流：随着提升CPU核心频率越来越难，处理器厂商选择了更加容易实现的多核方案来继续提升硬件的性能。进入后PC时代，移动处理器也同样面临着性能的提升与功耗的控制这两大挑战，为了满足提升性能与控制功耗的需求，多核也正成为其以后发展的方向。另一方面，云计算也渐渐成为软件开发的大势。在云计算的生态系统中最主要的设备是“端”和“云”。所谓端包括移动设备（智能手机，Pad等）和传统的PC，尤其是前者；而云指的就是由高性能服务器组成的大规模集群，它们向端设备提供各种服务支持。在云计算时代进行多核开发会是一幅什么样的场景？这两大趋势彼此会有什么样的影响？我们不妨先回顾一下在大型机和PC机时代软件开发的历史。

<p><a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era"  >阅读全文>></a></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E4%BA%91%E8%AE%A1%E7%AE%97%E6%97%B6%E4%BB%A3%E7%9A%84%E5%A4%9A%E6%A0%B8%E5%BC%80%E5%8F%91&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2012%2F01%2F22%2Fmulticore-programming-in-cloud-era%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E4%BA%91%E8%AE%A1%E7%AE%97%E6%97%B6%E4%BB%A3%E7%9A%84%E5%A4%9A%E6%A0%B8%E5%BC%80%E5%8F%91&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2012%2F01%2F22%2Fmulticore-programming-in-cloud-era%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p><em>注：原文发表于《程序员》杂志2011年第12期，略有删改。<br />
</em></p>
<p>云计算和多核这两大趋势正对软件开发者产生重大影响。近几年，多核逐渐成为主流：随着提升CPU核心频率越来越难，处理器厂商选择了更加容易实现的多核方案来继续提升硬件的性能。进入后PC时代，移动处理器也同样面临着性能的提升与功耗的控制这两大挑战，为了满足提升性能与控制功耗的需求，多核也正成为其以后发展的方向。另一方面，云计算也渐渐成为软件开发的大势。在云计算的生态系统中最主要的设备是“端”和“云”。所谓端包括移动设备（智能手机，Pad等）和传统的PC，尤其是前者；而云指的就是由高性能服务器组成的大规模集群，它们向端设备提供各种服务支持。在云计算时代进行多核开发会是一幅什么样的场景？这两大趋势彼此会有什么样的影响？我们不妨先回顾一下在大型机和PC机时代软件开发的历史。</p>
<h2><span style="color: #3366ff;">多核上开发将更加容易</span></h2>
<p align="left">在大型机时代，计算机非常昂贵，用户需要分时共享同一台大型机。计算资源的稀缺使得那时候的软件开发者必须高效地利用每一个处理器时钟周期，因此他们大都使用汇编、C等非常底层的语言来进行软件开发，而算法的效率是他们最关心的问题。在之后的几十年中，计算机硬件变得越来越廉价，软件开发者越来越不需要关心软件的性能。以主流的互联网应用为例，现在的开发大量使用成熟的框架来帮助自动生成大量的代码。就拿Django这个流行的Web开发框架来说，它的设计原则是“focuses on automating as much as possible and adhering to the DRY principle: Don’t Repeat Yourself.”开发者最核心的目标已经变成了如何用最少的代码，最快的速度将自己的点子转为成可用的软件产品并推向市场。<em>“市场投放时间”已经取代“处理器时钟周期”成为软件开发的关键指标。</em>在过去的几十年里，正是因为硬件一直在按照摩尔定律稳步地发展，所以开发者不再需要时刻关注软件的性能，而是将其注意力转移到更为重要的开发效率上，这点在近十年来Java、Python、Ruby等高级语言的兴起上就可见一斑。多核的出现，将硬件的细节再一次暴露在程序员的面前。如果想利用好多核，程序员必须手动的处理同步、死锁、数据竞跑等疑难问题，这极大的降低了软件开发的效率。现有的生产工具（多核开发框架、开发工具）远不能满足生产力（软件开发效率）的发展需要，还有很大的发展空间。可以预见，<strong><em>不久的将来更简单易用的多核开发框架将不断涌现，在多核上进行并行编程将变得越来越容易。</em></strong></p>
<p align="left">那放在云计算的大背景下，多核开发又会有怎么的发展呢？让我们先来看一看在“云”和“端”上的多核发展趋势。</p>
<h2><span style="color: #3366ff;">“云”和“端”的多核趋势</span></h2>
<p>据IDC预测，以智能手机和Pad为代表的移动设备在2013年将达到3.9亿台的出货量；相对的，传统PC机、笔记本和服务器加起来的出货量预计为4.4亿[1]。移动设备的日益流行将让更多的开发者转向移动平台。与此同时，云将为端设备提供更多的服务支撑。那么云和端上的多核将如何发展呢？</p>
<p><a href="http://farm8.staticflickr.com/7001/6820998747_b2e8d526fc.jpg"><img class="alignnone size-full wp-image-1180" title="multicore" src="http://www.parallellabs.com/wp-content/uploads/2012/01/multicore.bmp" alt="" width="708" height="87" /></a></p>
<p>如上图所示，从2012年开始双核的手机/平板将成为主流。因为受到功耗的限制，移动设备上的处理器核数并不会迅速增长。实际上，移动设备将会越来越多地依赖专用硬件加速器来提供高性能、低功耗的解决方案。GPU（图形处理器）就是一个很好的例子。在手机和平板上观看高清电影、玩高分辨游戏时会我们可以依靠专用的图形处理器来进行图像渲染、高清解码等操作，这种解决方案相比于使用更多的通用处理器核数来说能提供更高的性能功耗比。从开发者的角度来讲，产品设计、用户体验才是现阶段移动开发者最关注的问题，而如何利用并行编程的方式提升移动应用的性能在短期内还不会是最主要的关注点。不可否认的是，越来越多的移动应用将通过并行化的方式提供更绚丽的3D渲染，更流畅的用户体验以及更丰富的特效（尤其是游戏类应用）。</p>
<p>与此同时，云端服务器的处理器核数将继续以每18个月翻一番的速度增长。在多核出现之前，软件开发者无需担心软件的性能，他们唯一需要做的就是“等”：等到下一代处理器出现时，软件对性能的需要就能得到满足。这个免费的午餐在多核到来之后不复存在：单纯靠增加处理器的核数并不能提升单线程程序的性能。换言之，我们必须通过并行的方式来提升“串行”应用的性能。但是如果我们所关心的问题不再是如何提升单线程的性能，而是如何利用更多的核来处理已经并行化的应用（例如MapReduce），那么核数的增加不就能继续“免费”地提升此类应用的性能吗？从这个角度来看，云端的应用与多核有点天生一对的意味。举例来说，以Hadoop为基础的大规模数据处理通过并行执行Map和Reduce来有效的对海量数据进行有效的处理。这种数据并行（data parallel）的模式关心的不再是单个Mapper或者Reducer的性能，而是所有Mapper、Reducer的吞吐量。如果需要处理的数据增加了，那么我们一般只需要增加更多的机器（即更多的处理器核数）就能达到所需的性能。</p>
<p>当谈到并行计算时，我们必须区分好两种完全不同的应用：并行（Parallel）与并发（Concurrency）。所谓并行是指两个或多个task同时执行用以完成同一个计算任务，例如使用两个线程来并行地完成矩阵乘运算。所谓并发是指两个或多个task同时执行，但是彼此相互独立、分别在完成不同的计算（这里的task不仅仅局限于线程，它也可以代表纤程、进程等）。而对云计算来说，云端所需要处理的请求大都是并发任务，因为不同的终端请求彼此大都是相互独立的。想象一下数千用户同时使用Google Docs编辑文件，此时服务器端所需要处理的就是数千个并发请求，这些独立的请求能非常自然地把服务器上的多核利用好。由此可见，在云计算的大背景下，大量存在的并发应用能天然的利用好云端的多核，通过并行的方式来利用好多核并不是那么的重要。</p>
<h2><span style="color: #3366ff;">人人都是并行程序员？</span></h2>
<p>在多核出现之初，许多业界人士都惊呼狼来了，人人都需要掌握并行编程。殊不知并行编程这项技术早在二三十年前就已经存在了，只不过当时大都是由搞高性能计算的一小群人会并行编程，而随着多核的普及并行编程的神秘面纱也逐渐向大众展开。幸运的是，在云计算的大图下，多核的应用场景以及与高性能计算领域大不相同。高性能领域关心的主要问题是如何用更多的处理器核心来更快的完成同一个任务，例如天气预测，地震模拟等。而在云计算领域，我们面临的主要难题是如何满足众多端设备的并发请求，这些请求彼此大都独立，因此处于云端之上的开发者已经不太需要担心如何用并行编程来解决他们所面临的问题。</p>
<p><a href="http://farm8.staticflickr.com/7153/6821001131_6d35611db9.jpg"><img class="alignnone size-full wp-image-1181" title="google trend multicore" src="http://www.parallellabs.com/wp-content/uploads/2012/01/google-trend-multicore.bmp" alt="" width="601" height="337" /></a></p>
<p>如上图所示，在Google趋势中“云计算（cloud computing）”这个关键词的热度一直都处在上升趋势中，而“多核（multicore）”的热度一直都比较平稳。随着移动互联网的兴起，Android和iOS开发的热度也已经超过了多核。<strong><em>并不是所有的程序员都需要关心如何进行并行编程。在云计算的大背景下，并发应用能与多核很容易地结合在一起，将云端的多核利用好。</em></strong></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E4%BA%91%E8%AE%A1%E7%AE%97%E6%97%B6%E4%BB%A3%E7%9A%84%E5%A4%9A%E6%A0%B8%E5%BC%80%E5%8F%91&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2012%2F01%2F22%2Fmulticore-programming-in-cloud-era%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E4%BA%91%E8%AE%A1%E7%AE%97%E6%97%B6%E4%BB%A3%E7%9A%84%E5%A4%9A%E6%A0%B8%E5%BC%80%E5%8F%91&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2012%2F01%2F22%2Fmulticore-programming-in-cloud-era%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>12/28/2010 -- <a href="http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices/" title="移动设备进入多核时代！">移动设备进入多核时代！</a></li><li>04/01/2010 -- <a href="http://www.parallellabs.com/2010/04/01/the-third-software-crisis/" title="第三次软件危机">第三次软件危机</a></li><li>01/09/2012 -- <a href="http://www.parallellabs.com/2012/01/09/xrime/" title="X-RIME: 基于Hadoop的开源大规模社交网络分析工具">X-RIME: 基于Hadoop的开源大规模社交网络分析工具</a></li><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li><li>08/27/2011 -- <a href="http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/" title="浅析C++多线程内存模型 ">浅析C++多线程内存模型 </a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>X-RIME: 基于Hadoop的开源大规模社交网络分析工具</title>
		<link>http://www.parallellabs.com/2012/01/09/xrime/</link>
		<comments>http://www.parallellabs.com/2012/01/09/xrime/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 01:44:57 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[系统架构]]></category>
		<category><![CDATA[Big Data]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[ibm]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Social Network Analytics]]></category>
		<category><![CDATA[X-RIME]]></category>
		<category><![CDATA[互联网]]></category>
		<category><![CDATA[社交网络]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=1133</guid>
		<description><![CDATA[随着互联网的快速发展，涌现出了一大批以Facebook，Twitter，人人，微博等为代表的新型社交网站。这些网站用户数量的迅速增长使得海量的用户数据不断被产生出来，而如何有效地对这些海量的用户数据进行社交网络分析（Social Network Analysis）正成为一个越来越热门的问题。本文向大家介绍由IBM中国研究院和北京邮电大学合作开发的X-RIME开源库（http://xrime.sourceforge.net/），一个基于Hadoop的开源社交网络分析工具。

其实早在90年代初就已经有许多企业和研究机构对社交网络进行过相关研究。然而随着互联网用户的急速的增长，今日的社交网站所需处理的数据已经不是传统的解决方案所能够应对的了。例如，传统的社会网络分析算法和工具往往都是单机形式的，在面对大规模数据集的时候往往会出现存储和处理能力不足等方面问题，再加上原始输入数据和社会网络的内部表示大都属于无结构或者半结构化数据，传统关系数据库并不擅长处理此类数据，使得利用传统的社会网络分析算法和工具对大规模数据集进行处理变得更加困难。另一方面，随着Hadoop的日益流行，许多中小互联网企业可以通过搭建Hadoop集群来方便地进行大规模数据处理。然而，Hadoop并不直接提供社交网络分析的算法库，因此实施海量社交网络分析仍存在较高门槛。基于这些需求，我们设计并实现了X-RIME。

X-RIME是一个基于Hadoop的开源社会网络分析工具。依赖于Hadoop提供的大规模数据并行处理能力，X-RIME实现了对十几中网络分析算法的并行化，提供了一整套用于对大规模社会网络进行分析处理的解决方案。通过使用X-RIME，用户可以方便快捷地对海量社会网络数据进行分析，从这些海量社会网络数据中获取更深层次的有用信息，从而进一步挖掘商业价值，支持商业决策以及发现新的业务增长点。

<a href="http://www.parallellabs.com/2012/01/09/xrime" >阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=X-RIME%3A+%E5%9F%BA%E4%BA%8EHadoop%E7%9A%84%E5%BC%80%E6%BA%90%E5%A4%A7%E8%A7%84%E6%A8%A1%E7%A4%BE%E4%BA%A4%E7%BD%91%E7%BB%9C%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2012%2F01%2F09%2Fxrime%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=X-RIME%3A+%E5%9F%BA%E4%BA%8EHadoop%E7%9A%84%E5%BC%80%E6%BA%90%E5%A4%A7%E8%A7%84%E6%A8%A1%E7%A4%BE%E4%BA%A4%E7%BD%91%E7%BB%9C%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2012%2F01%2F09%2Fxrime%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p><strong>文 / 陈冠诚，史巨伟，杨博（IBM中国研究院)，杨寅（人民搜索）<br />
</strong></p>
<p>随着互联网的快速发展，涌现出了一大批以Facebook，Twitter，人人，微博等为代表的新型社交网站。这些网站用户数量的迅速增长使得海量的用户数据不断被产生出来，而如何有效地对这些海量的用户数据进行社交网络分析（Social Network Analysis）正成为一个越来越热门的问题。本文向大家介绍由IBM中国研究院和北京邮电大学合作开发的X-RIME开源库（<a href="http://xrime.sourceforge.net/" target="_blank">http://xrime.sourceforge.net/</a>），一个基于Hadoop的开源社交网络分析工具。</p>
<p>其实早在90年代初就已经有许多企业和研究机构对社交网络进行过相关研究。然而随着互联网用户的急速的增长，今日的社交网站所需处理的数据已经不是传统的解决方案所能够应对的了。例如，传统的社会网络分析算法和工具往往都是单机形式的，在面对大规模数据集的时候往往会出现存储和处理能力不足等方面问题，再加上原始输入数据和社会网络的内部表示大都属于无结构或者半结构化数据，传统关系数据库并不擅长处理此类数据，使得利用传统的社会网络分析算法和工具对大规模数据集进行处理变得更加困难。另一方面，随着Hadoop的日益流行，许多中小互联网企业可以通过搭建Hadoop集群来方便地进行大规模数据处理。然而，Hadoop并不直接提供社交网络分析的算法库，因此实施海量社交网络分析仍存在较高门槛。基于这些需求，我们设计并实现了X-RIME。</p>
<p>X-RIME是一个基于Hadoop的开源社会网络分析工具。依赖于Hadoop提供的大规模数据并行处理能力，X-RIME实现了对十几中网络分析算法的并行化，提供了一整套用于对大规模社会网络进行分析处理的解决方案。通过使用X-RIME，用户可以方便快捷地对海量社会网络数据进行分析，从这些海量社会网络数据中获取更深层次的有用信息，从而进一步挖掘商业价值，支持商业决策以及发现新的业务增长点。</p>
<h1>1. X-RIME架构介绍</h1>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>图一描述了X-RIME的整体架构，它主要由四层组成：HDFS，X-RIME数据模型，X-RIME算法库以及基于社交网络分析的商业智能分析应用。</p>
<div class="mceTemp" style="text-align: center;">
<dl id="attachment_1135" class="wp-caption alignnone" style="width: 561px;">
<dt class="wp-caption-dt"><a href="http://farm8.staticflickr.com/7003/6821005195_30c8776c93.jpg"><img class="size-full wp-image-1135   " title="X-RIME整体架构" src="http://www.parallellabs.com/wp-content/uploads/2011/12/xrime.bmp" alt="X-RIME整体架构" width="551" height="470" /></a></dt>
<dd class="wp-caption-dd">图1. X-RIME整体架构</dd>
</dl>
</div>
<p style="text-align: left;">
<p style="text-align: left;">X-RIME算法库是X-RIME的核心组成部分，他基于Map/Reduce实现了十余种分布式社交网络处理算法。</p>
<p style="text-align: left;">X-RIME最底层采用了HDFS来存储海量数据。像很多其他基于Hadoop的数据分析解决方案一样，X-RIME也采用了HDFS来构建底层的海量数据存储设施。整个X-RIME算法库的所有的输入文件、中间结果和最终结果都会存储在HDFS上。</p>
<p>处于倒数第二层的X-RIME数据模型层实现了社交网络数据的“数据结构”。我们知道，社交网络的基础模型是图论中的图模型。在这个模型中，社会网络的个体被视为图中的节点，个体之间的关联被视为图中的边。 X-RIME数据模型层包括了近20 种数据结构，主要包括基于Hadoop 的对社会网络中的点、边等抽象概念的具体数据结构表示。在后面一节我们会详细介绍该数据模型的设计原则。</p>
<p>在X-RIME数据模型层之上的是X-RIME核心算法库（它运行在Hadoop的MapReduce框架之上）。在算法库中，我们通过map()/reduce()函数对的形式实现了十余种常见的社交网络分析算法。这些算法通过将多个Hadoop Job按算法工作流程组合在一起来共同完成相应的任务。这些算法都被相同的接口封装起来，这些接口一般包括四种参数：（1）输入文件在HDFS中的路径，它保存了与X-RIME数据模型相兼容的输入文件；（2）输出文件在HDFS中的路径，它用以保存最终的分析结果；（3）MAP/REDUCE的相关参数，例如Mapper数或者Reducer数等；（4）社交网络分析算法相关参数，例如迭代次数等。</p>
<p>图一中最顶层是基于社交网络分析的商业智能分析应用。它通过调用X-RIME核心算法库来实现对社交网络的数据分析。如果需要的话，用户还能将它与已有的数据仓库解决方案集成（例如JAQL，Mahout等），从而提供一个更加完整、高效的综合商业智能分析解决方案。</p>
<h1>2. X-RIME 数据模型的设计原则</h1>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>X-RIME 的设计目标是用来专门做大规模数据集社会网络分析的工具，因此我们对X-RIME 数据模型进行设计时必须考虑以下两点原则：X-RIME 需要处理大规模数据集；X-RIME 分析的对象是社会网络。X-RIME 处理大规模数据集的能力主要依赖于Hadoop的大规模并行处理能力，因此只要X-RIME 中所有的数据结构都是基于HADOOP 的海量数据集接口即可。这里我们重点分析X-RIME分析的对象即社会网络的特点。之前的分析中已经提到社会网络的基础模型是图论中的图模型，在这个模型里，社会网络中的个体被视为图里的结点v ，结点的集合为V ；个体之间的关联被视为图里面的边e，边的集合是E = {e (u, v) | u∈V, v∈V}，因此整个模型就可以看作是G = (V, E)。基于此我们对X-RIME 的数据模型做了如下考量：</p>
<h2>2.1 采用邻接矩阵还是邻接表</h2>
<div class="mceTemp mceIEcenter" style="text-align: center;">
<dl id="attachment_1137" class="wp-caption aligncenter" style="width: 516px;">
<dt class="wp-caption-dt"><a href="http://farm8.staticflickr.com/7015/6821009975_db90b7b53f.jpg"><img class="size-full wp-image-1137  " title="稀疏图和稠密图的邻接表与邻接矩阵形式" src="http://www.parallellabs.com/wp-content/uploads/2011/12/稀疏图和稠密图的邻接表与邻接矩阵形式.bmp" alt="稀疏图和稠密图的邻接表与邻接矩阵形式" width="506" height="428" /></a></dt>
<dd class="wp-caption-dd">图2. 稀疏图和稠密图的邻接表与邻接矩阵形式</dd>
</dl>
</div>
<p style="text-align: left;">
<p style="text-align: left;">如图 2 所示，要表示一个图G = (V, E)，有两种标准的方法，即邻接矩阵和邻接表。一般认为当|E|远小于|V|2的图属于稀疏图，反之则认为是稠密图。使用邻接矩阵表示法的优点在于可以很快判断两个给定结点是否存在连接边，缺点在于当要表示的图是稠密图的时候有大量的空间会被浪费。邻接表表示方式的优点在于节省空间，缺点在于判断两个给定结点是否存在连接表需要遍历其中某个结点的邻接表，效率较低。基于以下两点考虑，我们采用了邻接表的方式表示X-RIME 中的图结构：</p>
<p>（1）社交网络一般属于稀疏图结构，因此使用邻接表表示可以节省大量空间，提高空间利用率。<br />
（2）X-RIME 中大部分算法不需要快速判断两个给定结点是否存在连接边。</p>
<h2>2.2 边的表现形式</h2>
<p>在邻接表中，结点之间的关系需要使用边来承载，边的形式可以有多种，如有向边，无向边，自环边（自己指向自己）等。考虑到在社会网络中，上述几种边都有可能存在，在不同的应用场景中有不同需求，因此我们需要有灵活的数据结构来支持上述各种不同形式的边。此外还有一种情况需要考虑，当有向边用{from, to}来表示时，传统的邻接表表示法只是将这条边信息记录在from 端，但是在社会网络分析中，我们可能存在某种场景需要同时将这条边信息记录在to 端，X-RIME 的设计中考虑了这种应用场景。</p>
<h2>2.3 额外的承载信息</h2>
<div class="mceTemp mceIEcenter" style="text-align: center;">
<dl id="attachment_1160" class="wp-caption aligncenter" style="width: 595px;">
<dt class="wp-caption-dt"><a href="http://farm8.staticflickr.com/7164/6821011811_510c82b7a9.jpg"><img class="size-full wp-image-1160  " title="社会网络中结点和边需要存储额外信息" src="http://www.parallellabs.com/wp-content/uploads/2012/01/社会网络中结点和边需要存储额外信息.bmp" alt="社会网络中结点和边需要存储额外信息" width="585" height="266" /></a></dt>
<dd class="wp-caption-dd">图3. 社会网络中结点和边需要存储额外信息</dd>
</dl>
</div>
<p style="text-align: left;">
<p style="text-align: left;">X-RIME 需要处理的社会网络图与传统的简单图不一样，它是个体以及个体之间复杂关系的一种抽象。如图3 所示，在社会网络中，结点自身往往需要存储一些额外的信息，例如当图中的结点表示人的时候，可能需要额外记录这个人的性别、年龄、家庭地址等信息；结点之间的关系（边）往往也需要存储一些额外的信息，例如当图中的边表示两个人是好朋友的时候，可能需要额外记录这条边的强度（好友关系的强烈程度）、边的类型（关系类型，如家人、朋友、同学等）、好友间的物理距离等。基于上述考虑，X-RIME 的设计中必须考虑为结点和边提供额外的信息存储功能。</p>
<h2 style="text-align: left;">2.4 比较器</h2>
<p>在社会网络中，个体和边需要进行某种程度的对比。例如在好友关系网中，人们可能希望比较得出哪些人是自己最好的朋友，人们同样可能希望比较得出自己在好友心目中的重要程度等。映射到X-RIME 中，大量的运算的确需要对结点以及边进行比较。这种比较可以是简单的数值比较（例如边的权值比较）也可以是复杂的逻辑比较（例如综合边的关系类型，边的强度，结点之间的物理距离等进行比较）。X-RIME 的设计中必须考虑数据类型之间的比较，需要设计各种比较器。</p>
<h2>2.5 效率问题</h2>
<p>X-RIME 需要处理的是大规模海量数据，如果我们对输入数据的读写处理只是简单地根据原始的文本文件格式进行读写，势必影响效率，因为这样多了一个中间转换过程，需要读入内存再根据特定的数据结构格式进行转换。Hadoop 提供的序列化IO 接口为我们提供了一个有效的方法来提高读写效率。在读取输入数据之前，我们需要预先对原始文本进行转换，通过Hadoop 序列化IO 接口的序列化功能将其转换成二进制镜像文件形式，这样每次X-RIME 读取被序列化产生的二进制文件的时候可以直接通过Hadoop 序列化IO 接口的反序列化功能将镜像文件装载到内存里，输出的时候直接通过Hadoop IO 的序列化功能进行输出，效率大大提高。两种读写方式的示意图如图4 所示。</p>
<div id="attachment_1167" class="wp-caption aligncenter" style="width: 424px"><a href="http://farm8.staticflickr.com/7149/6821014255_ecaa8f1d4d.jpg"><img class="size-full wp-image-1167 " title="两种输入输出方式（左：较为低效的传统方式，右：高效的序列化方式）" src="http://www.parallellabs.com/wp-content/uploads/2012/01/两种输入输出方式（左：较为低效的传统方式，右：高效的序列化方式）.bmp" alt="两种输入输出方式（左：较为低效的传统方式，右：高效的序列化方式）" width="414" height="345" /></a><p class="wp-caption-text">图4. 两种输入输出方式（左：较为低效的传统方式，右：高效的序列化方式）</p></div>
<h1>3. X-RIME使用介绍</h1>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>使用X-RIME大致可以分为四步。第一步：获取原始数据，例如使用爬虫获取原始网站数据。第二步：对数据进行预处理以转化成X-RIME数据模型所支持的格式。这个步骤与用户提供的具体数据格式相关，因而通常由X-RIME用户自己实现。第三步：调用X-RIME算法库对这些数据进行社交网络分析。第四步：对X-RIME的输出结果进行整合，生成易于理解的文档。</p>
<p>下面我们来介绍下使用X-RIME对某BBS中一个分论坛进行弱连通分支（Weakly Connected Components，后面简称WCC）算法分析的结果。在BBS中，每一个帖子的发起者A是一个节点，而如果另一个用户B回复了这个帖子，我们说这两个用户间形成了一个关系，即B指向了A。</p>
<div class="mceTemp mceIEcenter" style="text-align: center;">
<dl id="attachment_1169" class="wp-caption aligncenter" style="width: 512px;">
<dt class="wp-caption-dt"><a href="http://farm8.staticflickr.com/7171/6821016923_78c7a4859a.jpg"><img class="size-full wp-image-1169 " title="弱连通分布" src="http://www.parallellabs.com/wp-content/uploads/2012/01/弱连通分布.bmp" alt="弱连通分布" width="502" height="381" /></a></dt>
<dd class="wp-caption-dd">图5. 弱连通分布</dd>
</dl>
</div>
<p>图5中的蓝红紫三条线分别代表该BBS中MilitaryView版， Circuit版和Career_POST版的WCC分布情况。从图中我们可以看到，MilitaryView版和Circuit版中大部分的用户的WCC值都很高。这说明这两个版块中的大部分用户彼此都直接或者间接的联系在一起。相反的，Career_POST版中大部分的用户彼此间的联系都非常松散。其实这个结果非常易于理解，因为MilitaryView和Circuit版是专门的版块，在这个版块的用户大都是基于相同的兴趣而产生的发帖、回帖行为，因此彼此间的互动更频繁、联系更紧密；相对的，Career_POST版主要被用于发布和浏览招聘信息，因此用户的回帖行为不多，用户间的关联性不强。</p>
<h1>4. 总结</h1>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>X-RIME作为基于Hadoop的开源工具，为大家提供了一种方便快捷地进行大规模社交网络分析的新选择。如果您对X-RIME有什么新的需求或者建议，欢迎您直接与我们联系：chengc@cn.ibm.com。</p>
<h1>参考文献</h1>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>[1] X-RIME Homepage: http://xrime.sourceforge.net/</p>
<p>[2] Wei Xue, JuWei Shi, Bo Yang. X-RIME: Cloud-Based Large Scale Social Network Analysis. Proceedings of 2010 IEEE International Conference on Services Computing.</p>
<p>[3] Kai Shuang, Yin Yang, Bin Cai, Zhe Xiang. X-RIME: HADOOP-BASED LARGE-SCALE SOCIAL NETWORK ANALYSIS. Proceedings of IC-BNMT2010.</p>
<p>[4] 杨寅.大规模社会网络分析数据模型的设计与实现. 中国科技论文在线.</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=X-RIME%3A+%E5%9F%BA%E4%BA%8EHadoop%E7%9A%84%E5%BC%80%E6%BA%90%E5%A4%A7%E8%A7%84%E6%A8%A1%E7%A4%BE%E4%BA%A4%E7%BD%91%E7%BB%9C%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2012%2F01%2F09%2Fxrime%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=X-RIME%3A+%E5%9F%BA%E4%BA%8EHadoop%E7%9A%84%E5%BC%80%E6%BA%90%E5%A4%A7%E8%A7%84%E6%A8%A1%E7%A4%BE%E4%BA%A4%E7%BD%91%E7%BB%9C%E5%88%86%E6%9E%90%E5%B7%A5%E5%85%B7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2012%2F01%2F09%2Fxrime%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>09/22/2011 -- <a href="http://www.parallellabs.com/2011/09/22/internship-on-hadoop/" title="[已经招到了，谢谢大家！]IBM中国研究院招聘Hadoop实习生">[已经招到了，谢谢大家！]IBM中国研究院招聘Hadoop实习生</a></li><li>09/02/2011 -- <a href="http://www.parallellabs.com/2011/09/02/ibm-research-china-internship/" title="IBM中国研究院招聘大规模数据分析实习生">IBM中国研究院招聘大规模数据分析实习生</a></li><li>07/17/2011 -- <a href="http://www.parallellabs.com/2011/07/17/realtime-apache-hadoop-at-facebook/" title="Facebook的Realtime Hadoop及其应用">Facebook的Realtime Hadoop及其应用</a></li><li>12/28/2010 -- <a href="http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices/" title="移动设备进入多核时代！">移动设备进入多核时代！</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2012/01/09/xrime/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>并行编程中的“锁”难题</title>
		<link>http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/</link>
		<comments>http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/#comments</comments>
		<pubDate>Sun, 02 Oct 2011 02:11:14 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[多线程编程]]></category>
		<category><![CDATA[死锁]]></category>
		<category><![CDATA[线程同步]]></category>
		<category><![CDATA[锁竞争]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=1102</guid>
		<description><![CDATA[<em>注：本文发表于《程序员》2011年第8期并行编程专栏，略有删改。</em>

在并行程序中，锁的使用会主要会引发两类难题：一类是诸如死锁、活锁等引起的多线程Bug；另一类是由锁竞争引起的性能瓶颈。本文将介绍并行编程中因为锁引发的这两类难题及其解决方案。

<p><a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" >阅读全文>></a> </p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E4%B8%AD%E7%9A%84%E2%80%9C%E9%94%81%E2%80%9D%E9%9A%BE%E9%A2%98&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F10%2F02%2Flock-in-parallel-programming%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E4%B8%AD%E7%9A%84%E2%80%9C%E9%94%81%E2%80%9D%E9%9A%BE%E9%A2%98&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F10%2F02%2Flock-in-parallel-programming%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p><em>注：本文发表于《程序员》2011年第8期并行编程专栏，略有删改。</em></p>
<p>在并行程序中，锁的使用会主要会引发两类难题：一类是诸如死锁、活锁等引起的多线程Bug；另一类是由锁竞争引起的性能瓶颈。本文将介绍并行编程中因为锁引发的这两类难题及其解决方案。</p>
<h2>1. 用锁来防止数据竞跑</h2>
<p>在进行并行编程时，我们常常需要使用锁来保护共享变量，以防止多个线程同时对该变量进行更新时产生数据竞跑（Data Race）。所谓数据竞跑，是指当两个（或多个）线程同时对某个共享变量进行操作，且这些操作中至少有一个是写操作时所造成的程序错误。例1中的两个线程可能同时执行“counter++”从而产生数据竞跑，造成counter最终值为1（而不是正确值2）。<br />
例1：</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;pthread.h&gt;
int counter = 0;
void *func(void *params)
{
    counter++; //数据竞跑
}
void main()
{
    pthread_t thread1, thread2;
    pthread_create(&amp;thread1, 0, func, 0);
    pthread_create(&amp;thread2, 0, func, 0);
    pthread_join(thread1, 0 );
    pthread_join(thread2, 0 );
}
</pre>
<p>这是因为counter++本身是由三条汇编指令构成的（从主存中将counter的值读到寄存器中；对寄存器进行加1操作；将寄存器中的新值写回主存），所以例1中的两个线程可能按如下交错顺序执行，导致counter的最终值为1：<br />
例2：</p>
<pre class="brush: cpp; title: ; notranslate">
load [%counter], rax; // 线程1从counter读取0到寄存器rax
add rax, 1; // 线程1对寄存器rax进行加1
load [%counter], rbx; // 线程2从counter读取0到寄存器rbx
store rax [%counter]; // 线程1把1写入counter的主存地址
add rbx, 1; // 线程2对寄存器rbx进行加1
store rbx, [%counter]; // 线程2把1写入counter的主存地址
</pre>
<p>为了防止例1中的数据竞跑现象，我们可以使用锁来保证每个线程对counter++操作的独占访问（即保证该操作是原子的）。在例3的程序中，我们使用mutex锁将counter++操作放入临界区中，这样同一时刻只有获取锁的线程能访问该临界区，保证了counter++的原子性：即只有在线程1执行完counter++的三条指令之后线程2才能执行counter++操作，保证了counter的最终值必定为2。<br />
例3：</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;pthread.h&gt;
int counter = 0;
pthread_mutex_t mutex;
void *func(void *params)
{
    pthread_mutex_lock(&amp;mutex);
    counter++; //处于临界区，不会产生数据竞跑
    pthread_mutex_unlock(&amp;mutex);
}
void main()
{
    pthread_t thread1, thread2;
    pthread_mutex_init(&amp;mutex);
    pthread_create(&amp;thread1, 0, func, 0);
    pthread_create(&amp;thread2, 0, func, 0);
    pthread_join(thread1, 0 );
    pthread_join(thread2, 0 );
    pthread_mutex_destroy(&amp;mutex);
}
</pre>
<h2>2. 死锁和活锁</h2>
<p>然而，锁的使用非常容易导致多线程Bug，最常见的莫过于死锁和活锁。从原理上讲，死锁的产生是由于两个（或多个）线程在试图获取正被其他线程占有的资源时造成的线程停滞。在下例中，假设线程1在获取mutex_a锁之后正在尝试获取mutex_b锁，而线程2此时已经获取了mutex_b锁并正在尝试获取mutex_a锁，两个线程就会因为获取不到自己想要的资源、且自己正占有着对方想要的资源而停滞，从而产生死锁。<br />
例4：</p>
<pre class="brush: cpp; title: ; notranslate">
// 线程 1
void func1()
{
    LOCK(&amp;mutex_a);
    LOCK(&amp;mutex_b);//线程1停滞在此
    counter++;
    UNLOCK(&amp;mutex_b);
    UNLOCK(&amp;mutex_a);
} 						

// 线程 2
void func2()
{
    LOCK(&amp;mutex_b);
    LOCK(&amp;mutex_a);//线程2停滞在此
    counter++;
    UNLOCK(&amp;mutex_a);
    UNLOCK(&amp;mutex_b);
}
</pre>
<p>例4中的死锁其实是最简单的情形，在实际的程序中，死锁往往发生在复杂的函数调用过程中。在下面这个例子中，线程1在func1()中获取了mutex_a锁，之后调用func_call1()并在其函数体中尝试获取mutex_b锁；与此同时线程2在func2()中获取了mutex_b锁之后再在func_call2()中尝试获取mutex_a锁从而造成死锁。可以想象，随着程序复杂度的增加，想要正确的检测出死锁会变得越来越困难。<br />
例5：</p>
<pre class="brush: cpp; title: ; notranslate">
// 线程 1
void func1()
{
LOCK(&amp;mutex_a);
...
func_call1();
UNLOCK(&amp;mutex_a);
}						

func_call1()
{
   LOCK(&amp;mutex_b);
   ...
   UNLOCK(&amp;mutex_b);
   ...
}						

// 线程 2
void func2()
{
    LOCK(&amp;mutex_b);
    ...
    func_call2()
    UNLOCK(&amp;mutex_b);
}

func_call2()
{
    LOCK(&amp;mutex_a);
    ...
    UNLOCK(&amp;mutex_b);
    ...
}
</pre>
<p>其实避免死锁的方法非常简单，其基本原则就是保证各个线程加锁操作的执行顺序是全局一致的。例如，如果上例中的线程1和线程2都是先对mutex_a加锁再对mutex_b进行加锁就不会产生死锁了。在实际的软件开发中，除了严格遵守相同加锁顺序的原则防止死锁之外，我们还可以使用RAII（Resource Acquisition Is Initialization，即“资源获取即初始化”）的手段来封装加锁解锁操作，从而帮助减少死锁的发生[1]。</p>
<p>除死锁外，多个线程的加锁、解锁操作还可能造成活锁。在下例中，程序员为了防止死锁的产生而做了如下处理：当线程1在获取了mutex_a锁之后再尝试获取mutex_b时，线程1通过调用一个非阻塞的加锁操作（类似pthread_mutex_trylock）来尝试进行获得mutex_b：如果线程1成功获得mutex_b，则trylock()加锁成功并返回true，如果失败则返回false。线程2也使用了类似的方法来保证不会出现死锁。不幸的是，这种方法虽然防止了死锁的产生，却可能造成活锁。例如，在线程1获得mutex_a锁之后尝试获取mutex_b失败，则线程1会释放mutex_a并进入下一次while循环；如果此时线程2在线程1进行TRYLOCK(&#038;mutex_b)的同时执行TRYLOCK(&#038;mutex_a)，那么线程2也会获取mutex_a失败，并接着释放mutex_b及进入下一次while循环；如此反复，两个线程都可能在较长时间内不停的进行“获得一把锁、尝试获取另一把锁失败、再解锁之前已获得的锁“的循环，从而产生活锁现象。当然，在实际情况中，因为多个线程之间调度的不确定性，最终必定会有一个线程能同时获得两个锁，从而结束活锁。尽管如此，活锁现象确实会产生不必要的性能延迟，所以需要大家格外注意。<br />
例6：</p>
<pre class="brush: cpp; title: ; notranslate">
// 线程 1
void func1()
{
    int done = 0;
    while(!done) {
        LOCK(&amp;mutex_a);
        if (TRYLOCK(&amp;mutex_b)) {
            counter++;
            UNLOCK(&amp;mutex_b);
            UNLOCK(&amp;mutex_a);
            done = 1;
        }
        else {
            UNLOCK(&amp;mutex_a);
        }
    }
} 						

// 线程 2
void func2()
{
    int done = 0;
    while(!done) {
        LOCK(&amp;mutex_b);
        if (TRYLOCK(&amp;mutex_a)) {
            counter++;
            UNLOCK(&amp;mutex_a);
            UNLOCK(&amp;mutex_b);
            done = 1;
        }
        else {
            UNLOCK(&amp;mutex_b);
        }
    }
}
</pre>
<h2>3. 锁竞争性能瓶颈</h2>
<p>在多线程程序中锁竞争是最主要的性能瓶颈之一。在前面我们也提到过，通过使用锁来保护共享变量能防止数据竞跑，保证同一时刻只能有一个线程访问该临界区。但是我们也注意到，正是因为锁造成的对临界区的串行执行导致了并行程序的性能瓶颈。</p>
<h3>3.1阿姆达尔法则（Amdahl’s Law）</h3>
<p>在介绍锁竞争引起的性能瓶颈之前，让我们先来了解一下阿姆达尔法则。我们知道，一个并行程序是由两部分组成的：串行执行的部分和可以并行执行的部分。假设串行部分的执行时间为S，可并行执行部分的执行时间为P，则整个并行程序使用单线程（单核）串行执行的时间为S+P。阿姆达尔法则规定，可并行执行部分的执行时间与线程数目成反比：即如果有N个线程（N核CPU）并行执行这个可并行的部分，则该部分的执行时间为P/N。由此我们可以得到并行程序总体执行时间的公式：</p>
<pre class="brush: cpp; title: ; notranslate">
总体执行时间T = S + P/N
</pre>
<p>根据这个公式，我们可以得到一些非常有意思的结论。例如，如果一个程序全部代码都可以被并行执行，那么它的加速比会非常好，即随着线程数（CPU核数）的增多该程序的加速比会线性递增。换句话说，如果单线程执行该程序需要16秒钟，用16个线程执行该程序就只需要1秒钟。<br />
然而，如果这个程序只有80%的代码可以被并行执行，它的加速比却会急剧下降。根据阿姆达尔法则，如果用16个线程并行执行次程序可并行的部分，该程序的总体执行时间T = S + P/N = (16*0.2) + (16*0.8)/16 = 4秒，这比完全并行化的情况（只需1秒）足足慢了4倍！实际上，如果该程序只有50%的代码可以被并行执行，在使用16个线程时该程序的执行时间仍然需要8.5秒！<br />
从阿姆达尔法则我们可以看到，并行程序的性能很大程度上被只能串行执行的部分给限制住了，而由锁竞争引起的串行执行正是造成串行性能瓶颈的主要原因之一。</p>
<h3>3.2锁竞争的常用解决办法</h3>
<h4>3.2.1 避免使用锁</h4>
<p>为了提高程序的并行性，最好的办法自然是不使用锁。从设计角度上来讲，锁的使用无非是为了保护共享资源。如果我们可以避免使用共享资源的话那自然就避免了锁竞争造成的性能损失。幸运的是，在很多情况下我们都可以通过资源复制的方法让每个线程都拥有一份该资源的副本，从而避免资源的共享。如果有需要的话，我们也可以让每个线程先访问自己的资源副本，只在程序的后讲各个线程的资源副本合并成一个共享资源。例如，如果我们需要在多线程程序中使用计数器，那么我们可以让每个线程先维护一个自己的计数器，只在程序的最后将各个计数器两两归并（类比二叉树），从而最大程度提高并行度，减少锁竞争。</p>
<h4>3.2.2 使用读写锁</h4>
<p>如果对共享资源的访问多数为读操作，少数为写操作，而且写操作的时间非常短，我们就可以考虑使用读写锁来减少锁竞争。读写锁的基本原则是同一时刻多个读线程可以同时拥有读者锁并进行读操作；另一方面，同一时刻只有一个写进程可以拥有写者锁并进行写操作。读者锁和写者锁各自维护一份等待队列。当拥有写者锁的写进程释放写者锁时，所有正处于读者锁等待队列里的读线程全部被唤醒并被授予读者锁以进行读操作；当这些读线程完成读操作并释放读者锁时，写者锁中的第一个写进程被唤醒并被授予写者锁以进行写操作，如此反复。换句话说，多个读线程和一个写线程将交替拥有读写锁以完成相应操作。这里需要额外补充的一点是锁的公平调度问题。例如，如果在写者锁等待队列中有一个或多个写线程正在等待获得写者锁时，新加入的读线程会被放入读者锁的等待队列。这是因为，尽管这个新加入的读线程能与正在进行读操作的那些读线程并发读取共享资源，但是也不能赋予他们读权限，这样就防止了写线程被新到来的读线程无休止的阻塞。<br />
需要注意的是，并不是所有的场合读写锁都具备更好的性能，大家应该根据Profling的测试结果来判断使用读写锁是否能真的提高性能，特别是要注意写操作虽然很少但很耗时的情况。</p>
<h4>3.2.3 保护数据而不是操作</h4>
<p>在实际程序中，有不少程序员在使用锁时图方便而把一些不必要的操作放在临界区中。例如，如果需要对一个共享数据结构进行删除和销毁操作，我们只需要把删除操作放在临界区中即可，资源销毁操作完全可以在临界区之外单独进行，以此增加并行度。<br />
正是因为临界区的执行时间大大影响了并行程序的整体性能，我们必须尽量少在临界区中做耗时的操作，例如函数调用，数据查询，I/O操作等。简而言之，我们需要保护的只是那些共享资源，而不是对这些共享资源的操作，尽可能的把对共享资源的操作放到临界区之外执行有助于减少锁竞争带来的性能损失。</p>
<h4>3.2.4 尽量使用轻量级的原子操作</h4>
<p>在例3中，我们使用了mutex锁来保护counter++操作。实际上，counter++操作完全可以使用更轻量级的原子操作来实现，根本不需要使用mutex锁这样相对较昂贵的机制来实现。在今年程序员第四期的《volatile与多线程的那些事儿》中我们就有对Java和C/C++中的原子操作做过相应的介绍。</p>
<h4>3.2.5 粗粒度锁与细粒度锁</h4>
<p>为了减少串行部分的执行时间，我们可以通过把单个锁拆成多个锁的办法来较小临界区的执行时间，从而降低锁竞争的性能损耗，即把“粗粒度锁”转换成“细粒度锁”。但是，细粒度锁并不一定更好。这是因为粗粒度锁编程简单，不易出现死锁等Bug，而细粒度锁编程复杂，容易出错；而且锁的使用是有开销的（例如一个加锁操作一般需要100个CPU时钟周期），使用多个细粒度的锁无疑会增加加锁解锁操作的开销。在实际编程中，我们往往需要从编程复杂度、性能等多个方面来权衡自己的设计方案。事实上，在计算机系统设计领域，没有哪种设计是没有缺点的，只有仔细权衡不同方案的利弊才能得到最适合自己当前需求的解决办法。例如，Linux内核在初期使用了Big Kernel Lock（粗粒度锁）来实现并行化。从性能上来讲，使用一个大锁把所有操作都保护起来无疑带来了很大的性能损失，但是它却极大的简化了并行整个内核的难度。当然，随着Linux内核的发展，Big Kernel Lock已经逐渐消失并被细粒度锁而取代，以取得更好的性能。</p>
<h4>3.2.6 使用无锁算法、数据结构</h4>
<p>首先要强调的是，笔者并不推荐大家自己去实现无锁算法。为什么别去造无锁算法的轮子呢？因为高性能无锁算法的正确实现实在是太难了。有多难呢？Doug Lea提到java.util.concurrent库中一个Non Blocking的算法的实现大概需要1个人年，总共约500行代码。事实上，我推荐大家直接去使用一些并行库中已经实现好了的无锁算法、无锁数据结构，以提高并行程序的性能。典型的无锁算法的库有java.util.concurrent，Intel TBB等，它们都提供了诸如Non-blocking concurrent queue之类的数据结构以供使用。</p>
<h3>参考</h3>
<p>[1] 陈硕.<a href="http://blog.csdn.net/solstice/article/details/5307710">多线程服务器的常用编程模型. </a><br />
[2]  Darryl Gove.<a href="http://book.douban.com/subject/5366276/"> Multicore Application Programming</a><br />
[3]  并行实验室. <a href="http://www.parallellabs.com/2010/10/25/practical-concurrent-queue-algorithm/">多线程队列的算法优化. </a></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E4%B8%AD%E7%9A%84%E2%80%9C%E9%94%81%E2%80%9D%E9%9A%BE%E9%A2%98&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F10%2F02%2Flock-in-parallel-programming%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E4%B8%AD%E7%9A%84%E2%80%9C%E9%94%81%E2%80%9D%E9%9A%BE%E9%A2%98&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F10%2F02%2Flock-in-parallel-programming%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>11/13/2010 -- <a href="http://www.parallellabs.com/2010/11/13/concurrency-bugs-1/" title="多线程程序常见Bug剖析（上）">多线程程序常见Bug剖析（上）</a></li><li>01/31/2010 -- <a href="http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/" title="Pthreads并行编程之spin lock与mutex性能对比分析">Pthreads并行编程之spin lock与mutex性能对比分析</a></li><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>08/27/2011 -- <a href="http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/" title="浅析C++多线程内存模型 ">浅析C++多线程内存模型 </a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>[已经招到了，谢谢大家！]IBM中国研究院招聘Hadoop实习生</title>
		<link>http://www.parallellabs.com/2011/09/22/internship-on-hadoop/</link>
		<comments>http://www.parallellabs.com/2011/09/22/internship-on-hadoop/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 03:07:09 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[职业生涯]]></category>
		<category><![CDATA[ibm]]></category>
		<category><![CDATA[实习]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=1098</guid>
		<description><![CDATA[我们组最近有一个实习生的名额，做Hadoop性能优化相关的研究工作，如果大家感兴趣的话请给我发邮件:)

IBM Research China is looking for graduate computer science/engineering students who are interested in Hadoop performance optimizations works.

Location: Beijing
Job Tile: Research Intern
Job Openings: 1
Expected Duration: at least 3 months (full-time preferred)

Job responsibilities:
- Write MapReduce program and analyze Hadoop performance model.
- Tune and optimize the performance of Hadoop workloads.
- Publish high quality research papers to report your work.

Requirements:
- Creative and Self-motivated
- Knowledge of Parallel Computing and Distributed Systems.
- Knowledge of Java.
- Familiarity with Linux as development and testing environments.
- Knowledge of Apache Hadoop is a plus.
- Past research experience is a plus.

<strong>If you're interested, please feel free to send your Chinese or English resume with the mail title of "Intern_Your Name_University_Major_Grade" (e.g. Intern_Zhang San_XXU_CS_Master) to chengc_at_cn.ibm.com.</strong>

<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%5B%E5%B7%B2%E7%BB%8F%E6%8B%9B%E5%88%B0%E4%BA%86%EF%BC%8C%E8%B0%A2%E8%B0%A2%E5%A4%A7%E5%AE%B6%EF%BC%81%5DIBM%E4%B8%AD%E5%9B%BD%E7%A0%94%E7%A9%B6%E9%99%A2%E6%8B%9B%E8%81%98Hadoop%E5%AE%9E%E4%B9%A0%E7%94%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F09%2F22%2Finternship-on-hadoop%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%5B%E5%B7%B2%E7%BB%8F%E6%8B%9B%E5%88%B0%E4%BA%86%EF%BC%8C%E8%B0%A2%E8%B0%A2%E5%A4%A7%E5%AE%B6%EF%BC%81%5DIBM%E4%B8%AD%E5%9B%BD%E7%A0%94%E7%A9%B6%E9%99%A2%E6%8B%9B%E8%81%98Hadoop%E5%AE%9E%E4%B9%A0%E7%94%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F09%2F22%2Finternship-on-hadoop%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>我们组最近有一个实习生的名额，做Hadoop性能优化相关的研究工作，如果大家感兴趣的话请给我发邮件:)</p>
<p>IBM Research China is looking for graduate computer science/engineering students who are interested in Hadoop performance optimizations works.</p>
<p>Location: Beijing<br />
Job Tile: Research Intern<br />
Job Openings: 1<br />
Expected Duration: at least 3 months (full-time preferred)</p>
<p>Job responsibilities:<br />
- Write MapReduce program and analyze Hadoop performance model.<br />
- Tune and optimize the performance of Hadoop workloads.<br />
- Publish high quality research papers to report your work.</p>
<p>Requirements:<br />
- Creative and Self-motivated<br />
- Knowledge of Parallel Computing and Distributed Systems.<br />
- Knowledge of Java.<br />
- Familiarity with Linux as development and testing environments.<br />
- Knowledge of Apache Hadoop is a plus.<br />
- Past research experience is a plus.</p>
<p><strong>If you&#8217;re interested, please feel free to send your Chinese or English resume with the mail title of “Intern_Your Name_University_Major_Grade” (e.g. Intern_Zhang San_XXU_CS_Master) to chengc_at_cn.ibm.com.</strong></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%5B%E5%B7%B2%E7%BB%8F%E6%8B%9B%E5%88%B0%E4%BA%86%EF%BC%8C%E8%B0%A2%E8%B0%A2%E5%A4%A7%E5%AE%B6%EF%BC%81%5DIBM%E4%B8%AD%E5%9B%BD%E7%A0%94%E7%A9%B6%E9%99%A2%E6%8B%9B%E8%81%98Hadoop%E5%AE%9E%E4%B9%A0%E7%94%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F09%2F22%2Finternship-on-hadoop%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%5B%E5%B7%B2%E7%BB%8F%E6%8B%9B%E5%88%B0%E4%BA%86%EF%BC%8C%E8%B0%A2%E8%B0%A2%E5%A4%A7%E5%AE%B6%EF%BC%81%5DIBM%E4%B8%AD%E5%9B%BD%E7%A0%94%E7%A9%B6%E9%99%A2%E6%8B%9B%E8%81%98Hadoop%E5%AE%9E%E4%B9%A0%E7%94%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F09%2F22%2Finternship-on-hadoop%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/09/2012 -- <a href="http://www.parallellabs.com/2012/01/09/xrime/" title="X-RIME: 基于Hadoop的开源大规模社交网络分析工具">X-RIME: 基于Hadoop的开源大规模社交网络分析工具</a></li><li>09/02/2011 -- <a href="http://www.parallellabs.com/2011/09/02/ibm-research-china-internship/" title="IBM中国研究院招聘大规模数据分析实习生">IBM中国研究院招聘大规模数据分析实习生</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2011/09/22/internship-on-hadoop/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>IBM中国研究院招聘大规模数据分析实习生</title>
		<link>http://www.parallellabs.com/2011/09/02/ibm-research-china-internship/</link>
		<comments>http://www.parallellabs.com/2011/09/02/ibm-research-china-internship/#comments</comments>
		<pubDate>Thu, 01 Sep 2011 16:22:04 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[职业生涯]]></category>
		<category><![CDATA[ibm]]></category>
		<category><![CDATA[internship]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=1094</guid>
		<description><![CDATA[帮同事发文，招聘实习生： IBM Research China is looking for undergraduate and graduate computer science/engineering students who are interested in Big Data Analytics development and performance optimizations works. Location: Beijing Job Tile: Research Intern Job Openings: 1-2 Expected Duration: at least 3 months (full time) Job responsibilities: - Develop text mining solutions such as Topic Detection and Tracking [...]
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=IBM%E4%B8%AD%E5%9B%BD%E7%A0%94%E7%A9%B6%E9%99%A2%E6%8B%9B%E8%81%98%E5%A4%A7%E8%A7%84%E6%A8%A1%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%AE%9E%E4%B9%A0%E7%94%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F09%2F02%2Fibm-research-china-internship%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=IBM%E4%B8%AD%E5%9B%BD%E7%A0%94%E7%A9%B6%E9%99%A2%E6%8B%9B%E8%81%98%E5%A4%A7%E8%A7%84%E6%A8%A1%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%AE%9E%E4%B9%A0%E7%94%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F09%2F02%2Fibm-research-china-internship%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>帮同事发文，招聘实习生：</p>
<p>IBM Research China is looking for undergraduate and graduate computer science/engineering students who are interested in Big Data Analytics development and performance optimizations works. </p>
<p>Location: Beijing<br />
Job Tile: Research Intern<br />
Job Openings: 1-2<br />
Expected Duration: at least 3 months (full time)</p>
<p>Job responsibilities:<br />
- Develop text mining solutions such as Topic Detection and Tracking (TDT).<br />
- Write Apache MapReduce user function code to implement Social Network Analysis (SNA), Machine Learning and Text Mining algorithms.<br />
- Tune and optimize the performance of Apache MapReduce/HDFS based analytics workload on POWER7.<br />
- Publish high quality research papers to report your work. </p>
<p>Required skills:<br />
- Knowledge of 1) Parallel Computing and Distributed Systems or 2) Machine Learning and Data Mining<br />
- Knowledge of Java<br />
- Familiarity with Linux as development and testing environments.<br />
- Experience of Apache Hadoop will be a plus. </p>
<p>We also encourage exceptional students to generate and implement their own ideas about Big Data Analytics related works over the course of internship. </p>
<p>If you&#8217;re interested, please feel free to drop us an email to jwshi_at_cn.ibm.com with your resume. </p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=IBM%E4%B8%AD%E5%9B%BD%E7%A0%94%E7%A9%B6%E9%99%A2%E6%8B%9B%E8%81%98%E5%A4%A7%E8%A7%84%E6%A8%A1%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%AE%9E%E4%B9%A0%E7%94%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F09%2F02%2Fibm-research-china-internship%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=IBM%E4%B8%AD%E5%9B%BD%E7%A0%94%E7%A9%B6%E9%99%A2%E6%8B%9B%E8%81%98%E5%A4%A7%E8%A7%84%E6%A8%A1%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E5%AE%9E%E4%B9%A0%E7%94%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F09%2F02%2Fibm-research-china-internship%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/09/2012 -- <a href="http://www.parallellabs.com/2012/01/09/xrime/" title="X-RIME: 基于Hadoop的开源大规模社交网络分析工具">X-RIME: 基于Hadoop的开源大规模社交网络分析工具</a></li><li>09/22/2011 -- <a href="http://www.parallellabs.com/2011/09/22/internship-on-hadoop/" title="[已经招到了，谢谢大家！]IBM中国研究院招聘Hadoop实习生">[已经招到了，谢谢大家！]IBM中国研究院招聘Hadoop实习生</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2011/09/02/ibm-research-china-internship/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>浅析C++多线程内存模型</title>
		<link>http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/</link>
		<comments>http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/#comments</comments>
		<pubDate>Sat, 27 Aug 2011 03:39:47 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[C++1x]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[多线程内存模型]]></category>
		<category><![CDATA[多线程编程]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=1085</guid>
		<description><![CDATA[<em>注：本文发表于《程序员》2011年第6期并行编程专栏，略有删改。</em>

在即将到来的C++1x标准中，一个重大的更新就是引入了C++多线程内存模型。本文的主要目的在于介绍C++多线程内存模型涉及到的一些原理和概念，以帮助大家理解C++多线程内存模型的作用和意义。

<a href="http://www.parallellabs.com/?p=1085">阅读全文>></a> 
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E6%B5%85%E6%9E%90C%2B%2B%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F08%2F27%2Fc-plus-plus-memory-model%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E6%B5%85%E6%9E%90C%2B%2B%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F08%2F27%2Fc-plus-plus-memory-model%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p><em>注：本文发表于《程序员》2011年第6期并行编程专栏，略有删改。</em></p>
<p>在即将到来的C++1x标准中，一个重大的更新就是引入了C++多线程内存模型。本文的主要目的在于介绍C++多线程内存模型涉及到的一些原理和概念，以帮助大家理解C++多线程内存模型的作用和意义。</p>
<h4>1. 顺序一致性模型（Sequential Consistency）</h4>
<p>在介绍C++多线程模型之前，让我们先介绍一下最基本的顺序一致性模型。对多线程程序来说，最直观，最容易被理解的执行方式就是顺序一致性模型。顺序一致性的提出者Lamport给出的定义是：<br />
“… the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program.”<br />
从这个定义中我们可以看出，顺序一致性主要约定了两件事情：<br />
（1）从单个线程的角度来看，每个线程内部的指令都是按照程序规定的顺序（program order）来执行的；<br />
（2）从整个多线程程序的角度来看，整个多线程程序的执行顺序是按照某种交错顺序来执行的，且是全局一致的；</p>
<p>下面我们通过一个例子来理解顺序一致性。假设我们有两个线程（线程1和线程2），它们分别运行在两个CPU核上，有两个初始值为0的全局共享变量x和y，两个线程分别执行下面两条指令：<br />
初始条件： x = y = 0;</p>
<table style="font-size: 1em; line-height: inherit; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="3" width="100%" bordercolor="#000000">
<tbody>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%"><em>线程 1</em></td>
<td style="text-align: center;" width="50%"><em>线程 2</em></td>
</tr>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%">x = 1;</td>
<td style="text-align: center;" width="50%">y=1;</td>
</tr>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%">r1 = y;</td>
<td style="text-align: center;" width="50%">r2 = x;</td>
</tr>
</tbody>
</table>
<p>因为多线程程序交错执行的顺序是不确定的，所以该程序可能有如下几种执行顺序：</p>
<table style="font-size: 1em; line-height: inherit; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="3" width="100%" bordercolor="#000000">
<tbody></tbody>
</table>
<table style="font-size: 1em; line-height: inherit; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="3" width="100%" bordercolor="#000000">
<tbody>
<tr style="text-align: left;">
<td style="text-align: center;" width="33.333333333333336%">顺序 1</td>
<td style="text-align: center;" width="33.333333333333336%">顺序 2</td>
<td style="text-align: center;" width="33.333333333333336%">顺序 3</td>
</tr>
<tr style="text-align: left;">
<td width="33.333333333333336%">
<div style="margin-top: 0px; margin-bottom: 0px;">x = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r1 = y;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">y = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r2 = x;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">结果:r1==0 and r2 == 1</div>
</td>
<td width="33.333333333333336%">
<div style="margin-top: 0px; margin-bottom: 0px;">y = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r2 = x;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">x = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r1 = y;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">结果: r1 == 1 and r2 == 0</div>
</td>
<td width="33.333333333333336%">
<div style="margin-top: 0px; margin-bottom: 0px;">x = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">y = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r1 = y;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r2 = x;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">结果: r1 == 1 and r2 == 1</div>
</td>
</tr>
</tbody>
</table>
<p>顺序一致性模型的第一个约定要求每个线程内部的语句都是按照程序规定的顺序执行，例如，线程1里面的两条语句在该线程中一定是x=1先执行，r1=y后执行。顺序一致性的第二个约定要求多线程程序按照某种顺序执行，且所有线程看见的整体执行顺序必须一致，即该多线程程序可以按照顺序1、顺序2或者顺序3（以及其他可能的执行顺序）执行，且线程1和线程2所观察到的整个程序的执行顺序是一致的（例如，如果线程1“看见”整个程序的执行顺序是顺序 1，那么线程2“看见”的整个程序的执行顺序也必须是顺序1，而不能是顺序2或者顺序3）。依照顺序一致性模型，虽然这个程序还可能按其他的交错顺序执行，但是r1和r2的值却只可能出现上面三种结果，而不可能出现r1和r2同时为0的情况。</p>
<p>然而，尽管顺序一致性模型非常易于理解，但是它却对CPU和编译器的性能优化做出了很大的限制，所以常见的多核CPU和编译器大都没有实现顺序一致性模型。例如，编译器可能会为了隐藏一部分读操作的延迟而做如下优化，把线程1中对y的读操作（即r1=y）调换到x=1之前执行：</p>
<p>初始条件：x=y=0;</p>
<table style="font-size: 1em; line-height: inherit; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="3" width="100%" bordercolor="#000000">
<tbody>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%"><em><span style="font-size: x-small;">线程 1</span></em></td>
<td style="text-align: center;" width="50%"><em><span style="font-size: x-small;">线程 2</span></em></td>
</tr>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%"><span style="font-size: x-small;">r1 = y;</span></td>
<td style="text-align: center;" width="50%"><span style="font-size: x-small;">y=1;</span></td>
</tr>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%"><span style="font-size: x-small;">x = 1;</span></td>
<td style="text-align: center;" width="50%"><span style="font-size: x-small;">r2 = x;</span></td>
</tr>
</tbody>
</table>
<p>在这种情况下，该程序如果按下面的顺序执行就可能就会出现r1和r2都为0这样的违反顺序一致性的结果：</p>
<table style="font-size: 1em; line-height: inherit; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="3" width="100%" bordercolor="#000000">
<tbody>
<tr style="text-align: left;">
<td style="text-align: center;" width="100%">顺序 4</td>
</tr>
<tr style="text-align: left;">
<td style="text-align: center;" width="100%">r1 = y;<br />
y = 1;<br />
r2 = x;<br />
x = 1;</td>
</tr>
</tbody>
</table>
<p>那么为什么编译器会做这样的乱序优化呢？因为读一个在内存中而不是在cache中的共享变量需要较长的时钟周期，所以编译器就“自作聪明”的让读操作先执行，从而隐藏掉一些指令执行的延迟，从而提高程序的性能。实际上，这种优化是串行时代非常普遍的，因为它对单线程程序的语义是没有影响的。但是在进入多核时代后，编译器缺少语言级的内存模型的约束，导致其可能做出违法顺序一致性规定的多线程语义的错误优化。同样的，多核CPU中的写缓冲区（store buffer）也可能实施乱序优化：它会把要写入内存的值先在缓冲区中缓存起来，以便让该写操作之后的指令先执行，进而出现违反顺序一致性的执行顺序。</p>
<p>因为现有的多核CPU和编译器都没有遵守顺序一致模型，而且C/C++的现有标准中都没有把多线程考虑在内，所以给编写多线程程序带来了一些问题。例如，为了正确地用C++实现Double-Checked Locking，我们需要使用非常底层的内存栅栏（Memory Barrier）指令来显式地规定代码的内存顺序性（memory ordering）[5]。然而，这种方案依赖于具体的硬件，因此可移植性很差；而且它过于底层，不方便使用。</p>
<h4>2. C++多线程内存模型</h4>
<p>为了更容易的进行多线程编程，程序员希望程序能按照顺序一致性模型执行；但是顺序一致性对性能的损失太大了，CPU和编译器为了提高性能就必须要做优化。为了在易编程性和性能间取得一个平衡，一个新的模型出炉了：sequential consistency for data race free programs，它就是即将到来的C++1x标准中多线程内存模型的基础。对C++程序员来说，随着C++1x标准的到来，我们终于可以依赖高级语言内建的多线程内存模型来编写正确的、高性能的多线程程序。</p>
<p>C++内存模型可以被看作是C++程序和计算机系统（包括编译器，多核CPU等可能对程序进行乱序优化的软硬件）之间的契约，它规定了多个线程访问同一个内存地址时的语义，以及某个线程对内存地址的更新何时能被其它线程看见。这个模型约定：没有数据竞跑的程序是遵循顺序一致性的。该模型的核心思想就是由程序员用同步原语（例如锁或者C++1x中新引入的atomic类型的共享变量）来保证你程序是没有数据竞跑的，这样CPU和编译器就会保证程序是按程序员所想的那样执行的（即顺序一致性）。换句话说，程序员只需要恰当地使用具有同步语义的指令来标记那些真正需要同步的变量和操作，就相当于告诉CPU和编译器不要对这些标记好的同步操作和变量做违反顺序一致性的优化，而其它未被标记的地方可以做原有的优化。编译器和CPU的大部分优化手段都可以继续实施，只是在同步原语处需要对优化做出相应的限制；而且程序员只需要保证正确地使用同步原语即可，因为它们最终表现出来的执行效果与顺序一致性模型一致。由此，C++多线程内存模型帮助我们在易编程性和性能之间取得了一个平衡。</p>
<p>在C++1x标准之前，C++是在建立在单线程语义上的。为了进行多线程编程，C++程序员通过使用诸如Pthreads，Windows Thread等C++语言标准之外的线程库来完成代码设计。以Pthreads为例，它提供了类似pthread_mutex_lock这样的函数来保证对共享变量的互斥访问，以防止数据竞跑。人们不禁会问，Pthreads这样的线程库我用的好好的，干嘛需要C++引入的多线程，这不是多此一举么？其实，以线程库的形式进行多线程编程在绝大多数应用场景下都是没有问题的。然而，线程库的解决方案也有其先天缺陷。第一，如果没有在编程语言中定义内存模型的话，我们就不能清楚的定义到底什么样的编译器/CPU优化是合法的，而程序员也不能确定程序到底会怎么样被优化执行。例如，Pthreads标准中并未对什么是数据竞跑（Data Race）做出精确定义，因此C++编译器可能会进行一些错误优化从而导致数据竞跑[3]。第二，绝大多数情况下线程库能正确的完成任务，而在极少数对性能有更高要求的情况下（尤其是需要利用底层的硬件特性来实现高性能Lock Free算法时）需要更精确的内存模型以规定好程序的行为。简而言之，把内存模型集成到编程语言中去是比线程库更好的选择。</p>
<h4>3. C++1x中引入的atomic类型</h4>
<p>C++作为一种高性能的系统语言，其设计目标之一就在于提供足够底层的操作，以满足对高性能的需求。在这个前提之下，C++1x除了提供传统的锁、条件变量等同步机制之外，还引入了新的atomic类型。相对于传统的mutex锁来说，atomic类型更底层，具备更好的性能，因此能用于实现诸如Lock Free等高性能并行算法。有了atomic类型，C++程序员就不需要像原来一样使用汇编代码来实现高性能的多线程程序了。而且，把atomic类型集成到C++语言中之后，程序员就可以更容易地实现可移植的多线程程序，而不用再依赖那些平台相关的汇编语句或者线程库。</p>
<p>对常见的数据类型，C++1x都提供了与之相对应的atomic类型。以bool类型举例，与之相对应的atomic_bool类型具备两个新属性：原子性与顺序性。顾名思义，原子性的意思是说atomic_bool的操作都是不可分割的，原子的；而顺序性则指定了对该变量的操作何时对其他线程可见。在C++1x中，为了满足对性能的追求，atomic类型提供了三种顺序属性：sequential consistency ordering（即顺序一致性），acquire release ordering以及relaxed ordering。因为sequential consistency是最易理解的模型，所以默认情况下所有atomic类型的操作都会使sequential consistency顺序。当然，顺序一致性的性能相对来说比较差，所以程序员还可以使用对顺序性要求稍弱一些的acquire release ordering与最弱的relaxed ordering。</p>
<p>在下面这个例子中，atomic_bool类型的变量data_ready就被用来实现两个线程间的同步操作。需要注意的是，对data_ready的写操作仍然可以通过直接使用赋值操作符（即“=”）来进行，但是对其的读操作就必须调用load()函数来进行。在默认的情况下，所有atomic类型变量的顺序性都是顺序一致性（即sequential consistency）。在这个例子中，因为data_ready的顺序性被规定为顺序一致性，所以线程1中对data_ready的写操作会与线程2中对data_ready的读操作构建起synchronize-with的同步关系，即#2->#3。又因为writer_thread()中的代码顺序规定了#1在#2之前发生，即#1->#2；而且reader_thread中的代码顺序规定了#3->#4，所以就有了#1->#2->#3->#4这样的顺序关系，从而可以保证在#4中读取data的值时，#1已经执行完毕，即#4一定能读到#1写入的值（10）。</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;atomic&gt;
#include &lt;vector&gt;
#include &lt;iostream&gt;

std::vector&lt;int&gt; data;
std::atomic_bool data_ready(false);

// 线程1
void writer_thread()
{
data.push_back(10); // #1：对data的写操作
data_ready = true; // #2：对data_ready的写操作
}

// 线程2
void reader_thread()
{
while(!data_ready.load()) // #3：对data_ready的读操作
{
std::this_thread::sleep(std::milliseconds(10));
}
std::cout &lt;&lt; ”data is ” &lt;&lt; data[0] &lt;&lt; ”\n”; // #4：对data的读操作
}
</pre>
<p>相信很多朋友会纳闷，这样的执行顺序不是显然的么？其实不然。如果我们把data_ready的顺序性制定为relaxed ordering的话，编译器和CPU就可以自由地做违反顺序一致性的乱序优化，从而导致#1不一定在#2之前被执行，最终导致#4中读到的data的值不为10。</p>
<p>简单的来说，在atomic类型提供的三种顺序属性中，acquire release ordering对顺序性的约束程度介于sequential consistency（顺序一致性）和relaxed ordering之间，因为它不要求全局一致性，但是具有synchronized with的关系。Relaxed ordering最弱，因为它对顺序性不做任何要求。由此可见，除非非常必要，我们一般不建议使用relaxed ordering，因为这不能保证任何顺序性。关于这三种属性更详细的信息大家可以参考[1]。</p>
<p>通过上面的例子我们可以看到，C++1x中的多线程内存模型为了通过atomic类型提供足够的灵活性和性能，最大限度地将底层细节（三种不同的顺序属性）暴露给了程序员。这样的设计原则一方面给程序员提供了实现高性能多线程算法的可能，但却也大大增加了使用上的难度。我个人的建议是，如果常规的mutex锁、条件变量、future信号能满足您的设计需求，那么您完全不需要使用atomic变量。如果您决定使用atomic变量，请尽量使用默认的顺序一致性属性。</p>
<h4>4. 总结</h4>
<p>本文对C++1x标准中新引入的多线程内存模型进行了简要介绍。C++1x多线程内存模型的引入使得广大C++程序员可以享受语言原生支持的多线程机制，并为实现高性能多线程算法提供了足够丰富的工具（例如atomic类型）。但是，多线程内存模型本身的复杂性，以及一些底层机制（例如不同的顺序性属性）的引入也给使用C++进行多线程编程带来了不小的复杂度。如何高效、可靠的利用好这些新引入的多线程机制将会成为一个新的挑战。</p>
<h4>参考资料</h4>
<p>[1] C++ Concurrency in Action<br />
[2] C++1x standard draft<br />
[3] Threads cannot be implemented as a library<br />
[4] Memory Models: A Case for Rethinking Parallel Languages and Hardware<br />
[5] The “Double-Checked Locking is Broken” Declaration</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E6%B5%85%E6%9E%90C%2B%2B%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F08%2F27%2Fc-plus-plus-memory-model%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E6%B5%85%E6%9E%90C%2B%2B%E5%A4%9A%E7%BA%BF%E7%A8%8B%E5%86%85%E5%AD%98%E6%A8%A1%E5%9E%8B&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F08%2F27%2Fc-plus-plus-memory-model%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>03/06/2010 -- <a href="http://www.parallellabs.com/2010/03/06/why-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence/" title="为什么程序员需要关心顺序一致性（Sequential Consistency）而不是Cache一致性（Cache Coherence？）">为什么程序员需要关心顺序一致性（Sequential Consistency）而不是Cache一致性（Cache Coherence？）</a></li><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li><li>04/15/2010 -- <a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/" title="多线程程序中操作的原子性">多线程程序中操作的原子性</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Facebook的Realtime Hadoop及其应用</title>
		<link>http://www.parallellabs.com/2011/07/17/realtime-apache-hadoop-at-facebook/</link>
		<comments>http://www.parallellabs.com/2011/07/17/realtime-apache-hadoop-at-facebook/#comments</comments>
		<pubDate>Sun, 17 Jul 2011 07:38:27 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[系统架构]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[hadoop]]></category>
		<category><![CDATA[分布式系统]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=1076</guid>
		<description><![CDATA[在今年的SIGMOD‘11上，Facebook又发了一篇新paper（<a href="http://borthakur.com/ftp/RealtimeHadoopSigmod2011.pdf">点此下载</a>），讲述了它们在提高Hadoop实时性上的工作及其应用。简单来讲，他们的项目需求主要有：

1. Elasticity（伸缩性）
2. High write throughput（高写吞吐量）
3. Efficient and low-latency strong consistency semantics within a data center（单个data center内高性能、低延迟的强一致性）
4. Efficient random reads from disk（disk的高性能随机读）
5. High Availability and Disaster Recovery（高可靠性、灾后恢复能力）
6. Fault Isolation（错误隔离）
7. Atomic read-modify-write primitives（read-modify-write原子操作）
8. Range Scans（范围扫描）

<a href="http://www.parallellabs.com/2011/07/17/realtime-apache-hadoop-at-facebook">阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Facebook%E7%9A%84Realtime+Hadoop%E5%8F%8A%E5%85%B6%E5%BA%94%E7%94%A8&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F07%2F17%2Frealtime-apache-hadoop-at-facebook%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Facebook%E7%9A%84Realtime+Hadoop%E5%8F%8A%E5%85%B6%E5%BA%94%E7%94%A8&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F07%2F17%2Frealtime-apache-hadoop-at-facebook%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>在今年的SIGMOD‘11上，Facebook又发了一篇新paper（<a href="http://borthakur.com/ftp/RealtimeHadoopSigmod2011.pdf">点此下载</a>），讲述了它们在提高Hadoop实时性上的工作及其应用。简单来讲，他们的项目需求主要有：</p>
<p>1. Elasticity（伸缩性）<br />
2. High write throughput（高写吞吐量）<br />
3. Efficient and low-latency strong consistency semantics within a data center（单个data center内高性能、低延迟的强一致性）<br />
4. Efficient random reads from disk（disk的高性能随机读）<br />
5. High Availability and Disaster Recovery（高可靠性、灾后恢复能力）<br />
6. Fault Isolation（错误隔离）<br />
7. Atomic read-modify-write primitives（read-modify-write原子操作）<br />
8. Range Scans（范围扫描）</p>
<p>最终他们选择了Hadoop和HBase作为解决方案的基石，因为HBase已经满足了上述需求中的大部分。与此同时，他们还做了如下三点改进以满足实时性需求：<br />
1. File Appends<br />
2. Name Node的高可靠性优化 (<a href="http://hadoopblog.blogspot.com/2010/02/hadoop-namenode-high-availability.html">AvatarNode</a>)<br />
3. HBase的读性能的优化</p>
<p>文章还列举了三个基于此方案的应用：Facebook Message，Facebook Insight，Facebook Metric Systems，大家可以着重看看这三个应用的特点及需求是怎样被这个方案满足的。</p>
<p>在现在这个时代，只有大公司才有如此大的数据来做新东西，难怪Facebook，Google的paper被大量追捧了。</p>
<p>参考资料：<br />
[1] <a href="http://highscalability.com/blog/2011/3/22/facebooks-new-realtime-analytics-system-hbase-to-process-20.html">Facebook&#8217;s New Realtime Analytics System: HBase To Process 20 Billion Events Per Day</a><br />
[2] <a href="http://natishalom.typepad.com/nati_shaloms_blog/2011/07/real-time-analytics-for-big-data-an-alternative-approach-to-facebooks-new-realtime-analytics-system.html">Real Time Analytics for Big Data: An Alternative Approach</a></p>
<p>下面是这篇文章的slides：</p>
<div style="width:425px" id="__ss_8616309"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/parallellabs/sigmod-realtime-hadooppresentation" title="Realtime Apache Hadoop at Facebook" target="_blank">Realtime Apache Hadoop at Facebook</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/8616309" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/parallellabs" target="_blank">parallellabs</a> </div>
</p></div>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Facebook%E7%9A%84Realtime+Hadoop%E5%8F%8A%E5%85%B6%E5%BA%94%E7%94%A8&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F07%2F17%2Frealtime-apache-hadoop-at-facebook%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Facebook%E7%9A%84Realtime+Hadoop%E5%8F%8A%E5%85%B6%E5%BA%94%E7%94%A8&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F07%2F17%2Frealtime-apache-hadoop-at-facebook%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/09/2012 -- <a href="http://www.parallellabs.com/2012/01/09/xrime/" title="X-RIME: 基于Hadoop的开源大规模社交网络分析工具">X-RIME: 基于Hadoop的开源大规模社交网络分析工具</a></li><li>12/02/2010 -- <a href="http://www.parallellabs.com/2010/12/02/jeff-dean-on-google-system-architecture/" title="Jeff Dean关于Google系统架构的讲座">Jeff Dean关于Google系统架构的讲座</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2011/07/17/realtime-apache-hadoop-at-facebook/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《程序员的自我修养》中关于加锁不能保证线程安全的一个错误</title>
		<link>http://www.parallellabs.com/2011/04/09/pthread-mutex-lock-and-thread-safety/</link>
		<comments>http://www.parallellabs.com/2011/04/09/pthread-mutex-lock-and-thread-safety/#comments</comments>
		<pubDate>Sat, 09 Apr 2011 00:49:16 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[memory visibility]]></category>
		<category><![CDATA[Pthreads]]></category>
		<category><![CDATA[原子操作]]></category>
		<category><![CDATA[多线程编程]]></category>
		<category><![CDATA[线程安全]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=1062</guid>
		<description><![CDATA[在《程序员的自我修养 -- 链接装载与库》一书第28页“过度优化”这一节中，作者提到了编译器优化可能造成多线程bug的情况。但是《程》中所给出的例子其实是错误的。Pthreads线程库帮程序员保证了pthread mutex（spin lock也一样）所保护的临界区内共享变量的可见性：即Thread 1一执行完unlock()，x的最新值1一定能被Thread 2看见。（为了实现这一点，Pthreads线程库在实现的时候都会根据相应的硬件平台调用相应的memory barrier来保证内存可见性，感兴趣的同学可以看看nptl的实现）所以，只要正确的用锁保护好你的共享变量，你的程序就会是线程安全的。

<a href="http://www.parallellabs.com/2011/04/09/pthread-mutex-lock-and-thread-safety/"  >阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E3%80%8A%E7%A8%8B%E5%BA%8F%E5%91%98%E7%9A%84%E8%87%AA%E6%88%91%E4%BF%AE%E5%85%BB%E3%80%8B%E4%B8%AD%E5%85%B3%E4%BA%8E%E5%8A%A0%E9%94%81%E4%B8%8D%E8%83%BD%E4%BF%9D%E8%AF%81%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F04%2F09%2Fpthread-mutex-lock-and-thread-safety%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E3%80%8A%E7%A8%8B%E5%BA%8F%E5%91%98%E7%9A%84%E8%87%AA%E6%88%91%E4%BF%AE%E5%85%BB%E3%80%8B%E4%B8%AD%E5%85%B3%E4%BA%8E%E5%8A%A0%E9%94%81%E4%B8%8D%E8%83%BD%E4%BF%9D%E8%AF%81%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F04%2F09%2Fpthread-mutex-lock-and-thread-safety%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>在《程序员的自我修养 &#8212; 链接装载与库》一书第28页“过度优化”这一节中，作者提到了编译器优化可能造成多线程bug的情况（我手中的是09年6月第二次印刷那版）。原文如下：</p>
<blockquote><p>线程安全是一个非常烫手的山芋，因为即使合理的使用了锁，也不一定能保证线程安全，这是源于落后的编译器技术已经无法满足日益增长的并发需求。很多看似无错的代码在优化和并发前又产生了麻烦。最简单的例子，让我们看看如下代码：</p>
<p>x = 0;<br />
Thread 1        Thread 2<br />
lock();           lock();<br />
x++;             x++;<br />
unlock();        unlock();</p>
<p>由于有lock和unlock的保护，x++的行为不会被并发所破坏，那么x的值似乎必然是2了。然后，如果编译器为了提高x的访问速度，把x放到了某个寄存器里，那么我们知道不同线程的寄存器是各自独立的，因此如果Thread 1先获得锁，则程序的执行可能会呈现如下的执行情况：</p>
<p>*1 Thread 1：读取x的值到某个寄存器R[1] （R[1]=0）<br />
*2 Thread 1：R[1]++<br />
*3 Thread 2：读取x的值到某个寄存器R[2] （R[2]=0）<br />
*4 Thread 2：R[2]++<br />
*5 Thread 2：将R[2]写回至x（x=1）<br />
*6 Thread 1：（很久以后）将R[1]写回至x（x=1）</p>
<p>可见在这样的情况下即使正确的加锁，也不能保证多线程安全。</p></blockquote>
<p>这个“加锁后仍不能保证线程安全”的结论其实是错误的。在对一段代码进行加锁操作之后，被锁保护起来的代码就形成了一个临界区，在任何时刻最多只能有一个线程运行这个临界区中的代码，而其他的线程必须等待（例如<a href="http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/" target="“_blank”">pthread_mutex_lock是阻塞型等待，pthread_spin_lock是忙等待</a>）。给临界区加锁之后相当于给临界区内的代码添加了原子性的语义。</p>
<p>既然加锁之后临界区内的代码是原子操作的，那么就不可能出现《程》中描述的那种执行顺序，因为Thread 2必须要等到Thread 1执行完x++和unlock()之后才能获得锁并随即进行x++操作。即如下所述的执行顺序：</p>
<p>*1 Thread 1：lock()<br />
*2 Thread 1：读取x的值到某个寄存器R[1] （R[1]=0）<br />
*3 Thread 1：R[1]++<br />
*4 Thread 1：将R[1]写回至x（x=1）<br />
*5 Thread 1：unlock()<br />
*6 Thread 2：lock() //得到锁<br />
*7 Thread 2：读取x的值到某个寄存器R[2] （R[2]=1）<br />
*8 Thread 2：R[2]++<br />
*9 Thread 2：将R[2]写回至x（x=2）<br />
*10 Thread 2：unlock()</p>
<p>其实，这里更值得讨论的一个问题是memory visibility（内存可见性）。例如，在Thread 1将R[1]的值写回至x的这一步中，如果Thread 1只是将值放到了这个CPU核的write buffer（write buffer是多核CPU中为于优化写性能的一种硬件）里，而未将最新值直接更新至内存，那么处在另一个CPU核上的Thread 2真的有可能在第7步时读到的是x的旧值0，这下该怎么办？这个问题其实就是共享变量的值何时能被其他线程可见的问题。</p>
<p>好在正是因为内存可见性在共享内存的并行编程中如此的重要，所以以pthread为代表的线程库早就规定好了自己的内存模型，其中就包括了memory visibility的定义：</p>
<p>Memory Visibility<br />
- When will changes of shared data be visible to other threads?<br />
- Pthreads standard guarantees basic memory visibility rules<br />
» thread creation<br />
• memory state before calling pthread_create(&#8230;) is visible to created thread<br />
» mutex unlocking (also combined with condition variables)<br />
• memory state before unlocking a mutex is visible to thread which locks same mutex<br />
» thread termination (i.e. entering state “terminated”)<br />
• memory state before termination is visible to thread which joins with terminated thread<br />
» condition variables<br />
• memory state before notifying waiting threads is visible to woke up threads</p>
<p>说简单点，Pthreads线程库帮程序员保证了pthread mutex（spin lock也一样）所保护的临界区内共享变量的可见性：即Thread 1一执行完unlock()，x的最新值1一定能被Thread 2看见。（为了实现这一点，Pthreads线程库在实现的时候都会根据相应的硬件平台调用相应的memory barrier来保证内存可见性，感兴趣的同学可以看看nptl的实现）</p>
<p>所以，只要正确的用锁保护好你的共享变量，你的程序就会是线程安全的。《程》中所给出的上述例子其实是错误的。</p>
<p>PS.《程》确实是本好书，作者作为我的同龄人功力还是令人钦佩的。但是这个例子也反映了一个现实：写书最怕的就是出现重大的原则性错误，而博客作为互联网上的公开资源，能更容易的吸收大家的修改意见，保证文章的正确性。</p>
<p>参考文献：<br />
<a href="http://book.douban.com/subject/1941123/" target="_blank">[1] Programming with POSIX Threads</a><br />
<a href="http://www.domaigne.com/blog/computing/mutex-and-memory-visibility/" target="_blank">[2] Mutex and Memory Visibility</a></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E3%80%8A%E7%A8%8B%E5%BA%8F%E5%91%98%E7%9A%84%E8%87%AA%E6%88%91%E4%BF%AE%E5%85%BB%E3%80%8B%E4%B8%AD%E5%85%B3%E4%BA%8E%E5%8A%A0%E9%94%81%E4%B8%8D%E8%83%BD%E4%BF%9D%E8%AF%81%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F04%2F09%2Fpthread-mutex-lock-and-thread-safety%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E3%80%8A%E7%A8%8B%E5%BA%8F%E5%91%98%E7%9A%84%E8%87%AA%E6%88%91%E4%BF%AE%E5%85%BB%E3%80%8B%E4%B8%AD%E5%85%B3%E4%BA%8E%E5%8A%A0%E9%94%81%E4%B8%8D%E8%83%BD%E4%BF%9D%E8%AF%81%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F04%2F09%2Fpthread-mutex-lock-and-thread-safety%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>04/15/2010 -- <a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/" title="多线程程序中操作的原子性">多线程程序中操作的原子性</a></li><li>10/25/2010 -- <a href="http://www.parallellabs.com/2010/10/25/practical-concurrent-queue-algorithm/" title="多线程队列的算法优化">多线程队列的算法优化</a></li><li>01/31/2010 -- <a href="http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/" title="Pthreads并行编程之spin lock与mutex性能对比分析">Pthreads并行编程之spin lock与mutex性能对比分析</a></li><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2011/04/09/pthread-mutex-lock-and-thread-safety/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>你好，2011！</title>
		<link>http://www.parallellabs.com/2011/01/01/hello-2011/</link>
		<comments>http://www.parallellabs.com/2011/01/01/hello-2011/#comments</comments>
		<pubDate>Sat, 01 Jan 2011 06:47:28 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[生活笔记]]></category>
		<category><![CDATA[年终总结]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=1024</guid>
		<description><![CDATA[2010年总结与2011年计划。

<a href="http://www.parallellabs.com/?p=1024"  >阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E4%BD%A0%E5%A5%BD%EF%BC%8C2011%EF%BC%81&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F01%2F01%2Fhello-2011%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E4%BD%A0%E5%A5%BD%EF%BC%8C2011%EF%BC%81&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F01%2F01%2Fhello-2011%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<h2>2010年总结</h2>
<p><strong>爱人。</strong>在08年8月24日踏上去瑞典的飞机时我曾跟我的女友说：“宝贝，你放心，等我回来”。今年我最大的成就之一就是实现了两年前的诺言。</p>
<p><strong>家人。</strong>在暑假时我抽时间跟家人完成了一次欧洲游。“活在当下”是《追逐日光》作者的一句感慨，不要等到已经失去与你所爱的人相处的机会时再去后悔。</p>
<p><strong>研究。</strong>10年大部分时间都用来做研究了。我非常庆幸能有机会与我的导师Per Stenström一起共事，从他身上我学到了非常非常多的东西，是他帮助我找到了自己的兴趣和方向，他给我的<a href="http://www.parallellabs.com/2010/10/27/steve-jobs-talked-in-stanford-2005/">那句寄语</a>更是让我终生受益。临别之际我跟他说，“现在我因你而骄傲，将来我一定努力使你因我而自豪。”</p>
<p>2010年最有感触的一句话：”仰望星空与脚踏实地”。前者提醒我想成为的是一个对社会有用的人；后者提醒我在特定的环境下该如何把事情做好。</p>
<h2>2011年计划</h2>
<p><strong>自修。</strong>希望能全方面提升自己的修养。</p>
<p><strong>研究。</strong>希望能发一篇顶级Paper。现在正在冲刺ICS。</p>
<p><strong>工作。</strong>希望能在北京找到一份让我感到Exciting的工作，牛同事越多越好。</p>
<p><strong>编程。</strong>希望今年至少能写三万行代码。</p>
<p><strong>交际。</strong>希望能参加更多的线下聚会，认识更多的朋友。</p>
<p><strong>读书。</strong>希望能读完12本书，至少3本非技术的。</p>
<p><strong>博客。</strong>希望能写24篇博客。其实我觉得我写Wiki的形式更好，因为我的博客都很长。</p>
<p><strong>锻炼。</strong>希望每周能锻炼一次。</p>
<p><strong>效率。</strong>希望能全方面提升自己的个人效率。</p>
<p><strong>感情，亲情。</strong>放在心中。</p>
<p>2011年的箴言：”Stay Hungry，Stay Foolish”。<br />
郭去疾先生对这句话的解读我非常喜欢，特此与大家分享：</p>
<p>“乔布斯说stay hungry，我以为饥渴有三个层次：贪婪、成就动机、好奇心。三者分别关注：瞬间的结果，持续的过程，和远大的未知。三者也恰好对应了三种人：卑劣的投机者，艰辛的攀登者，与幸福的探索者。</p>
<p>乔布斯说的stay foolish，放在语言环境中（斯坦福毕业典礼），我觉得很有针对性的，是特别说给这些所谓名校毕业生听的，因为他们比较容易持才放旷，不可一世，或者投机取巧，追求捷径。翻译成中文，就是：切不要聪明反被聪明误。”</p>
<p>祝大家新年里幸福，平安，健康，开心！</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E4%BD%A0%E5%A5%BD%EF%BC%8C2011%EF%BC%81&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F01%2F01%2Fhello-2011%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E4%BD%A0%E5%A5%BD%EF%BC%8C2011%EF%BC%81&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2011%2F01%2F01%2Fhello-2011%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>12/31/2009 -- <a href="http://www.parallellabs.com/2009/12/31/09-summary/" title="09年感悟">09年感悟</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2011/01/01/hello-2011/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>移动设备进入多核时代！</title>
		<link>http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices/</link>
		<comments>http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 04:04:10 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[业界评论]]></category>
		<category><![CDATA[互联网]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[移动开发]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=1000</guid>
		<description><![CDATA[Nvidia最近发布了代号为Tegra 2的新一代双核移动处理器，移动设备即将进入多核时代。该款处理器由两个基于ARM Cortex A9的核心及其它视频音频图形专用核心（可看成Accelerator）组成，是一个典型的异构（Heterogeneous）平台。这个平台的关键特征有两个：低功耗（比高频单核的处理器耗电小），高性能（异构平台的性能优势）。

<a href="http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices">阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E7%A7%BB%E5%8A%A8%E8%AE%BE%E5%A4%87%E8%BF%9B%E5%85%A5%E5%A4%9A%E6%A0%B8%E6%97%B6%E4%BB%A3%EF%BC%81&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F28%2Fmulticore-and-mobile-devices%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E7%A7%BB%E5%8A%A8%E8%AE%BE%E5%A4%87%E8%BF%9B%E5%85%A5%E5%A4%9A%E6%A0%B8%E6%97%B6%E4%BB%A3%EF%BC%81&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F28%2Fmulticore-and-mobile-devices%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>Nvidia最近发布了代号为Tegra 2的新一代双核移动处理器，移动设备即将进入多核时代。该款处理器由两个基于ARM Cortex A9的核心及其它视频音频图形专用核心（可看成Accelerator）组成，是一个典型的异构（Heterogeneous）平台。这个平台的关键特征有两个：低功耗（比高频单核的处理器耗电小），高性能（异构平台的性能优势）。</p>
<p>我之前也讲过为什么我们要迁移到<a href="http://www.parallellabs.com/2010/08/17/the-trouble-with-multicore/" target="_blank">多核平台</a>，简单来说，继续提升核心频率及电压的办法会让处理器的功耗呈指数级增加，此时的功耗会难以让人接受；而在晶体管数目持续增加的前提下，工业界自然就（被迫）选择了<a href="http://www.parallellabs.com/2010/10/03/future-multiprocessors/"  target="_blank">更加容易实现的多核方案</a>来继续提升硬件的性能。这个趋势也即将体现在移动处理器上。</p>
<p>Nvidia的白皮书<a href="http://www.nvidia.com/content/PDF/tegra_white_papers/Benefits-of-Multi-core-CPUs-in-Mobile-Devices_Ver1.2.pdf"  target="_blank">《The Benefits of Multiple CPU Cores in Mobile Devices》</a>中提到了几个多核对移动应用带来的好处：</p>
<h4>1. 更快的网页加载速度</h4>
<p>现在的网页内容越来越丰富，也越来越复杂。HTML5，Flash，Javascript，视频等内容的呈现都需要强大的处理能力。Nvidia提供的测试数据表明Tegra 2的Javascript性能提升了1.5~2倍，网页平均加载速度提升了46%。事实上Firefox，Chrome等桌面浏览器都已经采用了多线程，而Android浏览器，Safari等采用的Webkit内核也已经实现了多线程。在浏览器已经并行化的前提下，多核移动处理器自然能提供更快更丰富的网页渲染体验。</p>
<h4>2. 更低的功耗及更高的性能瓦特比</h4>
<p>对多核来讲，任务调度及电源管理算法是提升性能瓦特比的关键。Tegra 2能通过如下几点降低功耗：<br />
1）把任务平均分配到两个核心上，这样每个核心都不必跑在最高频率/电压上，而只需要以较低的频率/电压就能完成任务，从而节省功耗<br />
2）如果要执行的任务是高度并行化的，Tegra 2就能更快的完成这个任务，从而更快的进入超低功耗待机模式，节省更多电量<br />
3）如果任务只需要一个核心的话，其他计算单元可以被关闭从而节省电量</p>
<p>续航能力一直是手机、Tablet等移动设备的关键问题之一，在电池技术没有突破性进展的今天，我们只能寄希望于硬件/软件上的优化手段来降低功耗了。</p>
<h4>3. 提升游戏体验</h4>
<p>Tegra 2的图形处理单元叫做Ultra Low Power (ULP) GeForce GPU，性能应该很不错。现在的一些主流游戏引擎早已经完成了并行化（多线程分别用来完成渲染，音频，网络，解码，碰撞检测，透明等任务）。白皮书中提供的测试数据表明虚幻3引擎在Tegra 2双核心上快了将近70%。一个值得注意的地方时很多游戏引擎是通过task parallelism的方式以适应不同的处理器核心数目，这说明基于这些引擎的游戏可以在几乎不修改程序的情况下在以后的4核乃至8核移动平台上取得更好的游戏体验。游戏在最受欢迎的移动应用中还是占了大头的，所以多核对移动游戏应用的影响会非常大。</p>
<p>下面是一些主流游戏引擎使用的线程数：<br />
Game/Engine（Number of Threads）<br />
Unreal Engine 3（4+）<br />
Id Tech 5（6+）<br />
Frostbite（14）<br />
Civilization 5（12）<br />
Mafia 2（4）<br />
Crysis（8）<br />
Uncharted 2（8）<br />
Killzone 2（8+）</p>
<h4>4. 更平滑的用户体验及更快的多任务处理能力</h4>
<p>多任务处理在手机/Tablet上都非常常见。当你一边听着歌，一边下载电影，一边上网冲浪时，多核处理器就能帮你把这些任务分配到不同的核心上进行处理，从而给你提供更好的更平滑的用户体验。我记得iPad上的一些电子杂志的界面响应速度是个很大的问题，因为渲染速度太慢了，性能更高的多核平台就能提供更快的处理速度，提升用户体验，当然，这个前提是该程序能充分利用好多核。</p>
<p>想到这我还要插一句题外话。iOS一开始不支持对第三方程序的多任务处理功能其实主要是因为iPhone/iPad上内存有限（256MB）且没有硬盘（即没有swap），具体可参考Robert Love（该大牛现在在做Android）这篇<a href="http://blog.rlove.org/2010/04/why-ipad-and-iphone-dont-support.html"  target="_blank">《Why the iPad and iPhone don&#8217;t Support Multitasking》</a>；至于Android怎么解决多任务处理的可以参考<a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html"  target="_blank">这篇《Multitasking Android Way》</a>（想看这两篇都要会功夫，你懂的）</p>
<p>移动设备的多核时代已经到来，移动开发者们，你们准备好了么？</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E7%A7%BB%E5%8A%A8%E8%AE%BE%E5%A4%87%E8%BF%9B%E5%85%A5%E5%A4%9A%E6%A0%B8%E6%97%B6%E4%BB%A3%EF%BC%81&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F28%2Fmulticore-and-mobile-devices%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E7%A7%BB%E5%8A%A8%E8%AE%BE%E5%A4%87%E8%BF%9B%E5%85%A5%E5%A4%9A%E6%A0%B8%E6%97%B6%E4%BB%A3%EF%BC%81&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F28%2Fmulticore-and-mobile-devices%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>10/03/2010 -- <a href="http://www.parallellabs.com/2010/10/03/future-multiprocessors/" title="多核的未来">多核的未来</a></li><li>09/20/2010 -- <a href="http://www.parallellabs.com/2010/09/20/the-trouble-with-multicore-2/" title="多核编程的难题（二）">多核编程的难题（二）</a></li><li>08/17/2010 -- <a href="http://www.parallellabs.com/2010/08/17/the-trouble-with-multicore/" title="多核编程的难题（一）">多核编程的难题（一）</a></li><li>04/01/2010 -- <a href="http://www.parallellabs.com/2010/04/01/the-third-software-crisis/" title="第三次软件危机">第三次软件危机</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>剖析为什么在多核多线程程序中要慎用volatile关键字？</title>
		<link>http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/</link>
		<comments>http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/#comments</comments>
		<pubDate>Sat, 04 Dec 2010 08:46:26 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[Pthreads]]></category>
		<category><![CDATA[volatile]]></category>
		<category><![CDATA[原子操作]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[多线程Bug]]></category>
		<category><![CDATA[多线程内存模型]]></category>
		<category><![CDATA[多线程编程]]></category>
		<category><![CDATA[线程同步]]></category>
		<category><![CDATA[线程安全]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=924</guid>
		<description><![CDATA[这篇文章详细剖析了为什么在多核时代进行多线程编程时需要慎用volatile关键字。

主要内容有：
1. C/C++中的volatile关键字
2. Visual Studio对C/C++中volatile关键字的扩展
3. Java/.NET中的volatile关键字
4. Memory Model（内存模型）
5. Volatile使用建议

<a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/"  >阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%89%96%E6%9E%90%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8%E5%A4%9A%E6%A0%B8%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E4%B8%AD%E8%A6%81%E6%85%8E%E7%94%A8volatile%E5%85%B3%E9%94%AE%E5%AD%97%EF%BC%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F04%2Fwhy-should-we-be-care-of-volatile-keyword-in-multithreaded-applications%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%89%96%E6%9E%90%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8%E5%A4%9A%E6%A0%B8%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E4%B8%AD%E8%A6%81%E6%85%8E%E7%94%A8volatile%E5%85%B3%E9%94%AE%E5%AD%97%EF%BC%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F04%2Fwhy-should-we-be-care-of-volatile-keyword-in-multithreaded-applications%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>这篇文章详细剖析了为什么在多核时代进行多线程编程时需要慎用volatile关键字。</p>
<p>主要内容有：<br />
1. C/C++中的volatile关键字<br />
2. Visual Studio对C/C++中volatile关键字的扩展<br />
3. Java/.NET中的volatile关键字<br />
4. Memory Model（内存模型）<br />
5. Volatile使用建议</p>
<h2>1. C/C++中的volatile关键字</h2>
<h3>1.1 传统用途</h3>
<p>C/C++作为系统级语言，它们与硬件的联系是很紧密的。volatile的意思是“易变的”，这个关键字最早就是为了针对那些“异常”的内存操作而准备的。它的效果是让编译器不要对这个变量的读写操作做任何优化，每次读的时候都直接去该变量的内存地址中去读，每次写的时候都直接写到该变量的内存地址中去，即不做任何缓存优化。它经常用在需要处理中断的嵌入式系统中，其典型的应用有下面几种：</p>
<p>a. 避免用通用寄存器对内存读写的优化。编译器常做的一种优化就是：把常用变量的频繁读写弄到通用寄存器中，最后不用的时候再存回内存中。但是如果某个内存地址中的值是由片外决定的（例如另一个线程或是另一个设备可能更改它），那就需要volatile关键字了。（感谢<a href="http://csbabel.wordpress.com/">Kenny老师</a>指正）<br />
b. 硬件寄存器可能被其他设备改变的情况。例如一个嵌入式板子上的某个寄存器直接与一个测试仪器连在一起，这样在这个寄存器的值随时可能被那个测试仪器更改。在这种情况下如果把该值设为volatile属性的，那么编译器就会每次都直接从内存中去取这个值的最新值，而不是自作聪明的把这个值保留在缓存中而导致读不到最新的那个被其他设备写入的新值。<br />
c. 同一个物理内存地址M有两个不同的内存地址的情况。例如两个程序同时对同一个物理地址进行读写，那么编译器就不能假设这个地址只会有一个程序访问而做缓存优化，所以程序员在这种情况下也需要把它定义为volatile的。</p>
<h3>1.2 多线程程序中的错误用法</h3>
<p>看到这里，很多朋友自然会想到：恩，那么如果是两个线程需要同时访问一个共享变量，为了让其中两个线程每次都能读到这个变量的最新值，我们就把它定义为volatile的就好了嘛！我想这个就是多线程程序中volatile之所以引起那么多争议的最大原因。可惜的是，这个想法是错误的。</p>
<p>举例来说，想用volatile变量来做同步（例如一个flag）？错！为什么？很简单，虽然volatile意味着每次读和写都是直接去内存地址中去操作，<strong>但是volatile在C/C++现有标准中即不能保证<a href="http://www.parallellabs.com/2010/11/13/concurrency-bugs-1/">原子性（Atomicity）</a>也不能保证<a href="http://www.parallellabs.com/2010/11/23/concurrency-bugs-2/">顺序性（Ordering）</a>，所以几乎所有试图用volatile来进行多线程同步的方案都是错的</strong>。我之前一篇文章介绍了<a href="http://www.parallellabs.com/2010/03/06/why-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence/">Sequential Consistency模型</a>（后面简称SC），它其实就是我们印象中多线程程序应该有的执行顺序。但是，SC最大的问题是性能太低了，因为CPU/编译器完全没有必要严格按代码规定的顺序（program order）来执行每一条指令。学过体系结构的同学应该知道不管是编译器也好CPU也好，他们最擅长做的事情就是帮你做乱序优化。在串行时代这些乱序优化对程序员来说都是透明的，封装好了的，你不用关心它们到底给你乱序成啥样了，因为它们会保证优化后的程序的运行结果跟你写程序时预期的结果是一模一样的。但是进入多核时代之后，CPU和编译器还会继续做那些串行时代的优化，更重要的是这些优化还会打破你多线程程序的SC模型语义，从而使得多线程程序的实际运行结果与我们所期待的运行结果不一致！</p>
<p>拿X86来说，它的多核内存模型没有严格执行SC，即属于weak ordering（或者叫relax ordering？）。它唯一允许的乱序优化是可以把对不同地址的load操作提到store之前去（即把store x->load y乱序优化成load y -> store x）。而store x -> store y、load x -> load y，以及store x -> load y不允许交换执行顺序。在X86这样的内存模型下，volatile关键字根本就不能保证对不同volatile变量x和y的store x -> load y的操作不会被CPU乱序优化成load y -> store x。</p>
<p>而对多线程读写操作的原子性来说，诸如volatile x=1这样的写操作的<a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/">原子性其实是由X86硬件保证的</a>，跟volatile没有任何关系。事实上，volatile根本不能保证对没有内存对齐的变量（或者超出机器字长的变量）的读写操作的原子性。</p>
<p>为了有个更直观的理解，我们来看看CPU的乱序优化是如何让volatile在多线程程序中显得如此无力的。下面这个著名的Dekker算法是想用flag1/2和turn来实现两个线程情况下的临界区互斥访问。这个算法关键就在于对flag1/2和turn的读操作（load）是在其写操作（store）之后的，因此这个多线程算法能保证dekker1和dekker2中对gSharedCounter++的操作是互斥的，即等于是把gSharedCounter++放到临界区里去了。但是，多核X86可能会对这个store->load操作做乱序优化，例如dekker1中对flag2的读操作可能会被提到对flag1和turn的写操作之前，这样就会最终导致临界区的互斥访问失效，而gSharedCounter++也会因此产生data race从而出现错误的计算结果。那么为什么多核CPU会对多线程程序做这样的乱序优化呢？因为从单线程的视角来看flag2和flag1、turn是没有依赖关系的，所以CPU当然可以对他们进行乱序优化以便充分利用好CPU里面的流水线（想了解更多细节请参考计算机体系结构相关书籍）。这样的优化虽然从单线程角度来讲没有错，但是它却违反了我们设计这个多线程算法时所期望的那个多线程语义。（想要解决这个bug就需要自己手动添加memory barrier，或者干脆别去实现这样的算法，而是使用类似pthread_mutex_lock这样的库函数，后面我会再讲到这点）</p>
<p>当然，对不同的CPU来说他们的内存模型是不同的。比如说，如果这个程序是在单核上以多线程的方式执行那么它肯定不会出错，因为单核CPU的内存模型是符合SC的。而在例如PowerPC，ARM之类的架构上运行结果到底如何就得去翻它们的硬件手册中内存模型是怎么定义的了。</p>
<pre class="brush: cpp; collapse: true; light: false; title: ; toolbar: true; notranslate">
/*
 * Dekker's algorithm, implemented on pthreads
 *
 * To use as a test to see if/when we can make
 * memory consistency play games with us in
 * practice.
 *
 * Compile: gcc -O2 -o dekker dekker.c -lpthread
 * Source: http://jakob.engbloms.se/archives/65
 */ 

#include &lt;assert.h&gt;
#include &lt;pthread.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

#undef PRINT_PROGRESS 

static volatile int flag1 = 0;
static volatile int flag2 = 0;
static volatile int turn  = 1;
static volatile int gSharedCounter = 0;
int gLoopCount;
int gOnePercent;

void dekker1( ) {
        flag1 = 1;
        turn  = 2;
        while((flag2 ==  1) &amp;&amp; (turn == 2)) ;
        // Critical section
        gSharedCounter++;
        // Let the other task run
        flag1 = 0;
}

void dekker2(void) {
        flag2 = 1;
        turn = 1;
        while((flag1 ==  1) &amp;&amp; (turn == 1)) ;
        // critical section
        gSharedCounter++;
        // leave critical section
        flag2 = 0;
}

//
// Tasks, as a level of indirection
//
void *task1(void *arg) {
        int i,j;
        printf(&quot;Starting task1\n&quot;);
        // Do the dekker very many times
#ifdef PRINT_PROGRESS
	for(i=0;i&lt;100;i++) {
	  printf(&quot;[One] at %d%%\n&quot;,i);
	  for(j=gOnePercent;j&gt;0;j--) {
	    dekker1();
	  }
	}
#else
	// Simple basic loop
        for(i=gLoopCount;i&gt;0;i--) {
                dekker1();
        }
#endif

}

void *task2(void *arg) {
        int i,j;
        printf(&quot;Starting task2\n&quot;);
#ifdef PRINT_PROGRESS
	for(i=0;i&lt;100;i++) {
	  printf(&quot;[Two] at %d%%\n&quot;,i);
	  for(j=gOnePercent;j&gt;0;j--) {
	    dekker2();
	  }
	}
#else
        for(i=gLoopCount;i&gt;0;i--) {
                dekker2();
        }
#endif
}

int
main(int argc, char ** argv)
{
        int            loopCount = 0;
        pthread_t      dekker_thread_1;
        pthread_t      dekker_thread_2;
        void           * returnCode;
        int            result;
        int            expected_sum;

        /* Check arguments to program*/
        if(argc != 2)
        {
                fprintf(stderr, &quot;USAGE: %s &lt;loopcount&gt;\n&quot;, argv[0]);
                exit(1);
        }

        /* Parse argument */
        loopCount   = atoi(argv[1]);	/* Don't bother with format checking */
        gLoopCount  = loopCount;
	gOnePercent = loopCount/100;
        expected_sum = 2*loopCount;

        /* Start the threads */
        result = pthread_create(&amp;dekker_thread_1, NULL, task1, NULL);
        result = pthread_create(&amp;dekker_thread_2, NULL, task2, NULL);

        /* Wait for the threads to end */
        result = pthread_join(dekker_thread_1,&amp;returnCode);
        result = pthread_join(dekker_thread_2,&amp;returnCode);
        printf(&quot;Both threads terminated\n&quot;);

        /* Check result */
        if( gSharedCounter != expected_sum ) {
                printf(&quot;[-] Dekker did not work, sum %d rather than %d.\n&quot;, gSharedCounter, expected_sum);
                printf(&quot;    %d missed updates due to memory consistency races.\n&quot;, (expected_sum-gSharedCounter));
                return 1;
        } else {
                printf(&quot;[+] Dekker worked.\n&quot;);
                return 0;
        }
}
</pre>
<h2>2. Visual Studio对C/C++中volatile关键字的扩展</h2>
<p>虽然C/C++中的volatile关键字没有对ordering做任何保证，但是微软从Visual Studio 2005开始就对volatile关键字添加了同步语义（保证ordering），即：对volatile变量的读操作具有acquire语义，对volatile变量的写操作具有release语义。Acquire和Release语义是来自data-race-free模型的概念。为了理解这个acquire语义和release语义有什么作用，我们来看看<a href="http://msdn.microsoft.com/en-us/library/12a04hfd(VS.80).aspx">MSDN中的一个例子</a>。</p>
<pre class="brush: cpp; collapse: true; light: false; title: ; toolbar: true; notranslate">
// volatile.cpp
// compile with: /EHsc /O2
// Output: Critical Data = 1 Success
#include &lt;iostream&gt;
#include &lt;windows.h&gt;
using namespace std;

volatile bool Sentinel = true;
int CriticalData = 0;

unsigned ThreadFunc1( void* pArguments ) {
   while (Sentinel)
      Sleep(0);   // volatile spin lock

   // CriticalData load guaranteed after every load of Sentinel
   cout &lt;&lt; &quot;Critical Data = &quot; &lt;&lt; CriticalData &lt;&lt; endl;
   return 0;
} 

unsigned  ThreadFunc2( void* pArguments ) {
   Sleep(2000);
   CriticalData++;   // guaranteed to occur before write to Sentinel
   Sentinel = false; // exit critical section
   return 0;
}

int main() {
   HANDLE hThread1, hThread2;
   DWORD retCode;

   hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&amp;ThreadFunc1,
      NULL, 0, NULL);
   hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&amp;ThreadFunc2,
      NULL, 0, NULL);

   if (hThread1 == NULL || hThread2 == NULL)       {
      cout &lt;&lt; &quot;CreateThread failed.&quot; &lt;&lt; endl;
      return 1;
   }

   retCode = WaitForSingleObject(hThread1,3000);

   CloseHandle(hThread1);
   CloseHandle(hThread2);

   if (retCode == WAIT_OBJECT_0 &amp;&amp; CriticalData == 1 )
      cout &lt;&lt; &quot;Success&quot; &lt;&lt; endl;
   else
      cout &lt;&lt; &quot;Failure&quot; &lt;&lt; endl;
}
</pre>
<p>例子中的 while (Sentinel) Sleep(0); // volatile spin lock 是对volatile变量的读操作，它具有acquire语义，acquire语义的隐义是当前线程在对sentinel的这个读操作之后的所有的对全局变量的访问都必须在该操作之后执行；同理，例子中的Sentinel = false; // exit critical section 是对volatile变量的写操作，它具有release语义，release语义的隐义是当前线程在对sentinel这个写操作之前的所有对全局变量的访问都必须在该操作之前执行完毕。所以ThreadFunc1（）读CriticalData时必定已经在ThreadFunc2（）执行完CriticalData++之后，即CriticalData最后输出的值必定为1。建议大家用纸画一下acquire/release来加深理解。<strong>一个比较形象的解释就是把acquire当成lock，把release当成unlock，它俩组成了一个临界区，所有临界区外面的操作都只能往这个里面移，但是临界区里面的操作都不能往外移，简单吧？</strong></p>
<p>其实这个程序就相当于用volatile变量的acquire和release语义实现了一个临界区，在临界区内部的代码就是 Sleep(2000); CriticalData++; 或者更贴切点也可以看成是一对pthread_cond_wait和pthread_cond_signal。</p>
<p>这个volatile的acquire和release语义是VS自己的扩展，C/C++标准里是没有的，所以同样的代码用gcc编译执行结果就可能是错的，因为编译器/CPU可能做违反正确性的乱序优化。Acquire和release语义本质上就是为了保证程序执行时memory order的正确性。<strong>但是，虽然这个VS扩展使得volatile变量能保证ordering，它还是不能保证对volatile变量读写的原子性。</strong>事实上，如果我们的程序是跑在X86上面的话，内存对齐了的变量的读写的原子性是由硬件保证的，跟volatile没有任何关系。而像volatile g_nCnt++这样的语句本身就不是原子操作，想要保证这个操作是原子的，就必须使用带LOCK语义的++操作，具体请看我<a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/">这篇文章</a>。</p>
<p>另外，VS生成的volatile变量的汇编代码是否真的调用了memory barrier也得看具体的硬件平台，例如x86上就不需要使用memory barrier也能保证acquire和release语义，因为X86硬件本身就有比较强的memory模型了，但是Itanium上面VS就会生成带memory barrier的汇编代码。具体可以参考<a href="http://blogs.msdn.com/b/kangsu/archive/2007/07/16/volatile-acquire-release-memory-fences-and-vc2005.aspx">这篇</a>。</p>
<p><strong>但是，虽然VS对volatile关键字加入了acquire/release语义，有一种情况还是会出错，即我们之前看到的dekker算法的例子。</strong>这个其实蛮好理解的，因为读操作的acquire语义不允许在其之后的操作往前移，但是允许在其之前的操作往后移；同理，写操作的release语义允许在其之后的操作往前移，但是不允许在其之前的操作往后移；这样的话对一个volatile变量的读操作（acquire）当然可以放到对另一个volatile变量的写操作（release）之前了！Bug就是这样产生的！下面这个程序大家拿Visual Studio跑一下就会发现bug了（我试了VS2008和VS2010，都有这个bug）。多线程编程复杂吧？希望大家还没被弄晕，要是晕了的话也很正常，仔仔细细重新再看一遍吧:)</p>
<p>想解决这个Bug也很简单，直接在dekker1和dekker2中对flag1/flag2/turn赋值操作之后都分别加入full memory barrier就可以了，即保证load一定是在store之后执行即可。具体的我就不详述了。</p>
<pre class="brush: cpp; collapse: true; light: false; title: ; toolbar: true; notranslate">
#include &lt;iostream&gt;
#include &lt;windows.h&gt;
using namespace std;

static volatile int flag1 = 0;
static volatile int flag2 = 0;
static volatile int turn = 1; // must have &quot;turn&quot;, otherwise the two threads might introduce deadlock at line 13&amp;23 of &quot;while...&quot;
static int gCount = 0;

void dekker1() {
	flag1 = 1;
	turn = 2;
	while ((flag2 == 1) &amp;&amp; (turn == 2));
	// critical section
	gCount++;
	flag1 = 0; 	// leave critical section
}

void dekker2() {
	flag2 = 1;
	turn = 1;
	while ((flag1 == 1) &amp;&amp; (turn == 1));
	// critical setion
	gCount++;
	flag2 = 0; 	// leave critical section
}

unsigned ThreadFunc1( void* pArguments ) {
	int i;
	//cout &lt;&lt; &quot;Starting Thread 1&quot; &lt;&lt; endl;
	for (i=0;i&lt;1000000;i++) {
		dekker1();
	}
	return 0;
} 

unsigned  ThreadFunc2( void* pArguments ) {
	int i;
	//cout &lt;&lt; &quot;Starting Thread 2&quot; &lt;&lt; endl;
	for (i=0;i&lt;1000000;i++) {
		dekker2();
	}
	return 0;
}

int main() {
	HANDLE hThread1, hThread2;
	//DWORD retCode;

	hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&amp;ThreadFunc1,
		NULL, 0, NULL);
	hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&amp;ThreadFunc2,
		NULL, 0, NULL);

	if (hThread1 == NULL || hThread2 == NULL) {
		cout &lt;&lt; &quot;CreateThread failed.&quot; &lt;&lt; endl;
		return 1;
	}

	WaitForSingleObject(hThread1,INFINITE);
	WaitForSingleObject(hThread2,INFINITE);
	cout &lt;&lt; gCount &lt;&lt; endl;

	if (gCount == 2000000)
		cout &lt;&lt; &quot;Success&quot; &lt;&lt; endl;
	else
		cout &lt;&lt; &quot;Fail&quot; &lt;&lt; endl;
}
</pre>
<h2>3. Java/.NET中的volatile关键字</h2>
<h3>3.1 多线程语义</h3>
<p>Java和.NET分别有JVM和CLR这样的虚拟机，保证多线程的语义就容易多了。<strong>说简单点，Java和.NET中的volatile关键字也是限制虚拟机做优化，都具有acquire和release语义，<del datetime="2011-06-08T07:55:52+00:00">而且由虚拟机直接保证了对volatile变量读写操作的原子性。</del> （volatile只保证可见性，不保证原子性。java中，对volatile修饰的long和double的读写就不是原子的 (http://java.sun.com/docs/books/jvms/second_edition/html /Threads.doc.html#22244)，除此之外的基本类型和引用类型都是原子的。&#8211; 多谢liuchangit指正） </strong>这里需要注意的一点是，Java和.NET里面的volatile没有对应于我们最开始提到的C/C++中对“异常操作”用volatile修饰的传统用法。原因很简单，Java和.NET的虚拟机对安全性的要求比C/C++高多了，它们才不允许不安全的“异常”访问存在呢。</p>
<p>而且像JVM/.NET这样的程序可移植性都非常好。虽然现在C++1x正在把多线程模型添加到标准中去，但是因为C++本身的性质导致它的硬件平台依赖性很高，可移植性不是特别好，所以在移植C/C++多线程程序时理解硬件平台的内存模型是非常重要的一件事情，它直接决定你这个程序是否会正确执行。</p>
<p>至于Java和.NET中是否也存在类似VS 2005那样的bug我没时间去测试，道理其实是相同的，真有需要的同学自己应该能测出来。好像这篇<a href="http://www.infoq.com/articles/memory_barriers_jvm_concurrency">InfoQ的文章</a>中显示Java运行这个dekker算法没有问题，因为JVM给它添加了mfence。另一个臭名昭著的例子就应该是<a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html">Double-Checked Locking</a>了。</p>
<h3>3.2 volatile int与AtomicInteger区别</h3>
<p>Java和.NET中这两者还是有些区别的，主要就是后者提供了类似incrementAndGet()这样的方法可以直接调用（保证了原子性），而如果是volatile x进行++操作则不是原子的。increaseAndGet()的实现调用了类似CAS这样的原子指令，所以能保证原子性，同时又不会像使用synchronized关键字一样损失很多性能，用来做全局计数器非常合适。</p>
<h2>4. Memory Model（内存模型）</h2>
<p>说了这么多，还是顺带介绍一下Memory Model吧。就像前面说的，CPU硬件有它自己的内存模型，不同的编程语言也有它自己的内存模型。如果用一句话来介绍什么是内存模型，我会说它就是程序员，编程语言和硬件之间的一个契约，它保证了共享的内存地址里的值在需要的时候是可见的。下次我会专门详细写一篇关于它的内容。它最大的作用是取得可编程性与性能优化之间的一个平衡。</p>
<h2>5. volatile使用建议</h2>
<p>总的来说，volatile关键字有两种用途：一个是ISO C/C++中用来处理“异常”内存行为（此用途只保证不让编译器做任何优化，对多核CPU是否会进行乱序优化没有任何约束力），另一种是在Java/.NET（包括Visual Studio添加的扩展）中用来实现高性能并行算法（此种用途通过使用memory barrier保证了CPU/编译器的ordering，以及通过JVM或者CLR保证了对该volatile变量读写操作的原子性）。</p>
<p>一句话，volatile对多线程编程是非常危险的，使用的时候千万要小心你的代码在多核上到底是不是按你所想的方式执行的，特别是对现在暂时还没有引入内存模型的C/C++程序更是如此。安全起见，大家还是用Pthreads，Java.util.concurrent，TBB等并行库提供的lock/spinlock，conditional variable, barrier, Atomic Variable之类的同步方法来干活的好，因为它们的内部实现都调用了相应的memory barrier来保证memory ordering，你只要保证你的多线程程序没有data race，那么它们就能帮你保证你的程序是正确的（是的，Pthreads库也是有它自己的内存模型的，只不过它的内存模型还些缺点，所以把多线程内存模型直接集成到C/C++中是更好的办法，也是将来的趋势，但是C++1x中将不会像Java/.NET一样给volatile关键字添加acquire和release语义，而是转而提供另一种具有同步语义的atomic variables，此为后话）。<strong>如果你想实现更高性能的lock free算法，或是使用volatile来进行同步，那么你就需要先把CPU和编程语言的memory model搞清楚，然后再时刻注意Atomicity和Ordering是否被保证了。</strong>（注意，用没有acquire/release语义的volatile变量来进行同步是错误的，但是你仍然可以在C/C++中用volatile来修饰一个不是用来做同步（例如一个event flag）而只是被不同线程读写的共享变量，只不过它的新值什么时候能被另一个线程读到是没有保证的，需要你自己做相应的处理）</p>
<p>Herb Sutter 在他的那篇<a href="http://www.drdobbs.com/high-performance-computing/212701484;jsessionid=YH24PBXWP5CJ3QE1GHPCKHWATMY32JVN?pgno=1" target="_blank">volatile vs. volatile</a>中对这两种用法做了很仔细的区分，我把其中两张表格链接贴过来供大家参考：</p>
<p><a href="http://i.cmpnet.com/ddj/images/article/2009/0901/090108sutter_f1.gif" target="_blank">volatile的两种用途</a><br />
<a href="http://i.cmpnet.com/ddj/images/article/2009/0901/090108sutter_t1.gif" target="_blank">volatile两种用途的异同</a></p>
<p>最后附上《Java Concurrency in Practice》3.1.4节中对Java语言的volatile关键字的使用建议（不要被英语吓到，这些内容确实对你有用，而且还能顺便帮练练英语，哈哈）：</p>
<p>So from a memory visibility perspective, writing a volatile variable is like exiting a synchronized block and reading a volatile variable is like entering a synchronized block. However, we do not recommend relying too heavily on volatile variables for visibility; code that relies on volatile variables for visibility of arbitrary state is more fragile and harder to understand than code that uses locking.</p>
<p>Use volatile variables only when they simplify implementing and verifying your synchronization policy; avoid using volatile variables when veryfing correctness would require subtle reasoning about visibility. Good uses of volatile variables include ensuring the visibility of their own state, that of the object they refer to, or indicating that an important lifecycle event (such as initialization or shutdown) has occurred.</p>
<p>Locking can guarantee both visibility and atomicity; volatile variables can only guarantee visibility.</p>
<p>You can use volatile variables only when all the following criteria are met:<br />
(1) Writes to the variable do not depend on its current value, or you can ensure that only a single thread ever updates the value;<br />
(2) The variable does not participate in invariants with other state variables; and<br />
(3) Locking is not required for any other reason while the variable is being accessed.</p>
<h2>参考资料</h2>
<p>1. <a href="http://book.douban.com/subject/1888733/">《Java Concurrency in Practice》</a>3.1.4节<br />
2. <a href="http://www.drdobbs.com/high-performance-computing/212701484;jsessionid=P2PXZYKEQVDFDQE1GHPCKHWATMY32JVN?pgno=1">volatile vs. volatile（Herb Sutter对volatile的阐述，必看）</a><br />
3. <a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html">The “Double-Checked Locking is Broken” Declaration</a><br />
4. <a href="http://www.albahari.com/threading/part4.aspx#_The_volatile_keyword">Threading in C#</a><br />
5. <a href="http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/">Volatile: Almost Useless for Multi-Threaded Programming</a><br />
6. <a href="http://www.linuxjournal.com/article/8212">Memory Ordering in Modern Microprocessors</a><br />
7. <a href="http://en.wikipedia.org/wiki/Memory_ordering">Memory Ordering @ Wikipedia</a><br />
8. <a href="http://www.spongeliu.com/clanguage/memorybarrier/">内存屏障什么的</a><br />
9. <a href="http://ivanwangcn.spaces.live.com/blog/cns!F291BBD27380D1CA!153.entry?wa=wsignin1.0&#038;sa=540891277">The memory model of x86</a><br />
10. <a href="http://codingdao.com/wp/post/vc-volatile-variable-memory-barrier-concurrent-lock/">VC 下 volatile 变量能否建立 Memory Barrier 或并发锁</a><br />
11. <a href="http://www.bluebytesoftware.com/blog/PermaLink,guid,a0484627-c752-45f6-a2ac-414130cb3d2f.aspx">Sayonara volatile（Concurrent Programming on Windows作者的文章 跟我观点几乎一致）</a><br />
12. <a href="http://www.ibm.com/developerworks/cn/java/j-jtp06197.html">Java 理论与实践: 正确使用 Volatile 变量</a><br />
13. <a href="http://blog.xiping.me/2010/12/java-volatile-is-not-so-evil.html">Java中的Volatile关键字</a></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%89%96%E6%9E%90%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8%E5%A4%9A%E6%A0%B8%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E4%B8%AD%E8%A6%81%E6%85%8E%E7%94%A8volatile%E5%85%B3%E9%94%AE%E5%AD%97%EF%BC%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F04%2Fwhy-should-we-be-care-of-volatile-keyword-in-multithreaded-applications%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%89%96%E6%9E%90%E4%B8%BA%E4%BB%80%E4%B9%88%E5%9C%A8%E5%A4%9A%E6%A0%B8%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E4%B8%AD%E8%A6%81%E6%85%8E%E7%94%A8volatile%E5%85%B3%E9%94%AE%E5%AD%97%EF%BC%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F04%2Fwhy-should-we-be-care-of-volatile-keyword-in-multithreaded-applications%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>04/09/2011 -- <a href="http://www.parallellabs.com/2011/04/09/pthread-mutex-lock-and-thread-safety/" title="《程序员的自我修养》中关于加锁不能保证线程安全的一个错误">《程序员的自我修养》中关于加锁不能保证线程安全的一个错误</a></li><li>11/13/2010 -- <a href="http://www.parallellabs.com/2010/11/13/concurrency-bugs-1/" title="多线程程序常见Bug剖析（上）">多线程程序常见Bug剖析（上）</a></li><li>04/15/2010 -- <a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/" title="多线程程序中操作的原子性">多线程程序中操作的原子性</a></li><li>01/31/2010 -- <a href="http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/" title="Pthreads并行编程之spin lock与mutex性能对比分析">Pthreads并行编程之spin lock与mutex性能对比分析</a></li><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Jeff Dean关于Google系统架构的讲座</title>
		<link>http://www.parallellabs.com/2010/12/02/jeff-dean-on-google-system-architecture/</link>
		<comments>http://www.parallellabs.com/2010/12/02/jeff-dean-on-google-system-architecture/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 22:00:28 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[系统架构]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[分布式系统]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=900</guid>
		<description><![CDATA[上个月Jeff Dean在Standford的<a href="http://www.stanford.edu/class/ee380/" target="_blank">Computer Systems Colloquium (EE380)</a>这门讨论课上详细讲了讲Google的系统架构发展过程，因为这是份很新的资料，所以特意把它的Slide下下来与大家分享一下。这门课是Standford的讲座课程，每一节课都由不同的顶级工程师/科学家/投资人前来讲授IT行业的最新动向，非常非常有料，绝对值得深挖。这门课的每节课都是带视频的，Jeff Dean的这个讲座的录像在<a href="http://ee380.stanford.edu/cgi-bin/videologger.php?target=101110-ee380-300.asx">这里</a>。

<a href="http://www.parallellabs.com/2010/12/02/jeff-dean-on-google-system-architecture">阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Jeff+Dean%E5%85%B3%E4%BA%8EGoogle%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E7%9A%84%E8%AE%B2%E5%BA%A7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F02%2Fjeff-dean-on-google-system-architecture%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Jeff+Dean%E5%85%B3%E4%BA%8EGoogle%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E7%9A%84%E8%AE%B2%E5%BA%A7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F02%2Fjeff-dean-on-google-system-architecture%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>上个月Jeff Dean在Standford的<a href="http://www.stanford.edu/class/ee380/" target="_blank">Computer Systems Colloquium (EE380)</a>这门讨论课上详细讲了讲Google的系统架构发展过程，因为这是份很新的资料，所以特意把它的Slide下下来与大家分享一下。这门课是Standford的讲座课程，每一节课都由不同的顶级工程师/科学家/投资人前来讲授IT行业的最新动向，非常非常有料，绝对值得深挖。这门课的每节课都是带视频的，Jeff Dean的这个讲座的录像在<a href="http://ee380.stanford.edu/cgi-bin/videologger.php?target=101110-ee380-300.asx">这里</a>。想要下载该视频的同学可以去<a href="http://www.youtube.com/user/VortexTech#p/u/0/eidc-A4ElmQ">这里</a>（要会功夫，你懂的）。</p>
<p>这个讲座的主要内容包括：<br />
• Evolution of various systems at Google<br />
– computing hardware<br />
– core search systems<br />
– infrastructure software</p>
<p>• Techniques for building large-scale systems<br />
– decomposition into services<br />
– design patterns for performance &#038; reliability</p>
<p>个人的一点小感想：Jeff Dean在Google的这几年能面临这么多有意思的挑战，编程模型，可靠性，伸缩性，运行时环境等等等等，真是羡煞旁人。随着Google业务的扩展，整个系统的设计也面临各种各样新的挑战。只有有了<a href="http://www.parallellabs.com/2010/11/29/erlang-user-conference-2010-and-some-thoughts-on-career-of-programmers/">扎实的基本功</a>，在面对没有现成解决方案的新问题时才能游刃有余，做工程是如此，做研究更是如此。</p>
<p>可能有些同学会因为这是个英语的讲座而头疼。我觉得大家可以坚持看，哪个单词看不懂的就查字典，刚开始可能痛苦点，但是只要坚持下去，积少成多，你就会发现自己的英语慢慢就上来了，至少看这些英文slides是没问题了。</p>
<div style="width:538px" id="__ss_5982202"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/parallellabs/building-software-systems-at-google-and-lessons-learned" title="Building Software Systems at Google and Lessons Learned">Building Software Systems at Google and Lessons Learned</a></strong><object id="__sse5982202" width="538" height="450"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=101110-slides-101130101117-phpapp01&#038;rel=0&#038;stripped_title=building-software-systems-at-google-and-lessons-learned&#038;userName=parallellabs" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse5982202" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=101110-slides-101130101117-phpapp01&#038;rel=0&#038;stripped_title=building-software-systems-at-google-and-lessons-learned&#038;userName=parallellabs" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="538" height="450"></embed></object></p>
<p>另外还有几个关于Jeff Dean的Google架构的博文：<br />
<a href="http://tiny4.org/prog/diary/2009/03/jeff-dean-wsdm-2009-keynote.html" target="_blank">Jeff Dean 在WSDM 2009上面的演讲 Keynote 和视频终于出来了</a><br />
<a href="http://peopleyun.com/?p=794" target="_blank">来自Jeff Dean的分布式系统设计模式（更新版）</a><br />
<a href="http://coolshell.cn/articles/3301.html" target="_blank">Jeff Dean的Stanford演讲</a></p>
<p>我还发现了Jeff另外一个在09年做的类似主题的讲座，内容稍有重复，但是可以算是一个补充，例如这个里面包括了BigTable等内容。</p>
<p>Enjoy！</p>
<div style="width:538px" id="__ss_6010344"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/parallellabs/dean-keynoteladis2009jeffdean" title="Dean keynote-ladis2009-jeff-dean">Dean keynote-ladis2009-jeff-dean</a></strong><object id="__sse6010344" width="538" height="450"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=dean-keynote-ladis2009-101202152049-phpapp01&#038;rel=0&#038;stripped_title=dean-keynoteladis2009jeffdean&#038;userName=parallellabs" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse6010344" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=dean-keynote-ladis2009-101202152049-phpapp01&#038;rel=0&#038;stripped_title=dean-keynoteladis2009jeffdean&#038;userName=parallellabs" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="538" height="450"></embed></object>
</div>
</div>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Jeff+Dean%E5%85%B3%E4%BA%8EGoogle%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E7%9A%84%E8%AE%B2%E5%BA%A7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F02%2Fjeff-dean-on-google-system-architecture%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Jeff+Dean%E5%85%B3%E4%BA%8EGoogle%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84%E7%9A%84%E8%AE%B2%E5%BA%A7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F12%2F02%2Fjeff-dean-on-google-system-architecture%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/09/2012 -- <a href="http://www.parallellabs.com/2012/01/09/xrime/" title="X-RIME: 基于Hadoop的开源大规模社交网络分析工具">X-RIME: 基于Hadoop的开源大规模社交网络分析工具</a></li><li>07/17/2011 -- <a href="http://www.parallellabs.com/2011/07/17/realtime-apache-hadoop-at-facebook/" title="Facebook的Realtime Hadoop及其应用">Facebook的Realtime Hadoop及其应用</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/12/02/jeff-dean-on-google-system-architecture/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
<enclosure url="http://ee380.stanford.edu/cgi-bin/videologger.php?target=101110-ee380-300.asx" length="127" type="video/x-ms-asf" />
		</item>
		<item>
		<title>Erlang User Conference 2010见闻（兼谈程序员职业生涯）</title>
		<link>http://www.parallellabs.com/2010/11/29/erlang-user-conference-2010-and-some-thoughts-on-career-of-programmers/</link>
		<comments>http://www.parallellabs.com/2010/11/29/erlang-user-conference-2010-and-some-thoughts-on-career-of-programmers/#comments</comments>
		<pubDate>Sun, 28 Nov 2010 16:07:09 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[职业生涯]]></category>
		<category><![CDATA[Ericsson]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[业界评论]]></category>
		<category><![CDATA[瑞典]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=867</guid>
		<description><![CDATA[这是我第一次参加关于Erlang的技术大会，总来的说收获非常大，不管是技术上的还是非技术上的都是如此。首先不得不说的是会议举行的地点。我从别人那得知之前的会议一直都是在Ericsson的总部大楼举行的，但是因为参会人数越来越多，好像是从去年开始就转移到市中心一个很有历史的电影院ASTORIA举行了。由于这个举办地是电影院的缘故，从去年开始EUC就开始有电影海报了！去年海报是由哈利波特改的，今年的是星球大战。

<a href="http://www.parallellabs.com/2010/11/29/erlang-user-conference-2010-and-some-thoughts-on-career-of-programmers/" >阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Erlang+User+Conference+2010%E8%A7%81%E9%97%BB%EF%BC%88%E5%85%BC%E8%B0%88%E7%A8%8B%E5%BA%8F%E5%91%98%E8%81%8C%E4%B8%9A%E7%94%9F%E6%B6%AF%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F29%2Ferlang-user-conference-2010-and-some-thoughts-on-career-of-programmers%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Erlang+User+Conference+2010%E8%A7%81%E9%97%BB%EF%BC%88%E5%85%BC%E8%B0%88%E7%A8%8B%E5%BA%8F%E5%91%98%E8%81%8C%E4%B8%9A%E7%94%9F%E6%B6%AF%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F29%2Ferlang-user-conference-2010-and-some-thoughts-on-career-of-programmers%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<h2>1. Erlang User Confernece 2010</h2>
<p>这是我第一次参加关于Erlang的技术大会，总来的说收获非常大，不管是技术上的还是非技术上的都是如此。首先不得不说的是会议举行的地点。我从别人那得知之前的会议一直都是在Ericsson的总部大楼举行的，但是因为参会人数越来越多，好像是从去年开始就转移到市中心一个很有历史的电影院ASTORIA举行了。由于这个举办地是电影院的缘故，从去年开始EUC就开始有电影海报了！去年海报是由哈利波特改的，今年的是星球大战。去年那张如下，有意思吧？</p>
<p><img src="http://www.parallellabs.com/wp-content/uploads/2010/11/Erlang-the-Movie-208x300.jpg" alt="Erlang-the-Movie" title="Erlang-the-Movie" width="208" height="300" class="aligncenter size-medium wp-image-868" /></p>
<p>海报上面的四个人是Erlang最早的设计者们：Joe Armstrong, Mike Williams, Robert Virding还有当时的团队经理Bjarne Däcker。有了海报没有电影怎么能行？点这里观看<a href="http://v.youku.com/v_show/id_XMTE2OTcxNzE2.html" target="_blank">Erlang – The Movie</a>。</p>
<p>因为我赶早乘火车去的斯德，所以我到的时候已经快9点了，大会即将开始。在去之前我就很期待能见到Joe Armstrong本人，结果意外的是在签到处我就见到Joe本人了！不知道为什么，他出现在我面前时的形象与我之前想象的一模一样，后来我想明白了，根本原因在于他穿的就是他那件非常眼熟的紫黑线衫！哈哈！Joe爷爷人非常开朗，时不时从他坐的地方传出爽朗的笑声，此为后话。因为会议即将开始所以我就赶紧进去找座位坐下，正好赶上Bjarne Däcker在致开幕辞，这是每年的传统了。仔细看了下我的签到卡，这已经是第16届Erlang大会了！</p>
<p><a href="http://klarna.se/en/personal" target="_blank">Klarna</a>无疑是这届大会最吸引眼球的公司。开幕第一个Talk就是关于他们怎么使用Erlang相关的工具来解决他们的CodeManagement，Translation，Testing等问题的。Klarna有两个中国程序员，我见到其中之一的<a href="http://www.erlang-factory.com/conference/ErlangUserConference2010/speakers/JiaWong" target="_blank">Wang Jia</a>。Klarna是由三位瑞典银行家在05年创立的公司，提供第三方电子支付解决方案。他们最早的开发者就是从当时提供Erlang咨询的公司（其实也是Ericsson前员工）跳出来的。传闻说当时创始人提出业务需求后，他们说这个太简单了，用Erlang几天就开发出来了，虽然最后花了大概一个礼拜，但是可见Erlang开发效率之高。现在他们应该是Erlang程序员最多的公司，而且随着业务的增长他们的开发团队也在快速扩张。一年前他们只有20个左右，现在已经解决60人了，听说还要继续招人。Good for them！ 我还见到另一个在Mobile Art做Erlang开发的中国人<a href="http://zhang.nu/" target="_blank">张浩</a>，他已经用Erlang做开发3年多了。我们聊了很多关于职业发展的问题，非常有收获。</p>
<p>此次大会的slides和talk都可以在<a href="http://www.erlang-factory.com/conference/ErlangUserConference2010/talks" target="_blank">这里下载</a>。</p>
<h2>2. 关于职业生涯</h2>
<p>除技术之外我最大的感触就是看见一群爷爷级的人物仍然热衷于参加这样的技术盛会，让我很有编程编到老的冲动。Joe Armstrong老爷子是1950年生的，早年在英国念物理PhD，后来自己钱花光了，就跑去了爱丁堡做人工智能了。他的导师Donald Michie在二战时跟图灵一起工作过，所以收藏有图灵所有的论文。Joe就在满是图灵的论文的办公室里工作了整整一年多，难怪如此之牛。做研究讲究家谱，大师之所以成为大师还是需要一些机缘在里面的（当然，独力开创一片新天地的神牛除外）。关于Joe的更多趣闻可以看<a href="http://book.douban.com/subject/3673223/" target="_blank">《Coders at Works》</a>，中文版应该快出版了，但是如果有条件的话还是推荐大家读英文版，边学大师的经验边学英语，一举两得，岂不快哉？如果大家好奇Joe是怎么修炼到大师级的，他自己一句话很有代表性：“So I would characterize that period, which took 20 years, as learning how to program”。这句话的上下文我就不详述了，简单地说你可以理解成他花了20年学会了如何编程（注意，这个“如何编程”可不是指精通C++之类的）。这说明要想成为大师，没有十几二十年的功力肯定是不行的。<a href="http://daiyuwen.freeshell.org/gb/misc/21-days-cn.html" target="_blank">十年学会编程</a>不是空谈，而是实实在在的。说到程序员的基本功，我必须要站出来批评一下《Coders at Works》此书在豆瓣的一个<a href="http://book.douban.com/review/3733680/" target="_blank">不负责任的书评</a>，这位同学说“去他的算法内功基础，对于程序员实用主义才是王道”，这完全是误人子弟，而且可悲的是这个观点竟然有很多人支持。表面上这句话好像抓住了“实用主义”的大旗，但是这位同学却借此抨击算法基本功的重要性，实在是荒谬。（Update：该同学已经把标题改掉了）就拿Google Fellow Jeff Dean来说，他绝对算得上是实用主义的大师了吧？可是如果你去看看他关于Google整个系统架构演变过程的讲座，你就会发现把Google的那些诸如MapReduce、GFS之类的看家法宝化繁为简之后都可以还原成最基本的算法、数据结构之类的问题。Google整个架构的发展是根据需求的变化而发展而来的，MapReduce之类的不就是在遇到需要解决大规模并行编程这个问题时产生的实用的解决方案吗？可是，<strong>如果没有扎实的基本功它能被设计出来么？哪一个大师不是编程十几二十年以上？他们的基本功可能差么？</strong>想真正成为杰出的程序员，没有扎实的基本功是绝对不可能的，因为你会发现当你需要面对一个没有现成的解决方案的问题时，你的基本功就是最可信赖的法宝。</p>
<p>我在国内念书时确实也不知道天有多高，国内IT界有多浮躁，到了瑞典之后我有机会在<a href="http://www.nemalabs.com" target="_blank">Nema Labs</a>（创业公司），<a href="http://www.ericsson.com" target="_blank">Ericsson</a>（大公司）实习，跟我的导师<a href="http://129.16.20.23/~pers/" target="_blank">Per Stenström</a>学习，与<a href="http://www.cse.chalmers.se/~rjmh/" target="_blank">John Hughes</a>这样的大师交流，眼界真的开阔了很多。浮躁在中国是很普遍的社会性现象，就拿程序员职业生涯发展来说，中国现在很难找到有十几二十年经验的超级程序员，为什么？因为他们都转到管理方向去了，当CEO，CTO去了。<strong>我觉得这是由中国“官本位”的社会思想导致的。大家都觉得管人的比被管的等级高，要拿更高的工资，这实在是大错特错。</strong>实际上在外国公司里终身从事技术工作的超级工程师大有人在，而且这些超级工程师的工资往往比他们的Manager高得多。在瑞典，做基站的超级工程师时薪4K多克朗的都有（克朗跟人民币几乎等值，绝对真实），50W年薪的比比皆是，这样的待遇还会让你觉得当一辈子工程师没前（钱）途吗？我觉得走管理路线本身没有错，前提是你确实喜欢管理，善于交流，适合你的性格，而不是为了职业发展“被迫”往管理方向转。<strong>在现代企业中，管理者与被管理者本身没有高低贵贱之分，只是职能不同罢了。</strong>最顶级的程序员不仅受人尊重，更可以拿高薪。可惜国内社会风气普遍浮躁，这样的状况想要改变还需要很长时间。<strong>从供需的角度来讲，超级程序员的身价是由市场需求决定的。</strong>就拿华为来说，我上次跟他们在瑞典这边的一位技术负责人聊天时了解到他们在Kista最喜欢有十几年以上经验的超级工程师，因为这样的人才国内根本招不到。为什么他们需要招这样的人？因为华为的竞争对手也是世界级的企业（例如Ericsson），这个时候科技创新就是企业最重要的核心竞争力，自然就需要最顶级的工程师才能在竞争中胜出。我们看到的Google花250W美金挽留一位女工程师的例子（未经证实，<a href="http://thunk.org/tytso/blog/2010/11/29/google-has-a-problem-retaining-great-engineers-bullcrap/">可能是Facebook负责招聘的人炒作</a>）不也刚刚发生么？国内不也出现了年薪200W的工程师牛新庄么？我觉得随着中国IT行业的发展，科技创新将会变得越来越重要，而超级程序员也会越来越成为香饽饽，如果各位同学确实热爱编程，愿意一辈子编程，我希望你坚持下去，因为只要你成为超级程序员肯定会有赏识你的公司。现在的盛大创新院好像做的不错，他们给高级研究员年薪能有30W+，可以算是一个招聘高端人才的例子。而一个反例就是不依靠科技创新的公司（例如团购网站），它们确实是不怎么需要高端人才的，这样的公司不怎么靠技术取胜。</p>
<p>当然，技术不是最重要的，哪怕对Google，对Facebook也是一样。再高端的技术也必须找到市场，满足消费者的需求才能创造财富。我现在相信的是市场>管理>技术。是走管理路线还是走技术路线最好是按照你自己的性格特点来，喜欢干哪个就做哪个，而不是跟风去做管理。只要你努力，做什么都会有回报。</p>
<h2>3. 关于英语</h2>
<p>关于程序员个人发展，我不得不提及英语能力。我个人感觉，英语是阻碍中国程序员提升眼界的一道非常重要的关卡。关于英语于程序员之重要性，Joe在此书里面说了一句“If you are not good at English you&#8217;ll never be a very good programmer.”在欧美IT企业引领科技潮流的今天我们不去学习他们的技术怎么可能追上甚至超越他们？<strong>我建议所有有追求的程序员一定要把英语当做最基本的一门编程语言来学习！</strong>我自己的亲身经历是：英语帮我打开了另一个更广阔的世界的大门，从此直接阅读原版书酣畅淋漓的学习新知识，从此随意阅读最新的论文了解新动态，从此直接与最厉害的程序员毫无障碍的交流！</p>
<h2>4. 创新+创业</h2>
<p>我在最近一次Ericsson Research Day上有幸与John Hughes在Demo Session成为邻居，所以才出现了我在推上征求推友关于Erlang问题的一幕。John是从Basic开始学习编程的，在牛津念博士时就做的就是函数式编程的研究，他也是Haskell的创始人之一，95年他来到Chalmers任教至今。他学术上最有影响力的论文之一“QuickCheck: A lightweight Tool for Random Testing of Haskell Programs”成为了他后来创办的<a href="http://quviq.com/" target="_blank">Quviq</a>的技术核心。这个公司目前只有四名员工，当然四个人各个都是教授（我知道另一个专做编译器前端的传奇公司<a href="http://www.lingcc.com/2010/09/16/11217/" target="_blank">EDG</a>也只有5个人）。John为人非常亲切，我跟他聊的非常开心。他追求的编程之美（好吧，我本也不想再用XX之美，但是实在没更合适的词了）是<em>make programming easier &#8212; I like my programs to be short, beautiful, and elegant, and I hate drudgery</em>。我还问他你编程是不是有快40年了？他老人家（其实他跟Joe都是精气神特好，非常年轻的那种）想了半天说还真有四十年了。我最羡慕他一点是，他跟我导师Per Stenström一样横跨学术界与工业界，创新与创业双管齐下，互利互惠，既是学识渊博的教授，又是能给社会创造价值的企业家，人生如此，夫复何求？我跟他说真羡慕你真能享受双倍乐趣啊，他说是啊，真是太有趣了！其实中国教授也有在工业界与学术界都取得成功的例子，例如普林斯顿的<a href="http://www.cs.princeton.edu/~li/">Li Kai</a>教授和UCSD的<a href="http://cseweb.ucsd.edu/~yyzhou/">Zhou Yuanyuan</a>教授，所以说主要还是环境问题导致的。我个人是<a href="http://www.loongson.cn/" target="_blank">龙芯</a>的坚决拥护者，很多人说怎么用MIPS的授权，怎么浪费国家的钱什么什么的，我觉得这些都是扯淡。从我知道的情况来看，龙芯他们组最近把Micro, HPCA, ISCA, ISSCC这些最顶级的会议全发了一个遍，学术水平毫无疑问！胡伟武老师用毛泽东思想来带领团队是有效的（不管是否有失偏薄），而且也有<a href="http://sites.google.com/site/yunji83ict/">Chen Yunji</a>这样的青年才俊，我相信至少龙芯团队培养出来的这批人才已经足以对社会做出贡献。现在龙芯商业化还处在初期阶段，任重而道远，我祝福他们，看好他们！</p>
<p>中国的发展需要创新！需要最高端的科技人才！需要最顶尖的程序员！</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Erlang+User+Conference+2010%E8%A7%81%E9%97%BB%EF%BC%88%E5%85%BC%E8%B0%88%E7%A8%8B%E5%BA%8F%E5%91%98%E8%81%8C%E4%B8%9A%E7%94%9F%E6%B6%AF%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F29%2Ferlang-user-conference-2010-and-some-thoughts-on-career-of-programmers%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Erlang+User+Conference+2010%E8%A7%81%E9%97%BB%EF%BC%88%E5%85%BC%E8%B0%88%E7%A8%8B%E5%BA%8F%E5%91%98%E8%81%8C%E4%B8%9A%E7%94%9F%E6%B6%AF%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F29%2Ferlang-user-conference-2010-and-some-thoughts-on-career-of-programmers%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>12/28/2010 -- <a href="http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices/" title="移动设备进入多核时代！">移动设备进入多核时代！</a></li><li>10/27/2010 -- <a href="http://www.parallellabs.com/2010/10/27/steve-jobs-talked-in-stanford-2005/" title="史蒂夫乔布斯(Steve Jobs)在Stanford2005年毕业典礼上的演讲">史蒂夫乔布斯(Steve Jobs)在Stanford2005年毕业典礼上的演讲</a></li><li>10/03/2010 -- <a href="http://www.parallellabs.com/2010/10/03/future-multiprocessors/" title="多核的未来">多核的未来</a></li><li>09/20/2010 -- <a href="http://www.parallellabs.com/2010/09/20/the-trouble-with-multicore-2/" title="多核编程的难题（二）">多核编程的难题（二）</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/11/29/erlang-user-conference-2010-and-some-thoughts-on-career-of-programmers/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>多线程程序常见Bug剖析（下）</title>
		<link>http://www.parallellabs.com/2010/11/23/concurrency-bugs-2/</link>
		<comments>http://www.parallellabs.com/2010/11/23/concurrency-bugs-2/#comments</comments>
		<pubDate>Tue, 23 Nov 2010 00:27:31 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[多线程Bug]]></category>
		<category><![CDATA[多线程编程]]></category>
		<category><![CDATA[线程同步]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=829</guid>
		<description><![CDATA[上一篇文章我们专门针对违反原子性（Atomicity Violation）的多线程程序Bug做了剖析，现在我们再来看看另一种常见的多线程程序Bug：违反执行顺序（Ordering Violation）。

简单来说，多线程程序各个线程之间交错执行的顺序的不确定性（Non-deterministic）是造成违反执行顺序Bug的根源[注1]。正是因为这个原因，程序员在编写多线程程序时就不能假设程序会按照你设想的某个顺序去执行，而是应该充分考虑到各种可能的顺序组合，从而采取正确的同步措施。

<a href="http://www.parallellabs.com/2010/11/23/concurrency-bugs-2/">阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E5%B8%B8%E8%A7%81Bug%E5%89%96%E6%9E%90%EF%BC%88%E4%B8%8B%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F23%2Fconcurrency-bugs-2%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E5%B8%B8%E8%A7%81Bug%E5%89%96%E6%9E%90%EF%BC%88%E4%B8%8B%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F23%2Fconcurrency-bugs-2%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.parallellabs.com/2010/11/13/concurrency-bugs-1/" target="_blank">上一篇文章</a>我们专门针对违反原子性（Atomicity Violation）的多线程程序Bug做了剖析，现在我们再来看看另一种常见的多线程程序Bug：违反执行顺序（Ordering Violation）。</p>
<p>简单来说，多线程程序各个线程之间交错执行的顺序的不确定性（Non-deterministic）是造成违反执行顺序Bug的根源[注1]。正是因为这个原因，程序员在编写多线程程序时就不能假设程序会按照你设想的某个顺序去执行，而是应该充分考虑到各种可能的顺序组合，从而采取正确的同步措施。</p>
<h3>1. 违反执行顺序（Ordering Violation）</h3>
<p>举例来说，下面这个来自Mozilla的多线程Bug产生的原因就是程序员错误地假设S1一定会在S2之前执行完毕，即在S2访问mThread之前S1一定已经完成了对mThread的初始化（因为线程2是由线程1创建的）。事实上线程2完全有可能执行的很快，而且S1这个初始化操作又不是原子的（因为需要几个时钟周期才能结束），从而在线程1完成初始化（即S1）之前就已经运行到S2从而导致Bug。</p>
<pre class="brush: cpp; title: ; notranslate">
例1：
    Thread 1                                 Thread 2
void init(...)                           void mMain(...)
{ ...                                    { ...
 S1: mThread=                              ...
      PR_CreateThread(mMain, ...);         S2: mState = mThread-&gt;State;
  ...                                      ...
}                                        }
</pre>
<p>上面这个例子是一个线程读一个线程写的情况，除此之外还有违反写-写顺序以及违反一组读写顺序的情况。例如下面这个程序，程序员错误的以为S2（写操作）一定会在S4（也是写操作）之前执行。但是实际上这个程序完全有可能先执行S4后执行S2，从而导致线程1一直hang在S3处：</p>
<pre class="brush: cpp; title: ; notranslate">
例2：
    Thread 1                                 Thread 2
int ReadWriteProc(...)                   void DoneWaiting(...)
{                                        {
  ...                                     /*callback func of PBReadAsync*/
 S1: PBReadAsync(&amp;p);
 S2: io_pending = TRUE;                   ...
  ...                                     S4: io_pending = FALSE;
 S3: while (io_pending) {...}             ...
  ...                                    }
}
</pre>
<p>下面这个是违反一组读写操作顺序的例子：程序员假设S2一定会在S1之前执行，但是事实上可能S1在S2之前执行，从而导致程序crash。</p>
<pre class="brush: cpp; title: ; notranslate">
例3：
    Thread 1                                 Thread 2
void js_DestroyContext(...){             void js_DestroyContext(...){
  /* last one entering this func */      /* non-last one entering this func */
  S1: js_UnpinPinnedAtom(&amp;atoms);          S2: js_MarkAtom(&amp;atoms,...);
}                                        }
</pre>
<p>调试违反执行顺序这种类型的Bug最困难的地方就在只有某几种执行顺序才会引发Bug，这大大降低了Bug重现的几率。最简单的调试手段自然是使用printf了，但是类似printf这样的函数会干扰程序的执行顺序，所以有可能违反执行顺序的Bug更难产生了。我所知道的目前最领先的商业多线程Debugger是Corensic的<a href="http://www.corensic.com" target="_blank">Jinx</a>，他们的技术核心是用Hypervisor来控制线程的执行顺序以找出可能产生Bug的那些特定的执行顺序（学生、开源项目可以申请免费使用，Windows/Linux版均有）。八卦一下，这个公司是从U of Washington发展出来的，他们现在做的Deterministic Parallelism是最热门的方向之一。</p>
<h3>2. Ordering Violation的解决方案</h3>
<p>常见的解决方案主要有四种：<br />
（1）加锁进行同步<br />
加锁的目的就在于保证被锁住的操作的原子性，从而这些被锁住的操作就不会被别的线程的操作打断，在一定程度上保证了所需要的执行顺序。例如上面第二个例子可以给{S1,S2}一起加上锁，这样就不会出现S4打断S1,S2的情况了（即S1->S4->S2），因为S4是由S1引发的异步调用，S4肯定会在{S1,S2}这个原子操作执行完之后才能被运行。</p>
<p>（2）进行条件检查<br />
进行条件检查是另一种常见的解决方案，关键就在于通过额外的条件语句来迫使该程序会按照你所想的方式执行。例如下面这个例子就会对n的值进行检查：</p>
<pre class="brush: cpp; title: ; notranslate">
例4：
retry:
  n = block-&gt;n;
  ...
  ...
  if (n!=block-&gt;n)
  {
    goto retry;
  }
  ...
</pre>
<p>（3）调整代码执行顺序<br />
这个也是很可行的方案，例如上面的例2不需要给{S1,S2}加锁，而是直接调换S2与S1的顺序，这样S2就一定会在S4之前执行了！</p>
<p>（4）重新设计算法/数据结构<br />
还有一些执行顺序的问题可以通过重新设计算法/数据结构来解决。这个就得具体情况具体分析了。例如MySQL的bug #7209中，一个共享变量HASH::current_record的访问有顺序上的冲突，但是实际上这个变量不需要共享，所以最后的解决办法就是线程私有化这个变量。</p>
<h3>3. 总结</h3>
<p>多线程Bug确实是个非常让人头痛的问题。写多线程程序不难，难的在于写正确的多线程程序。多线程的debug现在仍然可以作为CS Top10学校的博士论文题目。在看过这两篇分析多线程常见Bug的文章之后，不知道各位同学有没有什么关于多线程Bug的经历与大家分享呢？欢迎大家留言:)</p>
<p>需要注意的是，违反执行顺序和违反原子性这两种Bug虽然是相互独立的，但是两者又有着潜在的联系。例如，上一篇文章中我所讲到的第一个违反原子性的例子其实是因为执行顺序的不确定性造成的，而本文的第二个例子就可以通过把{S1,S2}加锁保证原子性来保证想要的执行顺序。</p>
<h3>参考</h3>
<p>[1] <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.121.1203" target="_blank">Learning from Mistakes – A Comprehensive Study on Real World Concurrency Bug Characteristics</a><br />
[2] <a href="https://www.ideals.illinois.edu/handle/2142/10865" target="_blank">Understanding, Detecting and Exposing Concurrency Bugs</a><br />
[3] <a href="http://ppcp.codeplex.com/" target="_blank">Practical Parallel and Concurrent Programming</a><br />
[4] <a href="http://www.ibm.com/developerworks/java/library/j-concurrencybugpatterns/index.html">Java concurrency bug patterns for multicore systems</a></p>
<p>注1：严格来讲，多线程交错执行顺序的不确定性只是违反执行顺序Bug的原因之一。另一个可能造成违反执行顺序Bug的原因是编译器/CPU对代码做出的违反多线程程序语义的乱序优化，这种“错误的优化”直接引出了编程语言的内存模型（memory model）这个关键概念。后面我会专门分析下C++与Java的内存模型，敬请期待。</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E5%B8%B8%E8%A7%81Bug%E5%89%96%E6%9E%90%EF%BC%88%E4%B8%8B%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F23%2Fconcurrency-bugs-2%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E5%B8%B8%E8%A7%81Bug%E5%89%96%E6%9E%90%EF%BC%88%E4%B8%8B%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F23%2Fconcurrency-bugs-2%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li><li>11/13/2010 -- <a href="http://www.parallellabs.com/2010/11/13/concurrency-bugs-1/" title="多线程程序常见Bug剖析（上）">多线程程序常见Bug剖析（上）</a></li><li>01/31/2010 -- <a href="http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/" title="Pthreads并行编程之spin lock与mutex性能对比分析">Pthreads并行编程之spin lock与mutex性能对比分析</a></li><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/11/23/concurrency-bugs-2/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>多线程程序常见Bug剖析（上）</title>
		<link>http://www.parallellabs.com/2010/11/13/concurrency-bugs-1/</link>
		<comments>http://www.parallellabs.com/2010/11/13/concurrency-bugs-1/#comments</comments>
		<pubDate>Sat, 13 Nov 2010 14:59:40 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[原子操作]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[多线程Bug]]></category>
		<category><![CDATA[死锁]]></category>
		<category><![CDATA[线程同步]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=773</guid>
		<description><![CDATA[编写多线程程序的第一准则是先保证正确性，再考虑优化性能。本文重点分析多线程编程中除死锁之外的两种常见Bug：违反原子性（Atomicity Violation）和违反执行顺序（Ordering Violation）。现在已经有很多检测多线程Bug的工具，但是这两种Bug还没有工具能完美地帮你检测出来，所以到目前为止最好的办法还是程序员自己有意识的避免这两种Bug。本文的目的就是帮助程序员了解这两种Bug的常见形式和常见解决办法。

<a href="http://www.parallellabs.com/2010/11/13/concurrency-bugs-1/" >阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E5%B8%B8%E8%A7%81Bug%E5%89%96%E6%9E%90%EF%BC%88%E4%B8%8A%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F13%2Fconcurrency-bugs-1%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E5%B8%B8%E8%A7%81Bug%E5%89%96%E6%9E%90%EF%BC%88%E4%B8%8A%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F13%2Fconcurrency-bugs-1%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p><strong>编写多线程程序的第一准则是先保证正确性，再考虑优化性能。</strong>本文重点分析多线程编程中除死锁之外的另两种常见Bug：违反原子性（Atomicity Violation）和违反执行顺序（Ordering Violation）。现在已经有很多检测多线程Bug的工具，但是这两种Bug还没有工具能完美地帮你检测出来，所以到目前为止最好的办法还是程序员自己有意识的避免这两种Bug。本文的目的就是帮助程序员了解这两种Bug的常见形式和常见解决办法。</p>
<h4>1. 多线程程序执行模型</h4>
<p>在剖析Bug之前，我们先来简单回顾一下多线程程序是怎么执行的。从程序员的角度来看，一个多线程程序的执行可以看成是每个子线程的指令交错在一起共同执行的，即<a href="http://www.parallellabs.com/2010/03/06/why-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence/">Sequential Consistency</a>模型。它有两个属性：每个线程内部的指令是按照代码指定的顺序执行的（Program Order），但是线程之间的交错顺序是任意的、不确定的（Non deterministic）。</p>
<p>我原来举过一个形象的例子。伸出你的双手，掌心面向你，两个手分别代表两个线程，从食指到小拇指的四根手指头分别代表每个线程要依次执行的四条指令。<br />
（1）对每个手来说，它的四条指令的执行顺序必须是从食指执行到小拇指<br />
（2）你两个手的八条指令（八个手指头）可以在满足（1）的条件下任意交错执行（例如可以是左1，左2，右1，右2，右3，左3，左4，右4，也可以是左1，左2，左3，左4，右1，右2，右3，右4，也可以是右1，右2，右3，左1，左2，右4，左3，左4等等等等）</p>
<p>好了，现在让我们来看看程序员在写多线程程序时是怎么犯错的。</p>
<h4>2. 违反原子性（Atomicity Violation）</h4>
<p>何谓原子性？简单的说就是不可被其他线程分割的操作。大部分程序员在编写多线程程序员时仍然是按照串行思维来思考，他们习惯性的认为一些简单的代码肯定是原子的。</p>
<p>例如：</p>
<pre class="brush: cpp; title: ; notranslate">
	Thread 1						Thread 2
S1: if (thd-&gt;proc_info)				...
{							S3: thd-&gt;proc_info=NULL;
  S2: fputs(thd-&gt;proc_info,...)
}
</pre>
<p>这个来自MySQL的Bug的根源就在于程序员误认为，线程1在执行S1时如果从thd->proc_info读到的是一个非空的值的话，在执行S2时thd->proc_info的值肯定也还是非空的，所以可以调用fputs()进行操作。事实上，{S1,S2}<strong>组合到一起之后</strong>并不是原子操作，所以它们可能被线程2的S3打断，即按S1->S3->S2的顺序执行，从而导致线程1运行到S2时出错（注意，虽然这个Bug是因为多线程程序执行顺序的不确定性造成的，可是它违反的是程序员对这段代码是原子的期望，所以这个Bug不属于违反顺序性的Bug）。</p>
<p>这个例子的对象是两条语句，所以很容易看出来它们的组合不是原子的。事实上，有些看起来像是原子操作的代码其实也不是原子的。最著名的莫过于多个线程执行类似<a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/">“x++”这样的操作</a>了。这条语句本身不是原子的，因为它在大部分硬件平台上其实是由三条语句实现的：</p>
<pre class="brush: cpp; title: ; notranslate">
mov eax,dword ptr [x]
add eax,1
mov dword ptr [x],eax
</pre>
<p>同样，下面这个“r.Location = p”也不是原子的，因为事实上它是两个操作：“r.Location.X = p.X”和“r.Location.Y = p.Y”组成的。</p>
<pre class="brush: csharp; title: ; notranslate">
struct RoomPoint {
   public int X;
   public int Y;
}

RoomPoint p = new RoomPoint(2,3);
r.Location = p;
</pre>
<p>从根源上来讲，如果你想让这段代码真正按照你的心意来执行，你就得在脑子里仔细考虑是否会出现违反你本意的执行顺序，特别是涉及的变量（例如thd->proc_info）在其他线程中有可能被修改的情况，也就是数据竞争（Data Race）[注1]。如果有两个线程同时对同一个内存地址进行操作，而且它们之中至少有一个是写操作，数据竞争就发生了。</p>
<p>有时候数据竞争可是隐藏的很深的，例如下面的Parallel.For看似很正常：</p>
<pre class="brush: csharp; title: ; notranslate">
Parallel.For(0, 10000,
    i =&gt; {a[i] = new Foo();})
</pre>
<p>实际上，如果我们去看看Foo的实现：</p>
<pre class="brush: csharp; title: ; notranslate">
class Foo {
	private static int counter;
	private int unique_id;
	public Foo()
       {
		unique_id = counter++;
       }
}
</pre>
<p>同志们，看出来哪里有数据竞争了么？是的，counter是静态变量，Foo()这个构造函数里面的counter++产生数据竞争了！想避免Atomicity Violation，其实根本上就是要保证没有数据竞争（Data Race Free）。</p>
<h4>3. Atomicity Violation的解决方案</h4>
<p>解决方案大致有三（可结合使用）：<br />
（1）把变量隔离起来：只有一个线程可以访问它（isolation）<br />
（2）把变量的属性定义为immutable的：这样它就是只读的了（immutability）<br />
（3）同步对这个变量的读写：比如用锁把它锁起来（synchronization）</p>
<p>例如下面这个例子里面x是immutable的；而a[]则通过index i隔离起来了，即不同线程处理a[]中不同的元素；</p>
<pre class="brush: csharp; title: ; notranslate">
Parallel.For(1,1000,
i =&gt; {
    a[i] = x;
});
</pre>
<p>例如下面这个例子在构造函数中给x和y赋值（此时别的线程不能访问它们），保证了isolation；一旦构造完毕x和y就是只读的了，保证了immutability。</p>
<pre class="brush: csharp; title: ; notranslate">
public class Coordinate
{
   private double x, y;

   public Coordinate(double a,
                     double b)
   {
      x = a;
      y = b;
   }
   public void GetX() {
      return x;
   }
   public void GetY() {
      return y;
   }
}
</pre>
<p>而我最开始提到的关于thd->proc_info的Bug可以通过把S1和S2两条语句用锁包起来解决（同志们，千万别忘了给S3加同一把锁，要不然还是有Bug！）。被锁保护起来的临界区在别的线程看来就是“原子”的，不可以被打断的。</p>
<pre class="brush: cpp; title: ; notranslate">
	Thread 1						Thread 2
LOCK(&amp;lock)
S1: if (thd-&gt;proc_info)				LOCK(&amp;lock);
{							S3: thd-&gt;proc_info=NULL;
  S2: fputs(thd-&gt;proc_info,...)		UNLOCK(&amp;lock);
}
UNLOCK(&amp;lock)
</pre>
<p>还有另一个用锁来同步的<a href="http://blog.csdn.net/shell_picker/archive/2010/04/28/5540619.aspx">例子</a>，即通过使用锁（Java中的synchronized关键字）来保证没有数据竞争：</p>
<p>“Java 5 中提供了 ConcurrentLinkedQueue 来简化并发操作。但是有一个问题：使用了这个类之后是否意味着我们不需要自己进行任何同步或加锁操作了呢？<br />
也就是说，如果直接使用它提供的函数，比如：queue.add(obj); 或者 queue.poll(obj);，这样我们自己不需要做任何同步。”但是，两个原子操作合起来可就不一定是原子操作了（Atomic + Atomic != Atomic），例如：</p>
<pre class="brush: java; title: ; notranslate">
if(!queue.isEmpty()) {
   queue.poll(obj);
}
</pre>
<p>事实情况就是在调用isEmpty()之后，poll()之前，这个queue没有被其他线程修改是不确定的，所以对于这种情况，我们还是需要自己同步，用加锁的方式来保证原子性（虽然这样很损害性能）：</p>
<pre class="brush: java; title: ; notranslate">
synchronized(queue) {
    if(!queue.isEmpty()) {
       queue.poll(obj);
    }
}
</pre>
<p>但是注意了，使用锁也会造成一堆Bug，死锁就先不说了，先看看初学者容易犯的一个错误（是的，我曾经也犯过这个错误），x在两个不同的临界区中被修改，加了锁跟没加一样，因为还是有数据竞争：</p>
<pre class="brush: cpp; title: ; notranslate">
int x = 0;
pthread_mutex_t lock1;
pthread_mutex_t lock2;

pthread_mutex_lock(&amp;lock1);
x++;
pthread_mutex_unlock(&amp;lock1);
...
...
pthread_mutex_lock(&amp;lock2);
x++;
pthread_mutex_unlock(&amp;lock2);
</pre>
<p>事实上，类似x++这样的操作最好的解决办法就是使用类似java.util.concurrent.atomic，Intel TBB中的atomic operation之类的方法完成，具体的例子可以参考<a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/">这篇文章</a>。</p>
<p>总结一下，不管是多条语句之间的原子性也好，单个语句（例如x++）的原子性也好都需要大家格外小心，有这种意识之后很多跟Atomicity Violation相关的Bug就可以被避免了。其实归根结底，我们最终是想让多线程程序按照你的意愿正确的执行，所以在清楚什么样的情形可能让你的多线程程序不能按你所想的那样执行之后我们就能有意识的避免它们了（或者更加容易的修复它们）。<a href="http://www.parallellabs.com/2010/11/23/concurrency-bugs-2/" target="_blank">下一篇文章</a>我们再来仔细分析下Ordering Violation。</p>
<p>[注1] 严格意义上来讲，Data Race只是Atomicity Violation的一个特例，Data Race Free不能保证一定不会出现Atomicity Violation。例如文中Java实现的那个Concurrent Queue的例子，严格意义上来讲它并没有data race，因为isEmpty()和poll()都是线程安全的调用，只不过它们<strong>组合起来</strong>之后会出现违反程序员本意的Atomicity Violation，所以要用锁保护起来。</p>
<p>P.S. 参考文献中的前两篇是<a href="http://cseweb.ucsd.edu/~yyzhou/" target="_blank">YuanYuan Zhou</a>教授的得意门生<a href="http://pages.cs.wisc.edu/~shanlu/" target="_blank">Dr. Shan Lu</a>的论文，后者现在已经是Wisconsin–Madison的教授了。</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E5%B8%B8%E8%A7%81Bug%E5%89%96%E6%9E%90%EF%BC%88%E4%B8%8A%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F13%2Fconcurrency-bugs-1%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E5%B8%B8%E8%A7%81Bug%E5%89%96%E6%9E%90%EF%BC%88%E4%B8%8A%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F11%2F13%2Fconcurrency-bugs-1%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li><li>11/23/2010 -- <a href="http://www.parallellabs.com/2010/11/23/concurrency-bugs-2/" title="多线程程序常见Bug剖析（下）">多线程程序常见Bug剖析（下）</a></li><li>04/15/2010 -- <a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/" title="多线程程序中操作的原子性">多线程程序中操作的原子性</a></li><li>01/31/2010 -- <a href="http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/" title="Pthreads并行编程之spin lock与mutex性能对比分析">Pthreads并行编程之spin lock与mutex性能对比分析</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/11/13/concurrency-bugs-1/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>史蒂夫乔布斯(Steve Jobs)在Stanford2005年毕业典礼上的演讲</title>
		<link>http://www.parallellabs.com/2010/10/27/steve-jobs-talked-in-stanford-2005/</link>
		<comments>http://www.parallellabs.com/2010/10/27/steve-jobs-talked-in-stanford-2005/#comments</comments>
		<pubDate>Tue, 26 Oct 2010 18:13:22 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[职业生涯]]></category>
		<category><![CDATA[jobs]]></category>
		<category><![CDATA[瑞典]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=736</guid>
		<description><![CDATA[我觉得这是我看过的最好的演讲之一。三个故事每一个都让我深受触动。

<a href="http://www.parallellabs.com/2010/10/27/steve-jobs-talked-in-stanford-2005/"  >阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%8F%B2%E8%92%82%E5%A4%AB%E4%B9%94%E5%B8%83%E6%96%AF%28Steve+Jobs%29%E5%9C%A8Stanford2005%E5%B9%B4%E6%AF%95%E4%B8%9A%E5%85%B8%E7%A4%BC%E4%B8%8A%E7%9A%84%E6%BC%94%E8%AE%B2&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F27%2Fsteve-jobs-talked-in-stanford-2005%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%8F%B2%E8%92%82%E5%A4%AB%E4%B9%94%E5%B8%83%E6%96%AF%28Steve+Jobs%29%E5%9C%A8Stanford2005%E5%B9%B4%E6%AF%95%E4%B8%9A%E5%85%B8%E7%A4%BC%E4%B8%8A%E7%9A%84%E6%BC%94%E8%AE%B2&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F27%2Fsteve-jobs-talked-in-stanford-2005%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p><embed src="http://player.youku.com/player.php/sid/XMTM3OTM5OTA0/v.swf" quality="high" width="480" height="400" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash"></embed></p>
<p>我觉得这是我看过的最好的演讲之一。三个故事每一个都让我深受触动。</p>
<p>这句话让我忍不住留下眼泪：<br />
“And most important, have the courage to follow your heart and intuition. They somehow already know what you truly want to become. Everything else is secondary.”<br />
“还有最重要的是, 你要有勇气去听从你直觉和心灵的指示——它们在某种程度上知道你想要成为什么样子，所有其他的事情都是次要的。 ”</p>
<p>今天我老板<a href="http://129.16.20.23/~pers/">Prof. Per Stenström</a>也跟我说：<br />
“Keep the focus on what you believe in and keep delivering what you promised yourself to deliver. Your contributions will not only be rewarding for yourself;  it will likely make a significant contribution to our society.”</p>
<p>博士与工业界之间我选择了后者，在即将毕业之时，我热切期待着下一个让我成长的机会，每个人都应该寻找并追寻自己内心最深切的渴望，Stay hungry, Stay foolish!</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%8F%B2%E8%92%82%E5%A4%AB%E4%B9%94%E5%B8%83%E6%96%AF%28Steve+Jobs%29%E5%9C%A8Stanford2005%E5%B9%B4%E6%AF%95%E4%B8%9A%E5%85%B8%E7%A4%BC%E4%B8%8A%E7%9A%84%E6%BC%94%E8%AE%B2&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F27%2Fsteve-jobs-talked-in-stanford-2005%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%8F%B2%E8%92%82%E5%A4%AB%E4%B9%94%E5%B8%83%E6%96%AF%28Steve+Jobs%29%E5%9C%A8Stanford2005%E5%B9%B4%E6%AF%95%E4%B8%9A%E5%85%B8%E7%A4%BC%E4%B8%8A%E7%9A%84%E6%BC%94%E8%AE%B2&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F27%2Fsteve-jobs-talked-in-stanford-2005%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>11/29/2010 -- <a href="http://www.parallellabs.com/2010/11/29/erlang-user-conference-2010-and-some-thoughts-on-career-of-programmers/" title="Erlang User Conference 2010见闻（兼谈程序员职业生涯）">Erlang User Conference 2010见闻（兼谈程序员职业生涯）</a></li><li>05/04/2010 -- <a href="http://www.parallellabs.com/2010/05/04/swedish-programmer/" title="聊一聊瑞典的程序员">聊一聊瑞典的程序员</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/10/27/steve-jobs-talked-in-stanford-2005/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>多线程队列的算法优化</title>
		<link>http://www.parallellabs.com/2010/10/25/practical-concurrent-queue-algorithm/</link>
		<comments>http://www.parallellabs.com/2010/10/25/practical-concurrent-queue-algorithm/#comments</comments>
		<pubDate>Sun, 24 Oct 2010 16:52:57 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[算法学习]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[queue]]></category>
		<category><![CDATA[多线程编程]]></category>
		<category><![CDATA[性能分析]]></category>
		<category><![CDATA[死锁]]></category>
		<category><![CDATA[线程安全]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=680</guid>
		<description><![CDATA[多线程队列（Concurrent Queue）的使用场合非常多，高性能服务器中的消息队列，并行算法中的Work Stealing等都离不开它。对于一个队列来说有两个最主要的动作：添加（enqueue）和删除（dequeue）节点。在一个（或多个）线程在对一个队列进行enqueue操作的同时可能会有一个（或多个）线程对这个队列进行dequeue操作。因为enqueue和dequeue都是对同一个队列里的节点进行操作，为了保证线程安全，一般在实现中都会在队列的结构体中加入一个队列锁（典型的如pthread_mutex_t q_lock），在进行enqueue和dequeue时都会先锁住这个锁以锁住整个队列然后再进行相关的操作。这样的设计如果实现的好的话一般性能就会很不错了。但是它其实有一个潜在的性能瓶颈，导致在线程数增多时极大的影响多线程程序的性能。

<a <a href="http://www.parallellabs.com/2010/10/25/practical-concurrent-queue-algorithm/" >阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E9%98%9F%E5%88%97%E7%9A%84%E7%AE%97%E6%B3%95%E4%BC%98%E5%8C%96&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F25%2Fpractical-concurrent-queue-algorithm%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E9%98%9F%E5%88%97%E7%9A%84%E7%AE%97%E6%B3%95%E4%BC%98%E5%8C%96&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F25%2Fpractical-concurrent-queue-algorithm%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>多线程队列（Concurrent Queue）的使用场合非常多，高性能服务器中的消息队列，并行算法中的Work Stealing等都离不开它。对于一个队列来说有两个最主要的动作：添加（enqueue）和删除（dequeue）节点。在一个（或多个）线程在对一个队列进行enqueue操作的同时可能会有一个（或多个）线程对这个队列进行dequeue操作。因为enqueue和dequeue都是对同一个队列里的节点进行操作，为了保证线程安全，一般在实现中都会在队列的结构体中加入一个队列锁（典型的如pthread_mutex_t q_lock），在进行enqueue和dequeue时都会先锁住这个锁以锁住整个队列然后再进行相关的操作。这样的设计如果实现的好的话一般性能就会很不错了。以链表实现的队列的结构体一般是这样的：</p>
<pre class="brush: cpp; title: ; notranslate">
struct queue_t {
    node_t *head;
    node_t *tail;
    pthread_mutex_t q_lock;
};
</pre>
<p>但是，这其中其实有一个潜在的性能瓶颈：enqueue和dequeue操作都要锁住整个队列，这在线程少的时候可能没什么问题，但是只要线程数一多，这个锁竞争所产生的性能瓶颈就会越来越严重。那么我们可不可以想办法优化一下这个算法呢？当然可以！如果我们仔细想一想enqueue和dequeue的具体操作就会发现他们的操作其实不一定是冲突的。例如：如果所有的enqueue操作都是往队列的尾部插入新节点，而所有的dequeue操作都是从队列的头部删除节点，那么enqueue和dequeue大部分时候都是相互独立的，我们大部分时候根本不需要锁住整个队列，白白损失性能！那么一个很自然就能想到的算法优化方案就呼之欲出了：我们可以把那个队列锁拆成两个：一个队列头部锁（head lock)和一个队列尾部锁(tail lock)。这样这样的设计思路是对了，但是如果再仔细思考一下它的实现的话我们会发现其实不太容易，因为有两个特殊情况非常的tricky（难搞）：第一种就是往空队列里插入第一个节点的时候，第二种就是从只剩最后一个节点的队列中删除那个“最后的果实”的时候。</p>
<p>为什么难搞呢？当我们向空队列中插入第一个节点的时候，我们需要同时修改队列的head和tail指针，使他们同时指向这个新插入的节点，换句话说，我们此时即需要拿到head lock又需要拿到tail lock。而另一种情况是对只剩一个节点的队列进行dequeue的时候，我们也是需要同时修改head和tail指针使他们指向NULL，亦即我们需要同时获得head和tail lock。有经验的同学会立刻发现我们进入危险区了！是什么危险呢？死锁！多线程编程中最臭名昭著的一种bug就是死锁了。例如，如果线程A在锁住了资源1后还想要获取资源2，而线程B在锁住了资源2后还想要获取资源1，这时两个线程谁都不能获得自己想要的那个资源，两个线程就死锁了。所以我们要小心奕奕的设计这个算法以避免死锁，例如保证enqueue和dequeue对head lock和tail lock的请求顺序（lock ordering）是一致的等等。但是这样设计出来的算法很容易就会包含多次的加锁/解锁操作，这些都会造成不必要的开销，尤其是在线程数很多的情况下反而可能导致性能的下降。我的亲身经历就是在32线程时这个思路设计出来的算法性能反而下降了10%左右，原因就是加锁/解锁的开销增加了。</p>
<p>好在有聪明人早在96年就想到了一个更妙的算法。这个算法也是用了head和tail两个锁，但是它有一个关键的地方是它在队列初始化的时候head和tail指针不为空，而是指向一个空节点。在enqueue的时候只要向队列尾部添加新节点就好了。而dequeue的情况稍微复杂点，它要返回的不是头节点，而是head->next，即头节点的下一个节点。先来看伪代码：</p>
<pre class="brush: cpp; title: ; notranslate">
typedef struct node_t {
    TYPE value;
    node_t *next
} NODE;

typedef struct queue_t {
    NODE *head;
    NODE *tail;
    LOCK q_h_lock;
    LOCK q_t_lock;
} Q;

initialize(Q *q) {
   node = new_node()   // Allocate a free node
   node-&gt;next = NULL   // Make it the only node in the linked list
   q-&gt;head = q-&gt;tail = node	// Both head and tail point to it
   q-&gt;q_h_lock = q-&gt;q_t_lock = FREE   // Locks are initially free
}

enqueue(Q *q, TYPE value) {
   node = new_node()       // Allocate a new node from the free list
   node-&gt;value = value	  // Copy enqueued value into node
   node-&gt;next = NULL       // Set next pointer of node to NULL
   lock(&amp;q-&gt;q_t_lock)	  // Acquire t_lock in order to access Tail
      q-&gt;tail-&gt;next = node // Link node at the end of the queue
      q-&gt;tail = node       // Swing Tail to node
   unlock(&amp;q-&gt;q_t_lock)    // Release t_lock
｝

dequeue(Q *q, TYPE *pvalue) {
   lock(&amp;q-&gt;q_h_lock)   // Acquire h_lock in order to access Head
      node = q-&gt;head    // Read Head
      new_head = node-&gt;next	     // Read next pointer
      if new_head == NULL         // Is queue empty?
         unlock(&amp;q-&gt;q_h_lock)     // Release h_lock before return
         return FALSE             // Queue was empty
      endif
      *pvalue = new_head-&gt;value   // Queue not empty, read value
      q-&gt;head = new_head  // Swing Head to next node
   unlock(&amp;q-&gt;q_h_lock)   // Release h_lock
   free(node)			  // Free node
   return TRUE			  // Queue was not empty, dequeue succeeded
}
</pre>
<p>发现玄机了么？是的，这个算法中队列总会包含至少一个节点。dequeue每次返回的不是头节点，而是头节点的下一个节点中的数据：如果head->next不为空的话就把这个节点的数据取出来作为返回值，同时再把head指针指向这个节点，此时旧的头节点就可以被free掉了。这个在队列初始化时插入空节点的技巧使得enqueue和dequeue彻底相互独立了。但是，还有一个小地方在实现的时候需要注意：对第一个空节点的next指针的读写。想象一下，当一个线程对一个空队列进行第一次enqueue操作时刚刚运行完第25行的代码（对该空节点的next指针进行写操作）；而此时另一个线程对这个队列进行第一次dequeue操作时恰好运行到第33行（对该空节点的next指针进行读操作），它们其实还是有冲突！不过，好在一般来讲next指针是32位数据，而现代的CPU已经能保证多线程程序中内存对齐了的32位数据<a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/">读写操作的原子性</a>，而一般来讲编译器会自动帮你对齐32位数据，所以这个不是问题。唯一需要注意的是我们要确保enqueue线程是先让要添加的新节点包含好数据再把新节点插入链表（也就是不能先插入空节点，再往节点中填入数据），那么dequeue线程就不会拿到空的节点。其实我们也可以把q_t_lock理解成生产者的锁，q_h_lock理解成消费者的锁，这样生产者（们）和消费者（们）的操作就相互独立了，只有在多个生产者对同一队列进行添加操作时，以及多个消费者对同一队列进行删除操作时才需要加锁以使访问互斥。</p>
<p>通过使用这个算法，我成功的把一个32线程程序的性能提升了11%！可见多线程中的锁竞争对性能影响之大！此算法出自一篇著名的论文：M. Michael and M. Scott. <a href="http://www.cs.rochester.edu/research/synchronization/pseudocode/queues.html" target="_blank">Simple, Fast, and Practical Non-Blocking and Blocking Concurren Queue Algorithms</a>. 如果还想做更多优化的话可以参考这篇论文实现相应的Non Blocking版本的算法，性能还能有更多提升。当然了，这个算法早已被集成到java.util.concurrent里了（即LinkedBlockingQueue），其他的并行库例如Intel的TBB多半也有类似的算法，如果大家能用上现成的库的话就不要再重复造轮子了。为什么别造并行算法的轮子呢？因为高性能的并行算法实在太难正确地实现了，尤其是Non Blocking，Lock Free之类的“火箭工程”。有多难呢？Doug Lea提到java.util.concurrent中一个Non Blocking的算法的实现大概需要1年的时间，总共约500行代码。所以，对最广大的程序员来说，别去写Non Blocking, Lock Free的代码，只管用就行了，我看见网上很多的Non Blocking阿，无锁编程的算法实现啊什么的都非常地害怕，谁敢去用他们贴出来的这些代码啊？我之所以推荐这个two lock的算法是因为它的实现相对Non Blocking之类的来说容易多了，非常具备实用价值。虽然这篇论文出现的很早，但是我在看了几个开源软件中多线程队列的实现之后发现他们很多还是用的本文最开始提到的那种一个锁的算法。如果你想要实现更高性能的多线程队列的话，试试这个算法吧！</p>
<p>Update: 多线程队列算法有很多种，大家应根据不同的应用场合选取最优算法（例如是CPU密集型还是IO密集型）。本文所列的算法应用在这样一个多线程程序中：每个线程都拥有一个队列，每个队列可能被本线程进行dequeue操作，也可以被其他线程进行dequeue（即work stealing），线程数不超过CPU核心数，是一个典型的CPU/MEM密集型客户端单写者多读者场景。</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E9%98%9F%E5%88%97%E7%9A%84%E7%AE%97%E6%B3%95%E4%BC%98%E5%8C%96&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F25%2Fpractical-concurrent-queue-algorithm%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E9%98%9F%E5%88%97%E7%9A%84%E7%AE%97%E6%B3%95%E4%BC%98%E5%8C%96&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F25%2Fpractical-concurrent-queue-algorithm%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li><li>04/09/2011 -- <a href="http://www.parallellabs.com/2011/04/09/pthread-mutex-lock-and-thread-safety/" title="《程序员的自我修养》中关于加锁不能保证线程安全的一个错误">《程序员的自我修养》中关于加锁不能保证线程安全的一个错误</a></li><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>04/15/2010 -- <a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/" title="多线程程序中操作的原子性">多线程程序中操作的原子性</a></li><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/10/25/practical-concurrent-queue-algorithm/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Google创始人的求职目标</title>
		<link>http://www.parallellabs.com/2010/10/13/objective-of-sergey-brin/</link>
		<comments>http://www.parallellabs.com/2010/10/13/objective-of-sergey-brin/#comments</comments>
		<pubDate>Wed, 13 Oct 2010 00:08:53 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[职业生涯]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=656</guid>
		<description><![CDATA[想知道Google创始人之一的谢尔盖·布林学生时代的求职目标么？

在他Stanford的主页上的一段被注释掉了的html代码透露了他的秘密。

<a href="http://www.parallellabs.com/2010/10/13/objective-of-sergey-brin/"  >阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Google%E5%88%9B%E5%A7%8B%E4%BA%BA%E7%9A%84%E6%B1%82%E8%81%8C%E7%9B%AE%E6%A0%87&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F13%2Fobjective-of-sergey-brin%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Google%E5%88%9B%E5%A7%8B%E4%BA%BA%E7%9A%84%E6%B1%82%E8%81%8C%E7%9B%AE%E6%A0%87&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F13%2Fobjective-of-sergey-brin%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>想知道Google创始人之一的谢尔盖·布林学生时代的求职目标么？</p>
<p>在他Stanford的resume页面上的一段被注释掉了的html代码透露了他的秘密：</p>
<pre class="brush: xml; title: ; notranslate">&lt;!--&lt;H4&gt;Objective:&lt;/H4&gt;
A large office, good pay, and very little work.
Frequent expense-account trips to exotic lands would be a plus.--&gt; </pre>
<p><a href="http://infolab.stanford.edu/~sergey/resume.html">瞻仰遗址</a>。</p>
<p>此八卦来自威武的<a href="http://www.unclexia.net/?p=761" target="_blank">虾叔</a>。</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Google%E5%88%9B%E5%A7%8B%E4%BA%BA%E7%9A%84%E6%B1%82%E8%81%8C%E7%9B%AE%E6%A0%87&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F13%2Fobjective-of-sergey-brin%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Google%E5%88%9B%E5%A7%8B%E4%BA%BA%E7%9A%84%E6%B1%82%E8%81%8C%E7%9B%AE%E6%A0%87&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F13%2Fobjective-of-sergey-brin%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">最多留言日志</h2><ul class="related_post"><li>03/06/2010 -- <a href="http://www.parallellabs.com/2010/03/06/why-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence/" title="为什么程序员需要关心顺序一致性（Sequential Consistency）而不是Cache一致性（Cache Coherence？）">为什么程序员需要关心顺序一致性（Sequential Consistency）而不是Cache一致性（Cache Coherence？）</a></li><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>10/25/2010 -- <a href="http://www.parallellabs.com/2010/10/25/practical-concurrent-queue-algorithm/" title="多线程队列的算法优化">多线程队列的算法优化</a></li><li>11/29/2010 -- <a href="http://www.parallellabs.com/2010/11/29/erlang-user-conference-2010-and-some-thoughts-on-career-of-programmers/" title="Erlang User Conference 2010见闻（兼谈程序员职业生涯）">Erlang User Conference 2010见闻（兼谈程序员职业生涯）</a></li><li>04/09/2011 -- <a href="http://www.parallellabs.com/2011/04/09/pthread-mutex-lock-and-thread-safety/" title="《程序员的自我修养》中关于加锁不能保证线程安全的一个错误">《程序员的自我修养》中关于加锁不能保证线程安全的一个错误</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/10/13/objective-of-sergey-brin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>多核的未来</title>
		<link>http://www.parallellabs.com/2010/10/03/future-multiprocessors/</link>
		<comments>http://www.parallellabs.com/2010/10/03/future-multiprocessors/#comments</comments>
		<pubDate>Sat, 02 Oct 2010 16:13:43 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[Chalmers]]></category>
		<category><![CDATA[业界评论]]></category>
		<category><![CDATA[多核]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=635</guid>
		<description><![CDATA[UT Austin的<a href="https://hostdb.ece.utexas.edu/~patt/">Yale Patt</a>教授上个月来Chalmers交流，做了题为《Future Microprocessors: Multi-core, Mega-nonsense, and What We Must Do Differently Moving Forward》的讲座。Yale Patt是计算机体系结构学术圈的巨擘，他最有名的研究成果是和Branch Predictor和HPS microarchitecture，他的学生们也巨牛无比，学术界有名的有UIUC的Wen-Mei Hwu，CMU的Onur Mutlu等等，工业界Intel不少核心工程师也出自他的门下。这个讲座主要谈了他对未来的多核处理器的发展的看法，有趣的是他二十年前也预测过现在的处理器，我还专门问了他当时的预测是否靠谱，他说“那我得回去查查看才行”,人非常的Nice。

<a></a><a href="http://www.parallellabs.com/2010/10/03/future-multiprocessors/" >阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%9A%84%E6%9C%AA%E6%9D%A5&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F03%2Ffuture-multiprocessors%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%9A%84%E6%9C%AA%E6%9D%A5&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F03%2Ffuture-multiprocessors%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>UT Austin的<a href="https://hostdb.ece.utexas.edu/~patt/">Yale Patt</a>教授上个月来Chalmers交流，做了题为《Future Microprocessors: Multi-core, Mega-nonsense, and What We Must Do Differently Moving Forward》的讲座。Yale Patt是计算机体系结构学术圈的巨擘，他最有名的研究成果是和Branch Predictor和HPS microarchitecture，他的学生们也巨牛无比，学术界有名的有UIUC的Wen-Mei Hwu，CMU的Onur Mutlu等等，工业界Intel不少核心工程师也出自他的门下。这个讲座主要谈了他对未来的多核处理器的发展的看法，有趣的是他二十年前也预测过现在的处理器，我还专门问了他当时的预测是否靠谱，他说“那我得回去查查看才行”,人非常的Nice。</p>
<p>简单介绍一下关键的几点：</p>
<p>1. 为什么要多核？<br />
It is easier than designing a much better uni-core<br />
It is cheaper than designing a much better uni-core<br />
It was embarrassing to continue making L2 bigger<br />
It was the next obvious step</p>
<p>2. Asymmetric Chip Multiprocessor才是未来<br />
一个chip上既有Large Core，又有Small Core，前者专门用来加速那些诸如Critical Section之类的串行代码。</p>
<p>3. ILP未死<br />
其实还有ILP的性能很多可挖掘的空间，只是多核设计上更经济更简单，所以大家都慢慢转到多核上来了</p>
<p>4. Parallel Programming is NOT Hard<br />
如果从新生就开始进行并行编程的教育，从一开始就thinking in parallel，并行编程就不难，关键是打破Abstraction。</p>
<p>UIUC的<a href="http://www.parallel.illinois.edu/dls_archive.html">Distinguished Lecture Series</a>也有他今年4月在UIUC的讲座，甚至还有video。</p>
<p>Enjoy!</p>
<div style="width:425px" id="__ss_5342231"><strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/parallellabs/chalmers-microprocessor-sept-2010" title="Chalmers microprocessor sept 2010">Chalmers microprocessor sept 2010</a></strong><object id="__sse5342231" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=chalmersmicroprocessorsept2010-101002163458-phpapp01&#038;stripped_title=chalmers-microprocessor-sept-2010&#038;userName=parallellabs" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed name="__sse5342231" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=chalmersmicroprocessorsept2010-101002163458-phpapp01&#038;stripped_title=chalmers-microprocessor-sept-2010&#038;userName=parallellabs" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object>
<div style="padding:5px 0 12px">View more <a href="http://www.slideshare.net/">presentations</a> from <a href="http://www.slideshare.net/parallellabs">parallellabs</a>.</div>
</div>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%9A%84%E6%9C%AA%E6%9D%A5&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F03%2Ffuture-multiprocessors%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%9A%84%E6%9C%AA%E6%9D%A5&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F10%2F03%2Ffuture-multiprocessors%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>12/28/2010 -- <a href="http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices/" title="移动设备进入多核时代！">移动设备进入多核时代！</a></li><li>09/20/2010 -- <a href="http://www.parallellabs.com/2010/09/20/the-trouble-with-multicore-2/" title="多核编程的难题（二）">多核编程的难题（二）</a></li><li>08/17/2010 -- <a href="http://www.parallellabs.com/2010/08/17/the-trouble-with-multicore/" title="多核编程的难题（一）">多核编程的难题（一）</a></li><li>04/01/2010 -- <a href="http://www.parallellabs.com/2010/04/01/the-third-software-crisis/" title="第三次软件危机">第三次软件危机</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/10/03/future-multiprocessors/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>多核编程的难题（二）</title>
		<link>http://www.parallellabs.com/2010/09/20/the-trouble-with-multicore-2/</link>
		<comments>http://www.parallellabs.com/2010/09/20/the-trouble-with-multicore-2/#comments</comments>
		<pubDate>Mon, 20 Sep 2010 04:11:06 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[业界评论]]></category>
		<category><![CDATA[并行编程]]></category>
		<category><![CDATA[多核]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=620</guid>
		<description><![CDATA[刚刚过去的一个月一直都在忙着赶实验赶论文，直到前几天完成一篇短论文的写作才得以抽身来补上这一篇关于多核的曙光的文章。我将分几个方面来阐述一下我对多核上并行编程持乐观态度的原因。

1. 较易并行化的应用
如果一个应用的子任务之间依赖关系比较小，相互独立性强，那么它就具有很好的可并行性。很容易我们就会想到服务端的应用。服务端应用的特征就是为多用户提供相似的服务，因为它本身具有内在的并行性，所以相比那些子任务之间依赖性很强的应用来说，它们是比较适合多核的。这些应用常见的例子有大型数据库、飞机票预订系统、银行交易系统、网络搜索、游戏服务器以及云计算所提供的软件即服务（SaaS）等等。

<a></a><a href="http://www.parallellabs.com/2010/09/20/the-trouble-with-multicore-2/" >阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%BC%96%E7%A8%8B%E7%9A%84%E9%9A%BE%E9%A2%98%EF%BC%88%E4%BA%8C%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F09%2F20%2Fthe-trouble-with-multicore-2%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%BC%96%E7%A8%8B%E7%9A%84%E9%9A%BE%E9%A2%98%EF%BC%88%E4%BA%8C%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F09%2F20%2Fthe-trouble-with-multicore-2%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>刚刚过去的一个月一直都在忙着赶实验赶论文，直到前几天完成一篇短论文的写作才得以抽身来补上这一篇关于多核的曙光的文章。我将分几个方面来阐述一下我对多核上并行编程持乐观态度的原因。</p>
<h3>1. 较易并行化的应用</h3>
<p>如果一个应用的子任务之间依赖关系比较小，相互独立性强，那么它就具有很好的可并行性。很容易我们就会想到服务端的应用。服务端应用的特征就是为多用户提供相似的服务，因为它本身具有内在的并行性，所以相比那些子任务之间依赖性很强的应用来说，它们是比较适合多核的。这些应用常见的例子有大型数据库、飞机票预订系统、银行交易系统、网络搜索、游戏服务器以及云计算所提供的软件即服务（SaaS）等等。</p>
<p>另一种大量采用并行化的成功案例就是图像处理了。举个简单的例子，渲染一幅图像这个任务就充满了大量的数据级并行（data-level parallelism）：一幅图像是由许许多多的像素组成的，而现在的GPU都有成百个核心，我们可以比较容易的做到让每个GPU核心分别负责渲染图像的一部分，从而快速的完成整个计算任务。虽然现在来讲GPU上面的编程很难，但是它所能提供的性能提升确实非常可观。</p>
<p>还有很火的GPGPU应用（General-purpost computing on GPU），它们在Scientific Computing领域也有不少成功案例，虽然John Carmack就在Twitter上对GPGPU编程的困难性这样评价过：“Hundreds of GPGPU research papers valiantly struggling with graphic API limitations are painfully obsolete with CUDA / OpenCL available.”其实Scientific Computing可以算是多核上的杀手级应用了，典型的例如天气预测、气候模拟等运用，为了得到更精确的结果肯定就需要处理更多的数据，而且是必须在短时间内出结果，要不然你预测后天的天气但是一个礼拜才给你出结果怎么行？这些大数据量的计算任务对性能的需求永远都是非常大的。而且这些应用本身有很多数据级的并行性，再加上这个领域一般都是行业专家和软件工程师的组合，大规模的应用并行计算是很自然的事情。</p>
<h3>2. 我们有持乐观态度的理由</h3>
<p>为什么我们可以对多核发展持乐观态度？因为第一点，现在整个工业界、学术界都在研究多核，研究怎样简化并行编程、怎样降低功耗、怎样持续提升性能。Intel和Microsoft资助UIUC和UC Berkeley建立了两个重点实验室，其他顶级研究机构对多核的研究也如火如荼，大量最顶尖的人才都在帮助普及并行计算。第二点，Motivation，即“动机”。免费午餐都结束了，想继续提升性能？你只能进行并行编程。不管是客户端应用也好服务器端应用也好，用户对性能的需求肯定是不会停止的。当并行编程成为持续提升性能的唯一选择时，再困难你也得去做对不对？不过大家不用特别担心，对广大的程序员来讲，一项新技术的普及本身就是需要时间的，现在来讲大量帮助程序员进行并行编程的软硬件工具都在处在发展阶段，我们有理由相信并行编程会更容易更大众。</p>
<h3>3. 多核的发展趋势</h3>
<p>9月初我去参加斯德哥尔摩举办的<a href="http://www.sics.se/multicore2010/presentations" target="_blank">Multicore Day</a>时听了一位在Intel负责Nehalem的首席工程师的演讲，里面有几点我记忆深刻：<br />
（1）单核的性能仍在提升<br />
虽然整个工业界主题是往多核发展，但是处理器的单线程性能仍然在持续提升，这是由需求决定的。例如Nehalem架构的i7的单线程性能是奔4的5倍，这一需求也在Google在Micro 2010的论文”<a href="http://www.google.com/research/pubs/archive/36448.pdf">Brawny cores still beat wimpy cores, most of the time</a>“中得到印证。这篇文章的核心观点就是性能较弱但是功耗较低的”小号“处理器只有在它们的单核性能接近中档的”大号“处理器时才具有足够的竞争力，否则它们羸弱的单核性能会成为Google现有应用中的性能瓶颈。虽然当初整个业界因为单核性能提升太困难而被迫转向更易实施的多核<br />
（2）CPU和GPU的融合趋势<br />
现在业界已经认同GPU比CPU更适合做数据级并行，而且这类应用需求量很大，这种需求就催生了Intel的Larrabee项目。虽然Larrabee流产了，但是它的技术还在，以后迟早会出现在Intel的产品线上。为了追求更高的性能，GPU和CPU结合的方案会是最好的选择，当然，怎样在这样的硬件上编程又是一个很大的难题。<br />
（3）性能与功耗都重要<br />
Intel的工程师一直在努力确保处理器的性能提升的同时它的功耗也一直在稳步下降。为什么说功耗很重要？我们可以举个很简单的例子，笔记本电脑上运行PowerPoint的速度已经很快了，让PowerPoint运行速度快个一两倍其实并不那么重要，但是如果在保证它运行速度的同时还能让笔记本的续航时间提升一些，这就很有意义了。服务器端更不用说了，现在哪个数据中心不把功耗当做头等大事来考虑？</p>
<h3>4. 并行编程的普及教育</h3>
<p>虽然说传统的应用一直都以串行计算为背景，所以现在来讲大家普遍觉得并行编程很困难。但是我们换个思路看看：如果从大一开始我们就教新生《并行算法》《并行编程导论》呢？如果程序员一开始就接受的是并行编程的教育，并行编程还是困难的吗？其实我们整个世界本身就充满了并行，人可以同时听课和做笔记，同时吃饭和交流，而计算机硬件更是可以并行工作，为什么软件就不可以？算法导论最新的第三版专门添加了一章<a href="http://blog.csdn.net/hoping/archive/2010/02/25/5326354.aspx" target="_blank">《多线程算法》</a>，（该书其中一位作者Prof. Charles Leiserson创办的并行编程的公司Cilk Art也已被Intel收购）让我大胆想象一下，整本算法导论通篇都是“并行”的时代还会远吗？</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%BC%96%E7%A8%8B%E7%9A%84%E9%9A%BE%E9%A2%98%EF%BC%88%E4%BA%8C%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F09%2F20%2Fthe-trouble-with-multicore-2%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%BC%96%E7%A8%8B%E7%9A%84%E9%9A%BE%E9%A2%98%EF%BC%88%E4%BA%8C%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F09%2F20%2Fthe-trouble-with-multicore-2%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>12/28/2010 -- <a href="http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices/" title="移动设备进入多核时代！">移动设备进入多核时代！</a></li><li>10/03/2010 -- <a href="http://www.parallellabs.com/2010/10/03/future-multiprocessors/" title="多核的未来">多核的未来</a></li><li>08/17/2010 -- <a href="http://www.parallellabs.com/2010/08/17/the-trouble-with-multicore/" title="多核编程的难题（一）">多核编程的难题（一）</a></li><li>04/01/2010 -- <a href="http://www.parallellabs.com/2010/04/01/the-third-software-crisis/" title="第三次软件危机">第三次软件危机</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/09/20/the-trouble-with-multicore-2/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>多核编程的难题（一）</title>
		<link>http://www.parallellabs.com/2010/08/17/the-trouble-with-multicore/</link>
		<comments>http://www.parallellabs.com/2010/08/17/the-trouble-with-multicore/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 04:49:14 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[业界评论]]></category>
		<category><![CDATA[并行编程]]></category>
		<category><![CDATA[多核]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=611</guid>
		<description><![CDATA[最近David Patterson老爷子（就是计算机体系结构--量化方法的作者之一）发表了一篇文章《The trouble with multicore》，文章高屋建瓴的分析了一下多核发展的当前形势，文章开篇就说了一句话“造芯片的家伙们正忙着生产那些大多数程序员不知道如何编程的多核CPU”。这不由的让我想起我跟我导师Per Stenstrom的一次对话，我问他说“现在多核出来了，有一大堆新的难题等着我们去解决，作为研究人员您是否觉得很兴奋呢？”结果他说“其实我还是有点沮丧的，因为我们是被迫转到多核上来的。”

<a <a href="http://www.parallellabs.com/2010/08/17/the-trouble-with-multicore/">阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%BC%96%E7%A8%8B%E7%9A%84%E9%9A%BE%E9%A2%98%EF%BC%88%E4%B8%80%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F08%2F17%2Fthe-trouble-with-multicore%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%BC%96%E7%A8%8B%E7%9A%84%E9%9A%BE%E9%A2%98%EF%BC%88%E4%B8%80%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F08%2F17%2Fthe-trouble-with-multicore%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>最近David Patterson老爷子（就是计算机体系结构&#8211;量化方法的作者之一）发表了一篇文章《<a href="http://spectrum.ieee.org/computing/software/the-trouble-with-multicore" target="_blank">The trouble with multicore</a>》，文章高屋建瓴的分析了一下多核发展的当前形势，文章开篇就说了一句话“造芯片的家伙们正忙着生产那些大多数程序员不知道如何编程的多核CPU”。这不由的让我想起我跟我导师Per Stenstrom的一次对话，我问他说“现在多核出来了，有一大堆新的难题等着我们去解决，作为研究人员您是否觉得很兴奋呢？”结果他说“其实我还是有点沮丧的，因为我们是被迫转到多核上来的。”</p>
<p>其实这就道出了多核发展中的一个关键：造硬件的没办法在单核上继续像以前那样容易地提升性能了（有兴趣的朋友可以查下“Power Wall”），为了利用更多的晶体管提高性能，只好走多核这条路，但是在他们选择走这条路的时候，所有人都不知道该如何在多核平台上有效的进行编程，David Patterson管这个叫“Hail Mary”，简单翻译过来就是“让我们多核吧，但是该咋进行多核编程就祈祷奇迹的发生吧！”</p>
<p>好吧，为什么多核编程很困难？一个形象的例子就是把编程比作写书，理论上10个作者同时写一本书应该会比一个人写快10倍。但是他们首先要把任务均匀的分成10份，否则任务最多的那个作者会拖后腿肯定就快不了10倍了。但是呢光这个还不够，如果这个故事中的某一部分必须要在其他部分写完之后才能写，这种顺序上的依赖关系也会拖慢速度；而且10个作者的故事情节还得一致，那么他们肯定少不了沟通啊，这又慢了一点。这就是三个多核编程的最大挑战：“load balancing（负载均衡）”、“sequential dependency（顺序依赖关系）”和“synchronization（同步）”。</p>
<p>难道就没有人尝试着解决这个问题吗？有啊！从60年代开始，一堆一堆的天才们尝试着创造新的编程语言好让并行编程更加美好：APL，Id，Linda，Occam，SISAL等等，他们中有的确实让并行编程更加容易了，但是没有一个人能成功的让他们向传统的串行编程语言一样兼具性能、效率和灵活性，更没有像C/C++、Java这样主要为串行编程设计的语言一样流行。我记得有人问过“Java的并发包挺好用的啊，是不是足够解决多核编程的问题了呢？”，我觉得不然。在语言上进行并行编程的扩展确实是有效的办法，但是它却不能从根本上解决并行编程困难的问题。最根本的原因是这些语言并不是天生为并发而设计的，这就决定了所有的库都只能给你提供并行编程最原始的工具，但是对程序员来说并行编程却并没有因为有了这些库就变得更容易了，你还是得面临死锁dead lock、数据竞跑data race、伪共享false sharing、锁竞争lock contention等种种问题。</p>
<p>讲到这我就想起Erlang了，它就是一种天生为并发设计的语言。它的并发模型核心是基于消息传递机制的轻量级进程，进程之间不共享内存。这样的模型好处就在于每个进程是相互独立的，要通信就发消息好了，最大程度上减少了进程间的依赖关系，从而能提高整体性能，而且核越多跑的越快。但是我们要考虑到Erlang最初是Ericsson为电信系统设计的语言，由它编写的程序的目标就是为了提高系统的throughput以便为更多的用户提供服务，这也是大部分服务器端程序的目标。它们的共同特征是每个用户的请求大部分情况下都是彼此独立的，所以多核对这样的高并发应用来讲其实是有点天生一对的感觉。但是对于传统的客户端程序来讲，latency才是它们的首要目标。例如大型的商业软件，它所希望的是完成一个任务的速度能够更快，或者单位时间内能处理更多的数据。</p>
<p>另一个解决并行编程难的思路就是设计更易进行并行编程的硬件，现在最火的Transactional Memory（事务性内存）就是其中的典范。但是现在它们还只处于研究阶段，里面有一大堆的问题尚待解决，最主要的就是性能还不足以到商用阶段。</p>
<p>还有的人尝试过用编译器自动并行化，但是多年的研究表明纯粹让编译器来给你进行自动并行化是完全走不通了。它能在一定程度上提升程序的性能，但是非常有限，而且随着核数的增加它对性能的提升会更加有限。</p>
<p>那么多核时代的曙光在哪里呢？请看我<a href="http://www.parallellabs.com/2010/09/20/the-trouble-with-multicore-2/">下一篇文章</a>。</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%BC%96%E7%A8%8B%E7%9A%84%E9%9A%BE%E9%A2%98%EF%BC%88%E4%B8%80%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F08%2F17%2Fthe-trouble-with-multicore%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E6%A0%B8%E7%BC%96%E7%A8%8B%E7%9A%84%E9%9A%BE%E9%A2%98%EF%BC%88%E4%B8%80%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F08%2F17%2Fthe-trouble-with-multicore%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>12/28/2010 -- <a href="http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices/" title="移动设备进入多核时代！">移动设备进入多核时代！</a></li><li>10/03/2010 -- <a href="http://www.parallellabs.com/2010/10/03/future-multiprocessors/" title="多核的未来">多核的未来</a></li><li>09/20/2010 -- <a href="http://www.parallellabs.com/2010/09/20/the-trouble-with-multicore-2/" title="多核编程的难题（二）">多核编程的难题（二）</a></li><li>04/01/2010 -- <a href="http://www.parallellabs.com/2010/04/01/the-third-software-crisis/" title="第三次软件危机">第三次软件危机</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/08/17/the-trouble-with-multicore/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>二进制的二三事</title>
		<link>http://www.parallellabs.com/2010/05/15/something-about-binary-numeral/</link>
		<comments>http://www.parallellabs.com/2010/05/15/something-about-binary-numeral/#comments</comments>
		<pubDate>Sat, 15 May 2010 10:14:52 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[算法学习]]></category>
		<category><![CDATA[Algorithm]]></category>
		<category><![CDATA[二进制]]></category>
		<category><![CDATA[面试]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=564</guid>
		<description><![CDATA[二进制是计算机的自然语言，逻辑门中神奇的0/1组合犹如那起起伏伏的“滴答”之声构成了曼妙的电子世界。不仅如此，二进制中的0和1往往也是我们解决实际问题的利器。

<a <a href="http://www.parallellabs.com/2010/05/15/something-about-binary-numeral/">阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%9A%84%E4%BA%8C%E4%B8%89%E4%BA%8B&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F05%2F15%2Fsomething-about-binary-numeral%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%9A%84%E4%BA%8C%E4%B8%89%E4%BA%8B&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F05%2F15%2Fsomething-about-binary-numeral%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>二进制是计算机的自然语言，逻辑门中神奇的0/1组合犹如那起起伏伏的“滴答”之声构成了曼妙的电子世界。不仅如此，二进制中的0和1往往也是我们解决实际问题的利器。</p>
<h3>Task1：求一个固定长度集合所有子集</h3>
<p>最直观的方法就是穷举：对集合中的每个元素来说它要么在当前子集中，要么不在当前子集中，以此依次类推穷举出所有可能的值。如果我们用0表示该元素在当前子集中，用1表示该元素不在当前子集中，我们就可以用一串0/1序列来表示当前的子集。</p>
<p>例如集合{a, b, c, d, e}中的子集{a, b, c}可以用“11100”来表示，子集{c, d, e}可以用“00111”来表示，空子集{}可以用“00000”来表示。</p>
<p>那么对任意固定长度的集合a[n]，我们可以从a[0]开始穷举a[0]在子集中和a[0]不在子集中两种情况，再依次类推从a[1]开始一直穷举到a[n-1]为止。于是我们可以得到一个很直观的递归程序：</p>
<pre class="brush: cpp; title: ; notranslate">
void sub_sets_recu(int index, int length, char *array, char *bits)
{
	int j = 0;

	if (index &gt;= length) {
		for (j = 0; j &lt; length; j++) {
			if (bits[j] == '1') {
				printf(&quot;%c&quot;, array[j]);
			}
		}
		printf(&quot;\n&quot;);
	}
	else {
		bits[index] = '1';
		sub_sets_recu(index+1, length, array, bits);
		bits[index] = '0';
		sub_sets_recu(index+1, length, array, bits);
	}
}
</pre>
<p>但是递归版本的缺点就是需要一个额外的数组bits来存储0/1序列，那么有没有办法改进呢？我们可以先试试把递归改成迭代的方式会不会有效果。</p>
<p>迭代的关键就在于明白你究竟要做哪些计算步骤，为此我们可以先画出递归函数的Execution Tree来看看：</p>
<p>&#8211;                       ○<br />
|                     0/  \1<br />
|                     ○    ○<br />
|                  0/  \1   .<br />
|                  ○    ○      .<br />
n层             .       .       .<br />
|                .         .<br />
|               .           .<br />
|             /  \        /  \<br />
|           ○     ○     ○    ○<br />
&#8211;</p>
<p>上图中，第i层的值为1的边来表示a[i]在子集中，值为0的边表示a[i]不在子集中，那么从根节点到所有叶子节点所经过的边的组合就是所有可能的子集组合，例如从根节点到最左叶子节点的组合为“00000”，即空子集。根据完全二叉树的性质，第n层有2^n个节点，所以共有2^n个不同的子集。既然所有的解都已经存储在这颗二叉树中，那么我们自然就可以依此构建一个遍历所有路径的迭代算法。</p>
<p>思路是有了，但是实际编码中我们需要用到一个跟二进制编码相关的trick了。我们知道任意一个十进制的数是可以用二进制来表示的，反过来我们也可以用十进制来表示二进制啊，“用二进制来思考”其实就是这个trick的关键。既然我们的解是“00000”~“11111”，那么它们自然可以用十进制的0~31来表示。很自然的我们就可以想到如果我们依次遍历0~31这些数，根据它们二进制值中每一位的值是0还是1即可确定当前元素是否在子集中。关于二进制的位操作等相关知识Matrix67的blog[1]有一个系列写的很不错，在此就不再赘述。</p>
<pre class="brush: cpp; title: ; notranslate">
void sub_sets_iter(int length, char *array)
{
	int i = 0;
	int j = 0;
	for (i = 0; i &lt; (1&lt;&lt;length); i++) {
		for (j = 0; j &lt; length; j++) {
			if ((i &amp; (1&lt;&lt;j)) != 0) {
				printf(&quot;%c&quot;, array[j]);
			}
		}
		printf(&quot;\n&quot;);
	}
}
</pre>
<p>再加上测试用的main函数：</p>
<pre class="brush: cpp; title: ; notranslate">
int main()
{
	char a[5] = {'a','b','c','d','e'};
	char b[5];
	int i;

#ifdef USE_RECU
	for (i = 0; i &lt; 10000000; i++) {
		sub_sets_recu(0, 5, a, b);
	}
#else
	for (i = 0; i &lt; 10000000; i++) {
		sub_sets_iter(5, a);
	}
#endif
	return 0;
}
</pre>
<p>好，代码全写完了，当然应该比试比试两个算法孰优孰劣。测试平台是：cygwin + gcc 3.4.4 + Core2 Duo T7300@2.0GHz</p>
<p>在测试时已经把两个算法中的printf给注释掉了，只比拼速度。先把gcc的优化设成-O0看看：</p>
<pre class="brush: bash; title: ; notranslate">
$ time ./recu.exe

real    0m8.847s
user    0m8.811s
sys     0m0.046s

$ time ./iter.exe

real    0m5.093s
user    0m4.999s
sys     0m0.046s
</pre>
<p>再看看gcc -O3的结果：</p>
<pre class="brush: bash; title: ; notranslate">
$ time ./recu_o3.exe

real    0m8.285s
user    0m8.234s
sys     0m0.031s

$ time ./iter_o3.exe

real    0m1.887s
user    0m1.796s
sys     0m0.031s
</pre>
<p>结果显示迭代算法优于递归算法。感兴趣的朋友可以反汇编一下编译器优化后的代码，看看为什么迭代算法优化后能快那么多。关于递归与迭代已经有很多分析了，简单说来递归更加直观易懂，但是栈的开销比较大；迭代的算法不容易一开始就想出来，但是一般来说效率更高。从编译器的角度来讲，部分的编译器能把相对简单的递归算法转化成迭代算法，因为递归的算法对编译器来说是更友好的算法，更易于在此基础上做更多的优化。从体系结构的角度来讲，递归算法更易于发挥CPU流水线的特点让多步运算同时执行，而某些特定的架构，例如GPU就没有对递归提供有效的硬件支持，因为栈空间是一个大问题。</p>
<h3>Task2：小白鼠试毒药问题</h3>
<p>实验室里有1000个一模一样的瓶子，但是其中的一瓶有毒。可以用实验室的小白鼠来测试哪一瓶是毒药。如果小白鼠喝掉毒药的话，会在一个星期的时候死去，其他瓶子里的药水没有任何副作用。请问最少用多少只小白鼠可以在一个星期以内查出哪瓶是毒药？</p>
<p>这个问题关键是跳出思维，并不是说瓶子和小白鼠必须一一对应，然后我们用1000只小白鼠，每只各试一瓶药水，等一个礼拜然后出结果。其实我们仔细想想，小白鼠试毒只有两种结果，非“死”即“生”，又是一个0/1状态。很显然我们可以再次构建一个0/1组成的二叉树，由此即可表示不同的试毒结果。假设我们需要n个小白鼠，那么2^n-1应大于等于1000（因为有1000种可能的结果，减一是指要除去小白鼠全部不死的情况 &#8212; 多谢danqi指正），那么最小的n就是10了。</p>
<h3>总结</h3>
<p>解决此类问题的关键在于找到能用0/1表示的状态，然后想办法用0/1组成的二进制数来表示不同的结果，从而达到节省存储空间，提高解题效率的目的。</p>
<p>二进制真是神奇，文章的最后附一张0和1构成的Fibonacci数列（来自[2]）：</p>
<p><img src="http://www.matrix67.com/blogimage/200601111.gif" alt="" /></p>
<h3>相关文献</h3>
<p>[1] <a href="http://www.matrix67.com/blog/archives/122" target="_blank">位运算讲解系列文章</a><br />
[2] <a href="http://www.matrix67.com/blog/archives/60" target="_blank">Fibonacci数列转二进制图形的惊异发现</a></p>
<p><span style="color: #ffffff;">转载请注明来自</span><a href="http://www.parallellabs.com" target="_blank"><span style="color: #ffffff;">www.parallellabs.com</span></a></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%9A%84%E4%BA%8C%E4%B8%89%E4%BA%8B&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F05%2F15%2Fsomething-about-binary-numeral%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E4%BA%8C%E8%BF%9B%E5%88%B6%E7%9A%84%E4%BA%8C%E4%B8%89%E4%BA%8B&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F05%2F15%2Fsomething-about-binary-numeral%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>10/25/2010 -- <a href="http://www.parallellabs.com/2010/10/25/practical-concurrent-queue-algorithm/" title="多线程队列的算法优化">多线程队列的算法优化</a></li><li>02/04/2010 -- <a href="http://www.parallellabs.com/2010/02/04/ericsson-interview-of-master-thesis-insweden/" title="瑞典Ericsson总部Master Thesis面试回忆录">瑞典Ericsson总部Master Thesis面试回忆录</a></li><li>11/12/2009 -- <a href="http://www.parallellabs.com/2009/11/12/algorithm-the-longest-plateau/" title="An interesting algorithm problem: the longest plateau">An interesting algorithm problem: the longest plateau</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/05/15/something-about-binary-numeral/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>聊一聊瑞典的程序员</title>
		<link>http://www.parallellabs.com/2010/05/04/swedish-programmer/</link>
		<comments>http://www.parallellabs.com/2010/05/04/swedish-programmer/#comments</comments>
		<pubDate>Tue, 04 May 2010 08:00:40 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[职业生涯]]></category>
		<category><![CDATA[Chalmers]]></category>
		<category><![CDATA[瑞典]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=558</guid>
		<description><![CDATA[在瑞典这个发达国家，IT企业的基本工资都相差不大。认识的一位Ericsson的员工（入职刚一年）工资是税前29K SEK/M（~30%的税率），资格老一点的员工能有40K~50K SEK/M。不过工资高的人交的税也会相应的增加（40%~50%），所以有一个流行的说法就是大学教授和码头工人的税后工资差不多。小公司的薪资也很不错，而且还有不同程度的股份。

<a <a href="http://www.parallellabs.com/2010/05/04/swedish-programmer/">阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E8%81%8A%E4%B8%80%E8%81%8A%E7%91%9E%E5%85%B8%E7%9A%84%E7%A8%8B%E5%BA%8F%E5%91%98&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F05%2F04%2Fswedish-programmer%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E8%81%8A%E4%B8%80%E8%81%8A%E7%91%9E%E5%85%B8%E7%9A%84%E7%A8%8B%E5%BA%8F%E5%91%98&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F05%2F04%2Fswedish-programmer%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding: 0px;">在瑞典这个发达国家，IT企业的基本工资都相差不大。认识的一位Ericsson的员工（入职刚一年）工资是税前29K SEK/M（~30%的税率），资格老一点的员工能有40K~50K SEK/M。不过工资高的人交的税也会相应的增加（40%~50%），所以有一个流行的说法就是大学教授和码头工人的税后工资差不多。小公司的薪资也很不错，而且还有不同程度的股份。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding: 0px;">瑞典的大学都是免学费的（明年开始向外国学生收费），由政府承担教育经费。瑞典的教育、医疗大都是免费的，它们需要的大量资金都由政府的税收收入来支持，取之于民用之于民。大学生的生活费大都是向政府申请的贷款（生活费大约7K SEK/M，父母大都不支持他们的生活费），所以很多我身边的瑞典朋友早早就开始在企业兼职来补贴生活费，这样在他们研究生毕业的时候很多人都已经有了几年的兼职经验。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding: 0px;">像瑞典这样的欧美发达国家，很多计算机专业的大学生很早就开始学习编程了，而且还非常普遍。他们在高中的时候就会开设编程相关的课程，更早一点的十二、三岁就开始学习编程了。我的一个瑞典朋友在高中的最后一年用汇编写了一个40K行的操作系统！另一个我认识的前辈在高中毕业之后就去了瑞典的一家游戏公司做开发，工作了七八年之后又回学校读本科，但是没读完又加入了另一家创业公司。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding: 0px;">瑞典的实习工资也很不错。Volvo的实习生能给到25K SEK/M，而其他公司的实习生大都能给到17K~20K SEK/M。另一种实习的方式是去做毕业设计。Ericsson的Master Thesis为期6个月，Offer的基本工资是35K，奖金根据最后的表现最多给15K，所以税前最多能拿50K，扣掉30%的税后能拿到30K左右。</p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0.8em; margin-left: 0px; padding: 0px;">高工资，高税收，高福利，大家收入都差不多，所以人们都很“安居乐业”。总而言之，我相信瑞典人真的不富（贫富差距不大），但是也没啥压力。这样的环境很容易出两种人，一种是真正爱搞研究搞创新的人，他们能弄出一些Great Idea开创一片天地；另一种就是在公司养老的人，能完成工作，但也就仅限于此。</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E8%81%8A%E4%B8%80%E8%81%8A%E7%91%9E%E5%85%B8%E7%9A%84%E7%A8%8B%E5%BA%8F%E5%91%98&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F05%2F04%2Fswedish-programmer%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E8%81%8A%E4%B8%80%E8%81%8A%E7%91%9E%E5%85%B8%E7%9A%84%E7%A8%8B%E5%BA%8F%E5%91%98&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F05%2F04%2Fswedish-programmer%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>11/29/2010 -- <a href="http://www.parallellabs.com/2010/11/29/erlang-user-conference-2010-and-some-thoughts-on-career-of-programmers/" title="Erlang User Conference 2010见闻（兼谈程序员职业生涯）">Erlang User Conference 2010见闻（兼谈程序员职业生涯）</a></li><li>10/27/2010 -- <a href="http://www.parallellabs.com/2010/10/27/steve-jobs-talked-in-stanford-2005/" title="史蒂夫乔布斯(Steve Jobs)在Stanford2005年毕业典礼上的演讲">史蒂夫乔布斯(Steve Jobs)在Stanford2005年毕业典礼上的演讲</a></li><li>10/03/2010 -- <a href="http://www.parallellabs.com/2010/10/03/future-multiprocessors/" title="多核的未来">多核的未来</a></li><li>02/04/2010 -- <a href="http://www.parallellabs.com/2010/02/04/ericsson-interview-of-master-thesis-insweden/" title="瑞典Ericsson总部Master Thesis面试回忆录">瑞典Ericsson总部Master Thesis面试回忆录</a></li><li>12/09/2009 -- <a href="http://www.parallellabs.com/2009/12/09/h1n1-vaccination-in-sweden/" title="在瑞典打甲流疫苗">在瑞典打甲流疫苗</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/05/04/swedish-programmer/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>多线程程序中操作的原子性</title>
		<link>http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/</link>
		<comments>http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 15:49:10 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[原子操作]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[多线程编程]]></category>
		<category><![CDATA[线程安全]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=469</guid>
		<description><![CDATA[原子操作就是不可再分的操作。在多线程程序中原子操作是一个非常重要的概念，它常常用来实现一些同步机制，同时也是一些常见的多线程Bug的源头。本文主要讨论了三个问题：1. 多线程程序中对变量的读写操作是否是原子的？2. 多线程程序中对Bit field（位域）的读写操作是否是线程安全的？3. 程序员该如何使用原子操作？

<a <a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/">阅读全文>></a>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E4%B8%AD%E6%93%8D%E4%BD%9C%E7%9A%84%E5%8E%9F%E5%AD%90%E6%80%A7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F04%2F15%2Fatomic-operation-in-multithreaded-application%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E4%B8%AD%E6%93%8D%E4%BD%9C%E7%9A%84%E5%8E%9F%E5%AD%90%E6%80%A7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F04%2F15%2Fatomic-operation-in-multithreaded-application%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<h3><span style="color: #000000;">0. 背景</span></h3>
<p><a id="mpkc" style="color: #551a8b;" title="原子操作" href="http://en.wikipedia.org/wiki/Atomic_operation">原子操作</a>就是不可再分的操作。在多线程程序中原子操作是一个非常重要的概念，它常常用来实现一些同步机制，同时也是一些常见的多线程Bug的源头。本文主要讨论了三个问题：1. 多线程程序中对变量的读写操作是否是原子的？2. 多线程程序中对Bit field（位域）的读写操作是否是线程安全的？3. 程序员该如何使用原子操作？</p>
<h3><span style="color: #000000;">1. 多线程环境下对变量的读写操作是否是原子的？</span></h3>
<p>我们先从一道很热门的百度笔试题讲起。很多人讲不清楚其背后的原理，下面我们就来对它进行一下剖析（其实这个题目有点歧义，后面我们会讲到）：</p>
<blockquote><p>以下多线程对int型变量x的操作，哪几个需要进行同步：（ ）<br />
A. x=y; B. x++; C. ++x; D. x=1;</p></blockquote>
<p>要彻底理解这个问题，我们首先需要从硬件讲起。以常见的X86 CPU来说，根据Intel的<a id="pvf3" style="color: #551a8b;" title="参考手册" href="http://download.intel.com/design/processor/manuals/253668.pdf">参考手册</a>，它基于以下三种机制保证了多核中加锁的原子操作（8.1节）：<br />
（1）Guaranteed atomic operations （注：8.1.1节有详细介绍）<br />
（2）Bus locking, using the LOCK# signal and the LOCK instruction prefix<br />
（3）Cache coherency protocols that ensure that atomic operations can be carried out on cached data structures (cache lock); this mechanism is present in the Pentium 4, Intel Xeon, and P6 family processors</p>
<p>这三个机制相互独立，相辅相承。简单的理解起来就是<br />
（1）一些基本的内存读写操作是本身已经被硬件提供了原子性保证（例如读写单个字节的操作）；<br />
（2）一些需要保证原子性但是没有被第（1）条机制提供支持的操作（例如read-modify-write）可以通过使用”LOCK#”来锁定总线，从而保证操作的原子性<br />
（3）因为很多内存数据是已经存放在L1/L2 cache中了，对这些数据的原子操作只需要与本地的cache打交道，而不需要与总线打交道，所以CPU就提供了cache coherency机制来保证其它的那些也cache了这些数据的processor能读到最新的值（关于cache coherency可以参加我的<a id="prz." style="color: #551a8b;" title="一篇博文" href="http://www.parallellabs.com/2010/03/06/why-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence/">一篇博文</a>）。</p>
<p>那么CPU对哪些（1）中的基本的操作提供了原子性支持呢？根据Intel手册8.1.1节的介绍：</p>
<p>从Intel486 processor开始，以下的基本内存操作是原子的：<br />
• Reading or writing a byte（一个字节的读写）<br />
• Reading or writing a word aligned on a 16-bit boundary（对齐到16位边界的字的读写）<br />
• Reading or writing a doubleword aligned on a 32-bit boundary（对齐到32位边界的双字的读写）</p>
<p>从Pentium processor开始，除了之前支持的原子操作外又新增了以下原子操作：<br />
• Reading or writing a quadword aligned on a 64-bit boundary（对齐到64位边界的四字的读写）<br />
• 16-bit accesses to uncached memory locations that fit within a 32-bit data bus（未缓存且在32位数据总线范围之内的内存地址的访问）</p>
<p>从P6 family processors开始，除了之前支持的原子操作又新增了以下原子操作：<br />
• Unaligned 16-, 32-, and 64-bit accesses to cached memory that fit within a cache line（对单个cache line中缓存地址的未对齐的16/32/64位访问）</p>
<p>那么哪些操作是非原子的呢？<br />
Accesses to cacheable memory that are split across bus widths, cache lines, and<br />
page boundaries are not guaranteed to be atomic by the Intel Core 2 Duo, Intel®<br />
Atom™, Intel Core Duo, Pentium M, Pentium 4, Intel Xeon, P6 family, Pentium, and<br />
Intel486 processors.（说点简单点，那些被总线带宽、cache line以及page大小给分隔开了的内存地址的访问不是原子的，你如果想保证这些操作是原子的，你就得求助于机制（2），对总线发出相应的控制信号才行）。</p>
<p>需要注意的是尽管从P6 family开始对一些非对齐的读写操作已经提供了原子性保障，但是非对齐访问是非常影响性能的，需要尽量避免。当然了，对于一般的程序员来说不需要太担心这个，因为大部分编译器会自动帮你完成内存对齐。</p>
<p>回到最开始那个笔试题。我们先反汇编一下看看它们到底执行了什么操作：</p>
<pre class="brush: cpp; title: ; notranslate">
x = y;
mov eax,dword ptr [y]
mov dword ptr [x],eax

x++;
mov eax,dword ptr [x]
add eax,1
mov dword ptr [x],eax

++x;
mov eax,dword ptr [x]
add eax,1
mov dword ptr [x],eax

x = 1;
mov dword ptr [x],1
</pre>
<p>（1）很显然，x=1是原子操作。<br />
因为x是int类型，32位CPU上int占32位，在X86上由硬件直接提供了原子性支持。实际上不管有多少个线程同时执行类似x=1这样的赋值语句，x的值最终还是被赋的值（而不会出现例如某个线程只更新了x的低16位然后被阻塞，另一个线程紧接着又更新了x的低24位然后又被阻塞，从而出现x的值被损坏了的情况）。</p>
<p>（2）再来看x++和++x。<br />
其实类似x++, x+=2, ++x这样的操作在多线程环境下是需要同步的。因为X86会按三条指令的形式来处理这种语句：从内存中读x的值到寄存器中，对寄存器加1，再把新值写回x所处的内存地址（见上面的反汇编代码）。</p>
<p>例如有两个线程，它们按照如下顺序执行（注意读x和写回x是原子操作，两个线程不能同时执行）：</p>
<p>time    Thread 1         Thread 2<br />
0      load eax, x<br />
1                            load eax, x<br />
2      add eax, 1        add eax, 1<br />
3      store x, eax<br />
4                            store x, eax</p>
<p>我们会发现最终x的值会是1而不是2，因为Thread 1的结果被覆盖掉了。这种情况下我们就需要对x++这样的操作加锁（例如Pthread中的mutex）以保证同步，或者使用一些提供了atomic operations的库（例如Windows API中的<a id="w3tu" style="color: #551a8b;" title="atomic库" href="http://msdn.microsoft.com/en-us/library/ms686360(VS.85).aspx">atomic库</a>，Linux内核中的<a id="jbi8" style="color: #551a8b;" title="atomic.h" href="http://lxr.linux.no/linux+v2.6.26.5/include/asm-x86/atomic_32.h">atomic.h</a>，Java concurrent库中的Atomic Integer，C++0x中即将支持的atomic_int等等，这些库会利用CPU提供的硬件机制做一层封装，提供一些保证了原子性的API）。</p>
<p>（3）最后来看看x=y。<br />
在X86上它包含两个操作：读取y至寄存器，再把该值写入x。读y的值这个操作本身是原子的，把值写入x也是原子的，但是两者合起来是不是原子操作呢？我个人认为x=y不是原子操作，因为它不是不可再分的操作。但是它需要不需要同步呢？其实问题的关键在于程序的上下文。</p>
<p>例如有两个线程，线程1要执行{y = 1; x = y;}，线程2要执行{y = 2; y = 3;}，假设它们按如下时间顺序执行：</p>
<p>time    Thread 1        Thread 2<br />
0        store y, 1<br />
1                            store y, 2<br />
2        load eax, y<br />
3                            store y, 3<br />
4        store x, eax</p>
<p>那么最终线程1中x的值为2，而不是它原本想要的1。我们需要加上相应的同步语句确保y = 2不会在线程1的两条语句之间发生。y = 3那条语句尽管在load y和store x之间执行，但是却不影响x=y这条语句本身的语义。所以你可以说x=y需要同步，也可以说x=y不需要同步，看你怎么理解题意了。x=1是否需要同步也是一样的道理，虽然它本身是原子操作，但是如果有另一个线程要读x=1之后的值，那肯定也需要同步，否则另一个线程读到的就是x的旧值而不是1了。</p>
<h3><span style="color: #000000;">2. 对Bit field（位域）的读写操作是否是线程安全的？</span></h3>
<p><a id="spoi" style="color: #551a8b;" title="Bit field" href="http://learn.akae.cn/media/ch19s04.html">Bit field</a>常用来高效的存储有限位数的变量，多用于内核/底层开发中。一般来说，对同一个结构体内的不同bit成员的多线程访问是无法保证线程安全的。</p>
<p>例如<a id="s:v." style="color: #551a8b;" title="WikiPedia" href="http://en.wikipedia.org/wiki/Bit_field">Wikipedia</a>中的如下例子：</p>
<pre class="brush: cpp; title: ; notranslate">
struct foo {
    int flag : 1;
    int counter : 15;
};

struct foo my_foo;

/* ... */

/* in thread 1 */

pthread_mutex_lock(&amp;my_mutex_for_flag);
my_foo.flag = !my_foo.flag;
pthread_mutex_unlock(&amp;my_mutex_for_flag);

/* in thread 2 */

pthread_mutex_lock(&amp;my_mutex_for_counter);
++my_foo.counter;
pthread_mutex_unlock(&amp;my_mutex_for_counter);
</pre>
<p>两个线程分别对my_foo.flag和my_foo.counter进行读写操作，但是即使有上面的加锁方式仍然不能保证它是线程安全的。原因在于不同的成员在内存中的具体排列方式“跟Byte Order、Bit Order、对齐等问题都有关，不同的平台和编译器可能会排列得很不一样，要编写可移植的代码就不能假定Bit-field是按某一种固定方式排列的”[3]。而且一般来讲CPU对内存操作的最小单位是<a id="mmki" style="color: #551a8b;" title="word" href="http://en.wikipedia.org/wiki/Word_length">word</a>（X86的word是16bits），而不是1bit。这就是说，如果my_foo.flag和my_foo.counter存储在同一个word里，CPU在读写任何一个bit member的时候会同时把两个值一起读进寄存器，从而造成读写冲突。这个例子正确的处理方式是用一个mutex同时保护my_foo.flag和my_foo.counter，这样才能确保读写是线程安全的。</p>
<p>在<a id="k.sc" style="color: #551a8b;" title="C++0x草案" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf">C++0x草案</a>中对bit field是这样定义的：<br />
连续的多个非0bit的bit fields是属于同一个memory location的；长度为0bit的bit field会把占单独的一个memory location。对同一个memory location的读写不是线程安全的；对不同memory location的读写是线程安全的。<br />
例如在下图的例子中bf1和bf2是同一个memory location，bf3是一个单独的memory location，bf4是一个单独的memory location：<br />
<img class="size-full wp-image-508 alignnone" title="bit field" src="http://www.parallellabs.com/wp-content/uploads/2010/04/bitfield.JPG" alt="bit field" width="525" height="388" /></p>
<p>这里有一个因为Bit field不是线程安全所导致的一个Linux内核中的<a id="bq8v" style="color: #551a8b;" title="bug" href="http://lkml.indiana.edu/hypermail/linux/kernel/0810.1/0828.html">Bug</a>。</p>
<p>引用一下Pongba的<a id="m40." style="color: #551a8b;" title="总结" href="http://www.newsmth.net/bbscon.php?bid=335&amp;id=186723">总结</a>：</p>
<blockquote><p>所以，如果你的多个bitfields是连续的，同时又想要无冲突的读取它们，有两种做法，一是在中间用0大小bitfield隔开，但这种做法实际上就消除了bitfield的节省内存的初衷，因为为了使它们不冲突，至少被隔开的两个bitfield肯定不可能共享byte了。另一种做法当然就是用锁了。</p></blockquote>
<h3><span style="color: #000000;">3. 程序员该怎么用Atomic操作？</span></h3>
<p>一般情况下程序员不需要跟CPU提供的原子操作直接打交道，所以只需要选择语言或者平台提供的atomic API即可。而且使用封装好了的API还有一个好处是它们常常还提供了诸如compare_and_swap，fetch_and_add这样既有读又有写的较复杂操作的封装。</p>
<p>常见的API如下：</p>
<p>Windows上<a id="fuwa" style="color: #551a8b;" title="InterlockedXXXX" href="http://msdn.microsoft.com/en-us/library/ms686360(VS.85).aspx">InterlockedXXXX</a>的API<br />
GNU/Linux上linux kernel中<a id="k6en" style="color: #551a8b;" title="atomic_32.h" href="http://lxr.linux.no/linux+v2.6.26.5/include/asm-x86/atomic_32.h">atomic_32.h</a><br />
GCC中的<a style="color: #551a8b;" href="http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html">Atomic Builtins</a> (__sync_fetch_and_add()等)<br />
Java中的java.util.concurrent.atomic<br />
C++0x中的<a style="color: #551a8b;" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3092.pdf">atomic operation</a><br />
Intel TBB中的<a style="color: #551a8b;" href="http://software.intel.com/en-us/blogs/2007/09/12/threading-building-blocks-atomic-operations-introduction/">atomic operation</a></p>
<h3><span style="color: #000000;">4. 参考文献：</span></h3>
<p>[1] <a style="color: #551a8b;" title="关于变量操作的原子性(atomicity)FAQ" href="http://www.newsmth.net/bbstcon.php?board=CPlusPlus&amp;gid=236548">关于变量操作的原子性(atomicity)FAQ</a><br />
[2] <a style="color: #551a8b;" href="http://en.wikipedia.org/wiki/Atomic_operation">http://en.wikipedia.org/wiki/Atomic_operation</a><br />
[3] <a style="color: #551a8b;" title="关于内存对齐、bit field等" href="http://learn.akae.cn/media/ch19s04.html">关于内存对齐、bit field等 &#8211;《Linux C编程一站式学习》</a><br />
[4] <a style="color: #551a8b;" href="http://www.alexonlinux.com/do-you-need-mutex-to-protect-int">Do you need mutex to protect an &#8216;int&#8217;?</a><br />
[5] <a style="color: #551a8b;" href="http://www.amazon.com/C-Concurrency-Action-Practical-Multithreading/dp/1933988770/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1272232877&amp;sr=8-1">C++ Concurrency in Action</a><br />
[6] <a style="color: #551a8b;" href="http://www.alexonlinux.com/multithreaded-simple-data-type-access-and-atomic-variables">Multithreaded simple data type access and atomic variables</a><br />
<span style="color: #ffffff;">[6] http://www.newsmth.net/bbscon.php?bid=335&amp;id=236629</span><span style="color: #ffffff;"><br />
[7] </span><span style="color: #ffffff;">http://www.newsmth.net/bbscon.php?bid=335&amp;id=209239</span><span style="color: #ffffff;"><br />
[8] </span><span style="color: #ffffff;">http://www.newsmth.net/bbscon.php?bid=335&amp;id=186723</span><br />
<span style="color: #ffffff;">转载请注明来自</span><a href="http://www.parallellabs.com" target="_blank"><span style="color: #ffffff;">parallellabs.com</span></a></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E4%B8%AD%E6%93%8D%E4%BD%9C%E7%9A%84%E5%8E%9F%E5%AD%90%E6%80%A7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F04%2F15%2Fatomic-operation-in-multithreaded-application%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E4%B8%AD%E6%93%8D%E4%BD%9C%E7%9A%84%E5%8E%9F%E5%AD%90%E6%80%A7&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F04%2F15%2Fatomic-operation-in-multithreaded-application%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>04/09/2011 -- <a href="http://www.parallellabs.com/2011/04/09/pthread-mutex-lock-and-thread-safety/" title="《程序员的自我修养》中关于加锁不能保证线程安全的一个错误">《程序员的自我修养》中关于加锁不能保证线程安全的一个错误</a></li><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li><li>08/27/2011 -- <a href="http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/" title="浅析C++多线程内存模型 ">浅析C++多线程内存模型 </a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>第三次软件危机</title>
		<link>http://www.parallellabs.com/2010/04/01/the-third-software-crisis/</link>
		<comments>http://www.parallellabs.com/2010/04/01/the-third-software-crisis/#comments</comments>
		<pubDate>Thu, 01 Apr 2010 04:54:40 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[业界评论]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[多线程编程]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=449</guid>
		<description><![CDATA[The major cause of the software crisis is that the machines have become several orders of magnitude more powerful! To put it quite bluntly: as long as there were no machines, programming was no problem at all; when we had a few weak computers, programming became a mild problem, and now we have gigantic computers, programming has become an equally gigantic problem.

造成软件危机的主要原因是因为计算机的计算能力正在呈指数级地增长！说的简单些：在没有计算机的时候，编程根本就不是一个问题；当一些计算能力较弱的计算机出现时，编程成了一个中等难度的问题，而现在，我们拥有了计算能力超绝的计算机，编程就变为了一个同样复杂的问题。

– Edsger Dijkstra, 1972年图灵奖获奖感言

<a href="http://www.parallellabs.com/2010/04/01/the-third-software-crisis/">阅读全文>></a> 
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E7%AC%AC%E4%B8%89%E6%AC%A1%E8%BD%AF%E4%BB%B6%E5%8D%B1%E6%9C%BA&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F04%2F01%2Fthe-third-software-crisis%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E7%AC%AC%E4%B8%89%E6%AC%A1%E8%BD%AF%E4%BB%B6%E5%8D%B1%E6%9C%BA&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F04%2F01%2Fthe-third-software-crisis%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<blockquote><p>The major cause of the software crisis is that the machines have become several orders of magnitude more powerful! To put it quite bluntly: as long as there were no machines, programming was no problem at all; when we had a few weak computers, programming became a mild problem, and now we have gigantic computers, programming has become an equally gigantic problem.</p>
<p>造成软件危机的主要原因是因为计算机的计算能力正在呈指数级地增长！说的简单些：在没有计算机的时候，编程根本就不是一个问题；当一些计算能力较弱的计算机出现时，编程成了一个中等难度的问题，而现在，我们拥有了计算能力超绝的计算机，编程就变为了一个同样复杂的问题。</p>
<p>– Edsger Dijkstra, 1972年图灵奖获奖感言</p></blockquote>
<p><strong>第一次软件危机 （60年代~70年代）</strong></p>
<p>这个时期主要的软件开发方式是使用机器语言或者汇编语言在特定的机器上进行软件的设计与编写。此时的软件规模较小，也不需要使用系统化的软件开发方法，基本上是个人设计编码、个人操作使用的模式。这个时代的程序一个典型特征就是依赖特定的机器，程序员必须根据所使用的计算机的硬件特性编写特定的程序。</p>
<p>然而从60年代中期开始，大容量、高速度计算机问世，程序设计的复杂度也随之增长。1968 年北大西洋公约组织的计算机科学家在联邦德国召开国际会议，第一次讨论软件危机问题，并正式提出“软件工程”一词，从此一门新兴的工程学科——软件工程学——为研究和克服软件危机应运而生，“软件危机”的概念也是在那次会议上由F. L. Bauer提出的。</p>
<p>当时业界最迫切的需求是需要在不损失性能的前提下获得更好的“抽象性”和“可移植性”。此时，比汇编和机器语言更高级的语言相聚诞生，典型的代表莫过于C语言（1972年）。C语言让程序员能让程序员编写的代码在没有或只有较少机器相关性的同时又有不输于汇编语言的性能，而且丰富的语言特性也使得编程难度大大降低，成功的解决了“抽象性”和“可移植性”的问题。</p>
<p><strong>第二次软件危机（80年代~90年代）</strong></p>
<p>这次危机可以归因于软件复杂性的进一步增长。这个时候的大规模软件常常由数百万行代码组成，有数以百计的程序员参与其中，怎样高效、可靠的构造和维护这样规模的软件成为了一个新的难题。著名的《人月神话》中提及，IBM公司开发的OS/360系统共有4000多个模块，约100万条指令，投入5000人年，耗资数亿美元，结果还是延期交付。在交付使用后的系统中仍发现大量（2000个以上）的错误。</p>
<p>这时候人们典型需求的是更好的“可组合性”(Composability)、“可延展性”(Malleability)以及“可维护性”(Maintainability)。程序的性能已经不是一个大问题了，因为摩尔定律能帮你搞定它（70年代编写的C程序仍然能在现在的计算机上运行，而且它还更快！）。为了解决这次危机，面向对象的编程语言（C++、C#、Java等）诞生了，更好的软件工程方法（设计模式、重构、测试、需求分析等等）诞生了，而程序员们也越来越不需要知道硬件是怎么工作的了。软件和硬件的界限越来越牢固，Java编写的代码能在任何JVM支持的平台上运行，程序员也非常乐于享受这样的便利。</p>
<p><strong>第三次软件危机（2005年至今）</strong></p>
<p>兄弟们，“<a href="http://blog.csdn.net/hsutter/archive/2006/08/29/1136281.aspx" target="_blank">免费的午餐已经结束了</a>”。<br />
摩尔定律在串行机器上宣告失效，多核时代正式来临！</p>
<p>这个时候怎样在多核平台上仍然能保持性能的持续增长就成为了这一次软件危机的核心。并行编程给我们带来了许许多多新的技术难题，现阶段想要高效的利用这些多核平台以获得更好的性能，就必须对计算机的硬件有较深入的理解，而广大程序员却更喜欢能有一些更加便利的编程模型（也许是一门新的语言、也许是新的编程模型）来简单高效地进行并行编程。我们正处在这次危机的开端，前路满是荆棘。但是只要有问题，就会有机会。多核时代，你们的机会在哪里呢？</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E7%AC%AC%E4%B8%89%E6%AC%A1%E8%BD%AF%E4%BB%B6%E5%8D%B1%E6%9C%BA&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F04%2F01%2Fthe-third-software-crisis%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E7%AC%AC%E4%B8%89%E6%AC%A1%E8%BD%AF%E4%BB%B6%E5%8D%B1%E6%9C%BA&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F04%2F01%2Fthe-third-software-crisis%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li><li>08/27/2011 -- <a href="http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/" title="浅析C++多线程内存模型 ">浅析C++多线程内存模型 </a></li><li>12/28/2010 -- <a href="http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices/" title="移动设备进入多核时代！">移动设备进入多核时代！</a></li><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/04/01/the-third-software-crisis/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>实施并行编程的五大障碍</title>
		<link>http://www.parallellabs.com/2010/03/22/five-obstacles-that-slow-down-parallelism/</link>
		<comments>http://www.parallellabs.com/2010/03/22/five-obstacles-that-slow-down-parallelism/#comments</comments>
		<pubDate>Sun, 21 Mar 2010 16:28:57 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[业界评论]]></category>
		<category><![CDATA[并行编程]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[多线程编程]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=433</guid>
		<description><![CDATA[近期看见一篇来自Intel的很有意思的<a id="p6t8" style="color: #551a8b;" title="分析文章" href="http://software.intel.com/en-us/blogs/2010/03/15/what-parallel-programmers-really-really-want/">分析文章</a>，作者提到在他向45名与会的各公司程序员/开发经理/战略师提问“什么是实施并行编程的最大障碍”时，下面五个因素被提及的次数最多：遗留代码(legacy code)、教育(education)、工具(tools)、对众核趋势的恐惧(fear of many cores)以及可维护性(maintainability)。文章虽然是一篇Intel Parallel Studio的软文，但是其中提及的这五大障碍却非常值得讨论，下面是我对这五大障碍的一些粗浅看法，希望能起到一个抛砖引玉的作用，欢迎大家给出你们的看法。

<a href="http://www.parallellabs.com/2010/03/22/five-obstacles-that-slow-down-parallelism/">阅读全文>></a> 
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%AE%9E%E6%96%BD%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E7%9A%84%E4%BA%94%E5%A4%A7%E9%9A%9C%E7%A2%8D&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F03%2F22%2Ffive-obstacles-that-slow-down-parallelism%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%AE%9E%E6%96%BD%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E7%9A%84%E4%BA%94%E5%A4%A7%E9%9A%9C%E7%A2%8D&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F03%2F22%2Ffive-obstacles-that-slow-down-parallelism%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>近期看见一篇来自Intel的很有意思的<a id="p6t8" style="color: #551a8b;" title="分析文章" href="http://software.intel.com/en-us/blogs/2010/03/15/what-parallel-programmers-really-really-want/">分析文章</a>，作者提到在他向45名与会的各公司程序员/开发经理/战略师提问“什么是实施并行编程的最大障碍”时，下面五个因素被提及的次数最多：遗留代码(legacy code)、教育(education)、工具(tools)、对众核趋势的恐惧(fear of many cores)以及可维护性(maintainability)。文章虽然是一篇Intel Parallel Studio的软文，但是其中提及的这五大障碍却非常值得讨论，下面是我对这五大障碍的一些粗浅看法，希望能起到一个抛砖引玉的作用，欢迎大家给出你们的看法。</p>
<p><strong>1. 遗留代码</strong></p>
<p>众所周知，怎样把公司的那些遗留代码给并行化是一件非常困难的事情。100K~1000K的代码量都非常正常，而并行编程本身又是非常容易出错的，一大堆诸如data race, dependency, non-deterministic, memory consistency, dead lock, serialization bottleneck, thread safe等的问题随便哪一个拉出来都让人头大，更别说要高效可靠的并行化这些庞大的遗留代码了。更困难的是很多遗留代码还有编写者已经离职，文档注释不全等问题，这无疑是雪上加霜。从成本上来讲，如果能通过一些优秀的编译器(例如Intel的ICC)自动并行化一些遗留代码无疑是最省钱的，但是这种方法最大的缺陷就在于像Intel ICC这种自动型编译器能自动并行化的代码非常少，从而导致它能提供的性能优化非常有限，而且就算是真正能获得speedup的代码也有很多约束条件(例如loop的循环之间没有dependence，并且该loop应该是一个程序热点)。所以目前的现状就是大量的遗留代码并不能有效的被并行化，从商业的角度上来讲，如果能有一种解决方案能在短时间内快速可靠的通过实施并行化让遗留代码在多核平台上获得10%~30%的性能提升，那么它就已经能为公司节省大量成本了。</p>
<p><strong>2. 教育</strong></p>
<p>第二大的障碍可能就是程序员缺乏并行编程方面的教育了。其实并行编程已经有二三十年的历史，不过在多核CPU出现之前那些并行编程都是“专家”们的玩具。那时候的并行编程大都是跑在集群、大型机或者服务器上，通过MPI(message passing interface)或者SMP(对称多处理器，即一个主板上有多个单核CPU，属于shared memory model)来完成并行计算。Pthread标准是1995年建立的，之后出来了Windows版的Win32 thread，后来又出来了“编译指导”、面向data parallel模型的OpenMP(OpenMP 3.0加入了task parallel支持)，task parallel的鼻祖Cilk，Intel的Intel Thread Building Block(task parallel)，Java 1.5开始对多线程提供较好的支持(加入了Java Memory Model)，近几年随着GPU的发展，Nvidia又开始搞CUDA(data-parallel)，Apple一看不对，并行编程以后是主流啊，我得插一手，于是自己撑旗弄了个针对CPU和GPU混合编程的OpenCL，微软一看也坐不住了也要随着Visual Studio2010开始搞C#的并行库，马上C++0x也要加入多线程支持，甚至连老古董Erlang也因为天生支持并行被重新热炒，总之随着摩尔定律在串行世界的失效，整个业界都开始<em>被迫</em>往并行编程方向发展。</p>
<p>可是对程序员来说呢是什么情况呢？我们现在所接受的教育大都还是串行世界的那些算法和数据结构，高德纳在一篇<a id="y-:i" style="color: #551a8b;" title="访谈" href="http://blog.csdn.net/programmer_editor/archive/2008/07/10/2631316.aspx">访谈</a>里说“在我看来，这种现象或多或少是由于硬件设计者已经无计可施了导致的，他们将Moore定律失效的责任推脱给软件开发者，而他们给我们的机器只是在某些指标上运行得更快了而已。如果多线程的想法被证明是失败的，我一点都不会感到惊讶&#8230;&#8230;你听说过有多少程序员对这种未来一片光明的机器抱有强烈的兴趣？我几乎没有听说过，除了他们的诉苦。尽管我们学院那些搞硬件的家伙一直想让我相信我是错的”，可见硬件发展被迫向多核转移直接导致程序员们<a id="gnai" style="color: #551a8b;" title="免费的午餐已经结束" href="http://www.gotw.ca/publications/concurrency-ddj.htm">免费的午餐已经结束</a>了。那么程序员现在受到良好的并行编程教育了吗？很显然，现在随便问一个普通的程序员：“你觉得并行编程容易么？”，十有八九会说“我觉得很难”。前一阵有人讨论服务器编程用多线程好还是多进程好？其实根本原因就在于哪怕多线程有性能优势，可是isolation的多进程模式能在programming productivity和performance之间找到比较好的折衷，所以国内很有服务器开发者都选择了多进程(例如<a id="b.12" style="color: #551a8b;" title="云风" href="http://blog.codingnow.com/2006/10/multi_process_design.html">云风</a>)。从大趋势上来讲，不管是研究体系机构的，还是写OS/Compiler的，还是定义编程语言的，现在都在积极努力的为广大的程序员提供一个更容易使用的并行编程模型，Intel这几年不也在搞多核培训么，这都是好现象，但是，离真正的全民并行编程时代还有相当长的路要走。近几年的IT技术热门书单里面很少有并行编程的书籍就是个很好的写照。</p>
<p><strong>3. 工具</strong></p>
<p>工欲善其事，必先利其器。那么现阶段我们能用的，并且好用的并行编程工具有多少呢（欢迎大家补充）？</p>
<p>(1) IDE: Intel Parallel Studio，微软马上出来的VS2010算一个，Sun的Sun Studio(不知道它的未来如何，但是它本来就很小众)，Nvidia的CUDA平台什么的就先不算了<br />
(2) Compiler: Intel的ICC(能自动并行化一些代码)，<a id="byuh" style="color: #551a8b;" title="Nema Labs" href="http://www.nemalabs.com/">Nema Labs</a>的FASThread(一套可以快速可靠的指导程序员实施并行化的解决方案，特别适合将遗留代码并行化)<br />
(3) Performance Tuning: Intel Vtune Analyzer(综合性能分析)，Thread profiler，<a id="r5i1" style="color: #551a8b;" title="Acumem" href="http://www.acumem.com/">Acumem</a>的Thread Spotter(针对多核Cache的性能分析和优化)<br />
(4) Debugging: Petra的<a id="ox8:" style="color: #551a8b;" title="Jinx" href="http://petravm.com/">Jinx</a></p>
<p>总体上我个人觉得它们对程序员来说确实有用，但是前提条件是你要会用。这其实又跟第二点“教育”有很大关系了。</p>
<p><strong>4. 对众核的恐惧</strong></p>
<p>现在我们看到4核已经非常普遍了，等过几年那可就是8核，16核，32核了。怎样确保你的代码在核数倍增的趋势下仍能有很好的性能，很好的可伸缩性？这真的是个问题。我现在所做的研究就是多线程程序中锁竞争的性能分析，目的就是为了帮助程序员更好的解决由锁竞争造成的性能瓶颈。实际上，为了得到很好的可伸缩性，程序员需要往往需要使用并行友好的数据结构(例如concurrent hash map)，使用细粒度的锁甚至无锁编程，设计data parallel的算法，性能调优(例如典型的false sharing问题)等等等等，这其中每一项都是不小的挑战。我曾经翻译过的一篇文章对设计多线程程序提供了一些<a id="t8n7" style="color: #551a8b;" title="有用的建议" href="http://www.parallellabs.com/2010/02/18/8-simple-rules-for-designing-multithreaded-applications/">有用的建议</a>。</p>
<p><strong>5. 可维护性</strong></p>
<p>毫无疑问，我们希望并行代码能够与现存的runtime系统、build系统以及其他现有代码一起正确的工作，我们更希望这些并行代码易于理解、便于维护并且有较长的生命周期。可是现阶段真正掌握并行编程的程序员少之又少，而且并行编程又是这么困难，哪怕你对这些并行代码只是做一些小小的改动都很有可能导致新的bug，新的性能瓶颈，那真的是一件非常痛苦的事情。</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%AE%9E%E6%96%BD%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E7%9A%84%E4%BA%94%E5%A4%A7%E9%9A%9C%E7%A2%8D&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F03%2F22%2Ffive-obstacles-that-slow-down-parallelism%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%AE%9E%E6%96%BD%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E7%9A%84%E4%BA%94%E5%A4%A7%E9%9A%9C%E7%A2%8D&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F03%2F22%2Ffive-obstacles-that-slow-down-parallelism%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li><li>08/27/2011 -- <a href="http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/" title="浅析C++多线程内存模型 ">浅析C++多线程内存模型 </a></li><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>04/15/2010 -- <a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/" title="多线程程序中操作的原子性">多线程程序中操作的原子性</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/03/22/five-obstacles-that-slow-down-parallelism/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>为什么程序员需要关心顺序一致性（Sequential Consistency）而不是Cache一致性（Cache Coherence？）</title>
		<link>http://www.parallellabs.com/2010/03/06/why-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence/</link>
		<comments>http://www.parallellabs.com/2010/03/06/why-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 13:01:48 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[多线程内存模型]]></category>
		<category><![CDATA[多线程编程]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=367</guid>
		<description><![CDATA[本文所讨论的计算机模型是Shared Memory Multiprocessor，即我们现在常见的共享内存的多核CPU。本文适合的对象是想用C++或者Java进行多线程编程的程序员。本文主要包括对Sequential Consistency和Cache Coherence的概念性介绍并给出了一些相关例子，目的是帮助程序员明白为什么需要在并行编程时关注Sequential Consistency。

<a href="http://www.parallellabs.com/2010/03/06/why-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence/">阅读全文>></a> 

<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A8%8B%E5%BA%8F%E5%91%98%E9%9C%80%E8%A6%81%E5%85%B3%E5%BF%83%E9%A1%BA%E5%BA%8F%E4%B8%80%E8%87%B4%E6%80%A7%EF%BC%88Sequential+Consistency%EF%BC%89%E8%80%8C%E4%B8%8D%E6%98%AFCache%E4%B8%80%E8%87%B4%E6%80%A7%EF%BC%88Cache+Coherence%EF%BC%9F%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F03%2F06%2Fwhy-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A8%8B%E5%BA%8F%E5%91%98%E9%9C%80%E8%A6%81%E5%85%B3%E5%BF%83%E9%A1%BA%E5%BA%8F%E4%B8%80%E8%87%B4%E6%80%A7%EF%BC%88Sequential+Consistency%EF%BC%89%E8%80%8C%E4%B8%8D%E6%98%AFCache%E4%B8%80%E8%87%B4%E6%80%A7%EF%BC%88Cache+Coherence%EF%BC%9F%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F03%2F06%2Fwhy-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p><em><span style="color: #0000ff;">最后一次修改：2010年11月11日</span></em></p>
<p>本文所讨论的计算机模型是Shared Memory Multiprocessor，即我们现在常见的共享内存的多核CPU。本文适合的对象是想用C++或者Java进行多线程编程的程序员。本文主要包括对Sequential Consistency和Cache Coherence的概念性介绍并给出了一些相关例子，目的是帮助程序员明白为什么需要在并行编程时关注Sequential Consistency。</p>
<p>Sequential Consistency（下文简称SC）是Java内存模型和即将到来的C++0x内存模型的一个关键概念，它是一个最直观最易理解的多线程程序执行顺序的模型。Cache Coherence（下文简称CC）是多核CPU在硬件中已经实现的一种机制，简单的说，它确保了对在多核CPU的Cache中一个地址的读操作一定会返回那个地址最新的（被写入）的值。</p>
<p>那么为什么程序员需要关心SC呢？因为现在的硬件和编译器出于性能的考虑会对程序作出违反SC的优化，而这种优化会影响多线程程序的正确性，也就是说你用C++编写的多线程程序可能会得到的不是你想要的错误的运行结果。Java从JDK1.5开始加入SC支持，所以Java程序员在进行多线程编程时需要注意使用Java提供的相关机制来确保你程序的SC。程序员之所以不需要关心CC的细节是因为现在它已经被硬件给自动帮你保证了（不是说程序员完全不需要关心CC，实际上对程序员来说理解CC的大致工作原理也是很有帮助的，典型的如避免多线程程序的<a href="http://blog.yufeng.info/archives/783">伪共享问题</a>，即<a href="http://en.wikipedia.org/wiki/False_sharing">False Sharing</a>）。</p>
<p>那么什么是SC，什么是CC呢？</p>
<h3>1. Sequential Consistency (顺序一致性）</h3>
<p>SC的作者Lamport给的严格定义是：<br />
<em>“&#8230; the result of any execution is the same as if the operations of all the processors were executed in some sequential order, and the operations of each individual processor appear in this sequence in the order specified by its program.”</em></p>
<p>这个概念初次理解起来拗口，不过不要紧，下面我会给出个很直观的例子帮助理解。</p>
<p>假设我们有两个线程（线程1和线程2）分别运行在两个CPU上，有两个初始值为0的全局共享变量x和y，两个线程分别执行下面两条指令：</p>
<p>初始条件： x = y = 0;</p>
<table style="font-size: 1em; line-height: inherit; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="3" width="100%" bordercolor="#000000">
<tbody>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%"><em>线程 1</em></td>
<td style="text-align: center;" width="50%"><em>线程 2</em></td>
</tr>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%">x = 1;</td>
<td style="text-align: center;" width="50%">y=1;</td>
</tr>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%">r1 = y;</td>
<td style="text-align: center;" width="50%">r2 = x;</td>
</tr>
</tbody>
</table>
<p>因为多线程程序是交错执行的，所以程序可能有如下几种执行顺序：</p>
<table style="font-size: 1em; line-height: inherit; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="3" width="100%" bordercolor="#000000">
<tbody></tbody>
</table>
<table style="font-size: 1em; line-height: inherit; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="3" width="100%" bordercolor="#000000">
<tbody>
<tr style="text-align: left;">
<td style="text-align: center;" width="33.333333333333336%">Execution 1</td>
<td style="text-align: center;" width="33.333333333333336%">Execution 2</td>
<td style="text-align: center;" width="33.333333333333336%">Execution 3</td>
</tr>
<tr style="text-align: left;">
<td width="33.333333333333336%">
<div style="margin-top: 0px; margin-bottom: 0px;">x = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r1 = y;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">y = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r2 = x;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">结果:r1==0 and r2 == 1</div>
</td>
<td width="33.333333333333336%">
<div style="margin-top: 0px; margin-bottom: 0px;">y = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r2 = x;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">x = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r1 = y;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">结果: r1 == 1 and r2 == 0</div>
</td>
<td width="33.333333333333336%">
<div style="margin-top: 0px; margin-bottom: 0px;">x = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">y = 1;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r1 = y;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">r2 = x;</div>
<div style="margin-top: 0px; margin-bottom: 0px;">结果: r1 == 1 and r2 == 1</div>
</td>
</tr>
</tbody>
</table>
<p>当然上面三种情况并没包括所有可能的执行顺序，但是它们已经包括所有可能出现的结果了，所以我们只举上面三个例子。我们注意到这个程序只可能出现上面三种结果，但是不可能出现r1==0 and r2==0的情况。</p>
<p>SC其实就是规定了两件事情：<br />
（1）每个线程内部的指令都是按照程序规定的顺序（program order）执行的（单个线程的视角）<br />
（2）线程执行的交错顺序可以是任意的，但是所有线程所看见的整个程序的总体执行顺序都是一样的（整个程序的视角）</p>
<p>第一点很容易理解，就是说线程1里面的两条语句一定在该线程中一定是x=1先执行，r1=y后执行。第二点就是说线程1和线程2所看见的整个程序的执行顺序都是一样的，举例子就是假设线程1看见整个程序的执行顺序是我们上面例子中的Execution 1，那么线程2看见的整个程序的执行顺序也是Execution 1，不能是Execution 2或者Execution 3。</p>
<p>有一个更形象点的例子。伸出你的双手，掌心面向你，两个手分别代表两个线程，从食指到小拇指的四根手指头分别代表每个线程要依次执行的四条指令。SC的意思就是说：<br />
（1）对每个手来说，它的四条指令的执行顺序必须是从食指执行到小拇指<br />
（2）你两个手的八条指令（八根手指头）可以在满足（1）的条件下任意交错执行（例如可以是左1，左2，右1，右2，右3，左3，左4，右4，也可以是左1，左2，左3，左4，右1，右2，右3，右4，也可以是右1，右2，右3，左1，左2，右4，左3，左4等等等等）</p>
<p>其实说简单点，SC就是我们最容易理解的那个多线程程序执行顺序的模型。</p>
<h3>2. Cache Conherence （缓存一致性）</h3>
<p>那么CC是干什么用的呢？这个要详细说的话就复杂了，写一本书绰绰有余。简单来说，我们知道现在的多核CPU的Cache是多层结构，一般每个CPU核心都会有一个私有的L1级和L2级Cache，然后多个CPU核心共享一个L3级缓存，这样的设计是出于提高内存访问性能的考虑。但是这样就有一个问题了，每个CPU核心之间的私有L1，L2级缓存之间需要同步啊。比如说，CPU核心1上的线程A对一个共享变量global_counter进行了加1操作，这个被写入的新值存到CPU核心1的L1缓存里了；此时另一个CPU核心2上的线程B要读global_counter了，但是CPU核心2的L1缓存里的global_counter的值还是旧值，最新被写入的值现在还在CPU核心1上呢！怎么把？这个任务就交给CC来完成了！</p>
<p>CC是Cache之间的一种同步协议，它其实保证的就是对某一个地址的读操作返回的值一定是那个地址的最新值，而这个最新值可能是该线程所处的CPU核心刚刚写进去的那个最新值，也可能是另一个CPU核心上的线程刚刚写进去的最新值。举例来说，上例的Execution 3中，r1 = y是对y进行读操作，该读操作一定会返回在它之前已经执行的那条指令y=1对y写入的最新值。可能程序员会说这个不是显而意见的么？r1肯定是1啊，因为y=1已经执行了。其实这个看似简单的”显而易见“在多核processor的硬件实现上是有很多文章的，因为y=1是在另一个CPU上发生的事情，你怎么确保你这个读操作能立刻读到别的CPU核心刚刚写入的值？不过对程序员来讲你不需要关心CC，因为CPU已经帮你搞定这些事情了，不用担心多核CPU上不同Cache之间的同步的问题了（感兴趣的朋友可以看看体系结构的相关书籍，现在的多核CPU一般是以MESI protocol为原型来实现CC）。<strong>总结一下，CC和SC其实是相辅相承的，前者保证对单个地址的读写正确性，后者保证整个程序对多个地址读写的正确性，两者共同保证多线程程序执行的正确性。</strong></p>
<h3>3. 为什么要关心SC？</h3>
<p>好，回到SC的话题。为什么说程序员需要关心SC？因为现在的CPU和编译器会对代码做各种各样的优化，有时候它们可能会为了优化性能而把程序员在写程序时规定的代码执行顺序(program order)打乱，导致程序执行结果是错误的。</p>
<p>例如编译器可能会做如下优化，即把线程1的两条语序调换执行顺序：<br />
初始条件： x=y=0;</p>
<table style="font-size: 1em; line-height: inherit; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="3" width="100%" bordercolor="#000000">
<tbody>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%"><em><span style="font-size: x-small;">线程 1</span></em></td>
<td style="text-align: center;" width="50%"><em><span style="font-size: x-small;">线程 2</span></em></td>
</tr>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%"><span style="font-size: x-small;">r1 = y;</span></td>
<td style="text-align: center;" width="50%"><span style="font-size: x-small;">y=1;</span></td>
</tr>
<tr style="text-align: left;">
<td style="text-align: center;" width="50%"><span style="font-size: x-small;">x = 1;</span></td>
<td style="text-align: center;" width="50%"><span style="font-size: x-small;">r2 = x;</span></td>
</tr>
</tbody>
</table>
<p>那么这个时候程序如果按如下顺序执行就可能就会出现r1==r2==0这样程序员认为”不正确“的结果：</p>
<table style="font-size: 1em; line-height: inherit; border-collapse: collapse;" border="1" cellspacing="0" cellpadding="3" width="100%" bordercolor="#000000">
<tbody>
<tr style="text-align: left;">
<td style="text-align: center;" width="100%">Execution 4</td>
</tr>
<tr style="text-align: left;">
<td style="text-align: center;" width="100%">r1 = y;<br />
y = 1;<br />
r2 = x;<br />
x = 1;</td>
</tr>
</tbody>
</table>
<p>为什么编译器会做这样的优化呢？因为读一个在内存中而不是在cache中的共享变量需要很多周期，所以编译器就”自作聪明“的让读操作先执行，从而隐藏掉一些指令执行的latency，提高程序的性能。实际上这种类似的技术是在单核时代非常普遍的优化方法，但是在进入多核时代后编译器没跟上发展，导致了对多线程程序进行了违反SC的错误优化。为什么编译器很难保证SC？因为对编译器来讲它很难知道多个线程在执行时会按照什么样的交错顺序执行，因为这需要一个整个程序运行时的视角，而只对一份静态的代码做优化的编译器是很难得到这种运行时的上下文的。那么为什么硬件也保证不了呢？因为CPU硬件中的写缓冲区（store buffer）会把要写入memory的值缓存起来，然后当前线程继续往下执行，而这个被缓存的值可能要很晚才会被其他线程“看见”，从而导致多线程程序逻辑出错。其实硬件也提供了一些例如Memory Barrier等解决方案，但是开销是一个比较大的问题，而且很多需要程序员手动添加memory barrier，现在还不能指望CPU或者编译器<strong>自动</strong>帮你搞定这个问题。（感兴趣的朋友可以在本文的参考文献中发现很多硬件优化造成SC被违反的例子以及Memory Barrier等解决方案）</p>
<p>好了，我们发现为了保证多线程的正确性，我们希望程序能按照SC模型执行；但是SC的对性能的损失太大了，CPU硬件和编译器为了提高性能就必须要做优化啊！为了既保证正确性又保证性能，在经过十几年的研究后一个新的新的模型出炉了：sequential consistency for data race free programs。简单地说这个模型的原理就是对没有data race的程序可以保证它是遵循SC的，这个模型在多线程程序的正确性和性能间找到了一个平衡点。对广大程序员来说，我们依赖高级语言内建的内存模型来帮我们保证多线程程序的正确性。例如，从JDK1.5开始引入的Java内存模型中已经支持data race free的SC了（例如使用volatile关键字，atomic变量等），但是C++程序员就需要等待C++0x中新的内存模型的atomic类型等来帮助保证SC了(因为atomic类型的值具有acquire和release语义，它隐式地调用了memory barrier指令)。什么意思呢？说简单点，就是由程序员用同步原语（例如锁或者atomic的同步变量）来保证你程序是没有data race的，这样CPU和编译器就会保证你程序是按你所想的那样执行的（即SC），是正确的。换句话说，程序员只需要恰当地使用具有acquire和release语义的同步原语标记那些真正需要同步的变量和操作，就等于告诉CPU和编译器你们不要对这些标记出来的操作和变量做违反SC的优化，而其它未被标记的地方你们可以随便优化，这样既保证了正确性又保证了CPU和编译器可以做尽可能多的性能优化。<del datetime="2010-10-26T10:19:54+00:00">来告诉编译器和CPU这里这里你不能做违反SC的优化，那里那里你不能做违反SC的优化，然后你写的程序就会得到正确的执行结果了。</del></p>
<p>从根源上来讲，在串行时代，编译器和CPU对代码所进行的乱序执行的优化对程序员都是封装好了的，无痛的，所以程序员不需要关心这些代码在执行时被乱序成什么样子，因为这些都被编译器和CPU封装起来了，你不用担心内部细节，它最终表现出来的行为就是按你想要的那种方式执行的。但是进入多核时代，程序员、编译器、CPU三者之间未能达成一致（例如诸如C/C++之类的编程语言没有引入多线程），所以CPU、编译器就会时不时地给你捣蛋，故作聪明的做一些优化，让你的程序不会按照你想要的方式执行，是错误的。Java作为引入多线程的先驱从1.5开始支持内存模型，等于是帮助程序员达成了与编译器、CPU（以及JVM）之间的契约，程序员只要正确的使用同步原语就可以保证程序最终表现出来的行为跟你所想的一样（即我们最容易理解的SC模型），是正确的。</p>
<p>本文并未详细介绍所有针对SC问题的解决方案（例如X86对SC的支持，Java对它的支持，C++对它的支持等等），如果想了解更多，可以参考本文所指出的参考文献。下一次我会写一篇关于data race free model, weak ordering, x86 memory model等相关概念的文章，敬请期待。</p>
<h3>题外话：</h3>
<p>并行编程是非常困难的，在多核时代的程序员不能指望硬件和编译器来帮你搞定所有的事情，努力学习多核多线程编程的一些基础知识是很有必要的，至少你应该知道你的程序到底会以什么样的方式被执行。</p>
<p>参考文献：<br />
<a href="http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/threadsintro.html">[1] Hans Boehm: C++ Memory Model</a><br />
<a href="http://www.cs.umd.edu/~pugh/java/memoryModel/">[2] Bill Pugh: The Java Memory Model</a><br />
<a href="http://en.wikipedia.org/wiki/Cache_coherence">[3] Wiki: Cache Coherence</a><br />
<a href="http://en.wikipedia.org/wiki/Sequential_consistency">[4] Wiki: Sequential Consistency</a><br />
<a href="http://ivanwangcn.spaces.live.com/blog/cns!F291BBD27380D1CA!153.entry">[5] The Memory Model of X86 (中文，从硬件角度讲SC问题)</a><br />
<a href="http://blog.csdn.net/pongba/archive/2007/06/20/1659952.aspx">[6] 《C++0x漫谈》系列之：多线程内存模型</a></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A8%8B%E5%BA%8F%E5%91%98%E9%9C%80%E8%A6%81%E5%85%B3%E5%BF%83%E9%A1%BA%E5%BA%8F%E4%B8%80%E8%87%B4%E6%80%A7%EF%BC%88Sequential+Consistency%EF%BC%89%E8%80%8C%E4%B8%8D%E6%98%AFCache%E4%B8%80%E8%87%B4%E6%80%A7%EF%BC%88Cache+Coherence%EF%BC%9F%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F03%2F06%2Fwhy-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E4%B8%BA%E4%BB%80%E4%B9%88%E7%A8%8B%E5%BA%8F%E5%91%98%E9%9C%80%E8%A6%81%E5%85%B3%E5%BF%83%E9%A1%BA%E5%BA%8F%E4%B8%80%E8%87%B4%E6%80%A7%EF%BC%88Sequential+Consistency%EF%BC%89%E8%80%8C%E4%B8%8D%E6%98%AFCache%E4%B8%80%E8%87%B4%E6%80%A7%EF%BC%88Cache+Coherence%EF%BC%9F%EF%BC%89&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F03%2F06%2Fwhy-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>08/27/2011 -- <a href="http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/" title="浅析C++多线程内存模型 ">浅析C++多线程内存模型 </a></li><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li><li>04/15/2010 -- <a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/" title="多线程程序中操作的原子性">多线程程序中操作的原子性</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/03/06/why-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>八条设计多线程程序的简单规则</title>
		<link>http://www.parallellabs.com/2010/02/18/8-simple-rules-for-designing-multithreaded-applications/</link>
		<comments>http://www.parallellabs.com/2010/02/18/8-simple-rules-for-designing-multithreaded-applications/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 11:59:01 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[多线程编程]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=343</guid>
		<description><![CDATA[前言：最近在看该作者的《The Art of Concurrency》，里面第四章就是上面这篇文章，觉得很实用而且很有共鸣。作者基于在并行编程领域的20多年工作经验总结成上面八条简单的原则，一下子帮我把之前并行编程时的一些认识给理清了，量化了，实在是“居家旅行，并行编程，必备良药”。花了几天时间把它翻译了一下，不知道各位在看了之后是否有些共鸣呢？

<a href=" http://www.parallellabs.com/2010/02/18/8-simple-rules-for-designing-multithreaded-applications">阅读全文>></a> 
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%85%AB%E6%9D%A1%E8%AE%BE%E8%AE%A1%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%AE%80%E5%8D%95%E8%A7%84%E5%88%99&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F02%2F18%2F8-simple-rules-for-designing-multithreaded-applications%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%85%AB%E6%9D%A1%E8%AE%BE%E8%AE%A1%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%AE%80%E5%8D%95%E8%A7%84%E5%88%99&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F02%2F18%2F8-simple-rules-for-designing-multithreaded-applications%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>更新：<br />
[2010.3.6] Scalability翻译从”可扩展性“改成”可伸缩性“.</p>
<p>前言：最近在看该作者的《The Art of Concurrency》，里面第四章就是上面这篇文章，觉得很实用而且很有共鸣。作者基于在并行编程领域的20多年工作经验总结成下面八条简单的原则，一下子帮我把之前并行编程时的一些认识给理清了，量化了，实在是“居家旅行，并行编程，必备良药”。花了几天时间把它翻译了一下，不知道各位在看了之后是否有些共鸣呢？</p>
<p><strong><br />
作者：Clay Breshears<br />
译者：并行实验室 Parallel Labs</strong></p>
<p>在Intel，并行化技术主要有四个步骤：分析，设计与实现，调试以及性能调优。这些步骤用来对一段串行代码进行并行化。尽管这四个步骤中的第一、三、四步都已经有了很多相关文档，但是关于怎样进行设计与实现的却不多。</p>
<p>并行编程更像是一门艺术，而不是一门科学。这里将会给出八条设计多线程程序的简单规则，你可以把他们一一放进你的多线程程序设计百宝箱中。通过参考这些规则，你能写出高质量、高效率的多线程程序。我努力试着将这些规则按照(半)时间顺序组织起来，但是它们之间并没有硬性的先后顺序。就像“别在泳池边奔跑”和“别在浅水区跳水”一样，两个都是好主意，但是后者也能放在前者的前面，反之亦然。</p>
<p><strong>规则一：找到真正不相关的计算任务</strong><br />
如果你将要执行的运算任务相互之间不独立的话，你是不可能将它们并行化的。我可以很容易的举出一些真实世界中相互独立的任务如何为了达成同一个目的而工作的例子。比如说一个DVD出租店，它先把收到的求租电影的订单分给员工们，员工再从存放电影DVD的地方根据订单找到影片拷贝。当一个员工取出一张古典音乐喜剧的拷贝时，他并不影响另一个寻找最近科幻电影大作的员工，也不影响另一个寻找某热门犯罪连续剧第二季花絮的员工（我假设所有不能被满足的订单在递交给DVD出租店之前就已经被处理过了）。同样的，每个订单的打包和邮递工作也不会影响其他订单的查找、运送和处理工作。</p>
<p>你也可能会遇到某些不能被并行化的而只能串行执行的计算任务，它们大多数是因为循环之间或者计算步骤之间有依赖关系从而导致它们只能按照特定的顺序串行执行。一个很好的例子是驯鹿怀孕的过程。通常驯鹿需要八个月来生小驯鹿，你不可能为了早点生个小驯鹿就让八个驯鹿来一起来生，想一个月就生出一个来。但是，如果圣诞老人希望尽快的扩充雪橇队伍，他可以让八只驯鹿一起生，这样八个月后就能有八只小驯鹿了（注：可以理解为尽管单个任务的执行时间没缩短，但是吞吐量却大了）。</p>
<p><strong>规则二：尽可能地在最高层进行并行化</strong><br />
在对一段串行代码进行并行化时我们有两种方法可以选择，一个是自底向上，另一个是自顶向下。在对我们的代码进行分析的过程中，我们先找到花费了最多执行时间的程序热点(hotspots)。对这些代码段进行并行化是使我们获得最大的性能提升的最好办法。</p>
<p>在自底向上的方法中，你可以考虑先直接对那些程序热点进行并行化。如果这不太可能实现的话，我们可以顺着它的调用栈(call stack)向上查找，看看能不能找到其他的可以并行化的程序热点。假如你的程序热点在一个嵌套循环的最里层，我们可以从内向外的逐一检查每一层循环，看看某一层是否能被并行执行。即使我们能一开始就很顺利的把程序热点并行化了，我们仍然应该去检查一下是否可能在调用栈中更高的某一层上实现并行化。这样做能提高每个线程所执行的任务的粒度。（注：每个线程所执行的任务的粒度可以理解为成功并行化了的部分在整个程序中所占的比例，根据Amdahl定律，并行化的部分越多，程序的整体性能越高）</p>
<p>为了更清楚的描述这条规则，让我们举一个对视频编码程序进行并行化的例子。如果你的程序热点是针对每个像素的计算，你可以先找到对一帧视频中的每个像素进行计算的循环，并考虑对它进行并行化。以此为基础向“上”找，你可能会发现对每一帧进行处理的循环也是可以被并行化的，这意味着每个线程都可以以帧为单位对一组数据进行独立的处理。如果这个视频编码程序同时要对好几个视频进行处理，那么让每个线程单独处理一个视频流将会是最高层的并行化。</p>
<p>在另一种自顶向下的并行化方法中，我们可以先对整个程序以及计算的流程（为了完成计算任务而依序组合起来的各个程序模块）进行分析。如果并行化的机会不是很明显，我们可以挑出那些包含了程序热点的模块并对他们进行分析，如果不行就再分析更小的程序热点模块，直到能找到独立的计算任务为止。</p>
<p>对视频编码程序的例子来说，如果你的程序热点是针对单个像素的计算，采用自顶向下的方法时就可以首先考虑该程序对多个不同的视频流进行编码的情况（每个编码任务都包含了像素计算的任务）。如果你能在这一层成功进行并行化，那么你已经得到了最高层的并行。如果没能成功，那我们可以向“下”找，看看每个视频流的不同帧的计算是否能被并行处理，最后看看每个帧的不同像素的计算是否能被并行处理。</p>
<p>并行任务的粒度可以理解成在进行同步之前所需要完成的计算量。同步之间运行的时间越长，粒度越大。细粒度的并行存在的隐患就是给每个线程分配的任务可能不够多，以至于都不够弥补使用多线程所带来的开销。此时，在计算量不变的情况下使用更多的线程只会让情况变得更加糟糕。粗粒度的并行化拥有相对来说更少的线程开销，并且更可能在线程增多的情况下仍然有很好的可扩展性。尽可能的在最高层对程序热点实现并行化是实现对多线程的粗粒度任务划分的主要方法之一。</p>
<p><strong>规则三：尽早针对众核趋势做好可伸缩性的规划</strong><br />
当我写这本书的时候，四核处理器已经成为了主流。未来处理器的核心数量只会越来越多。所以你应该在你的软件中为这个发展趋势做好规划。可伸缩性（scalability）被用来用来衡量一个程序应对变化的能力，典型的变化有系统资源（例如核心数量，内存大小，总线速度）或数据集大小的增加等。在面对越来越多的可用核心时，你必须写出能灵活高效的利用不同数量的核心的代码。</p>
<p>C. Northcote Parkinson说过，“数据的增长是为了适应处理能力的增加”。这意味着随着计算能力的增长加（核心数量的增加），很有可能我们会有更多的数据需要处理。我们永远会有更多的计算任务需要完成。不管是增加科学模拟中的建模精度，还是处理更清晰的高清视频，又或者搜索许多更大的数据库，如果你拥有了更多的计算资源，总会有人想要处理更多的数据。</p>
<p>用数据分解(data decomposition)的方法来设计和实现并行化能给你提供更多的高可扩展性的解决方案。任务分解(task decomposition)的方法可能会面临程序中可独立运行的函数或者代码段数量有限或者数量固定的问题。等到每一个独立的任务已经在单独的线程和核心上运行的时候，再想通过增加线程的数量来利用空闲的多余核心的方法就提高不了程序的性能了。因为在一个程序中数据的大小比独立的计算任务的数量更有可能增加，所以基于数据分解的设计将更有可能获得很好的可伸缩性。</p>
<p>即使有的程序已经基于任务分解的模式给每个线程分配了不同的计算任务，我们仍然可以在需要处理的数据增加的时候利用更多的线程来完成工作。例如我们需要修建一个杂货店，这项工程由一些不同的任务组成。如果开发商又买了一块相邻的地皮，并且商店要盖的楼层数翻倍了，我们可以雇佣更多的工人去完成这些的任务，比如说更多的油漆工，更多的盖顶工，更多的电工。因此，我们应该注意是否能对增加了的数据进行数据分解，以便利用空闲核心上的可用线程来完成这个工作，哪怕是在我们已经采用了任务分解的方式的程序中。</p>
<p><strong>规则四：尽可能利用已有的线程安全库</strong><br />
如果你的程序热点的计算任务能通过库函数调用来完成，强烈建议你考虑使用同等功能的库函数，而不是调用自己手写的代码。即使是串行程序，“重新造轮子”来完成已经被高度优化的库函数实现了的功能仍不是一个好主意。许多的库，例如Intel Math Kernel Library（Intel MKL）和Intel Integrated Performance Primitives (Intel IPP)，提供了能更好的利用多核处理器的并行版本的函数。</p>
<p>比使用并行版本的函数库更重要的一点是：我们需要确保所有的库函数调用都是线程安全的（thread-safe）。如果你已经把你串行代码中的程序热点替换成了一个库函数调用，你仍有可能在调用树(call tree)的更高层上发现能把程序分解成独立的计算任务的代码段。当你有好几个并行的计算任务，并且它们都同时调用了库函数（特别是第三方函数库），那么函数库中引用并更新共享变量的函数可能会造成数据竞争(data race)。记得好好检查你在并行编程中所调用的函数库的文档中关于线程安全性的描述。当你在设计和编写自己的用于并行执行的函数库时，请务必确保函数是可重入(reentrant)的。如果不能确保的话，你应该给共享的资源加上同步机制。</p>
<p><strong>规则五：使用合适的多线程模型</strong><br />
如果并行版的函数库不足以完成程序的并行化，而你又想使用可以自己控制的线程，在隐式的多线程模型能满足你的功能需求的前提下请尽量使用该模型（例如OpenMP或者Intel Thread Building Block）而不是显式的多线程模型（例如Pthread）。显式的多线程模型确实能提供对线程的更精确的控制。但是，如果你仅仅是想把你的计算密集型循环给并行化，或者你不需要显式多线程模型提供的诸多特性，那么我们最好还是能满足需要就好。实现的复杂度越高，犯错误的几率就越大，以后代码的维护难度也会越大。</p>
<p>OpenMP采用的是数据分解的方法，它尤其适合并行化那些需要处理大量数据的循环。尽管这种类型的并行化可能是唯一一种你能引入的并行模式，但是可能还会有其他的要求（例如由你的雇主或者管理层所决定的工程方案）让你不能使用OpenMP。如果是那样的话，我建议你先使用OpenMP来快速开发出并行化后的模型，估算一下可能的性能提升、可扩展性以及大概需要多少时间才能把这些串行代码用显式多线程库给并行化。</p>
<p><strong>规则六：永远不要假设具体的执行顺序</strong><br />
在串行程序中我们可以非常容易地预测某个程序的当前状态结束之后它会变成什么状态。然而，多个线程的执行顺序却是不确定的，它是由操作系统的调度器(scheduler)决定的。这意味着我们不可能准确的预测两个执行状态之间多个线程的执行顺序，甚至连预测哪个线程会在下一步被调度执行也不能。这样的机制主要是为了隐藏程序运行时的延迟，特别是当运行的线程的数量多于核心的数量时。例如，如果一个线程因为要访问不在cache中的地址，或者需要处理一个I/O请求而被阻塞了(blocked)，那么操作系统的调度器就会把该线程调度到等待队列里，同时把另一个等待执行的线程调度进来并执行它。</p>
<p>数据竞争(data race)就是由这种调度的不确定性造成的。如果你假设一个线程对共享变量的写操作会在另一个线程对该共享变量的读操作之前完成，你的预测可能会一直正确，有可能有些时候会正确，也有可能从来都不会正确。如果你足够幸运的话，有时候在一个特定平台上每次你运行这个程序时线程的执行顺序都不会改变。但是系统间的每个不同（例如数据在磁盘上存储的位置，内存的速度或者插座中的交流电源）都有可能影响线程的调度。对一段需要特定的线程执行顺序的代码来说，如果仅仅依靠乐观的估计而不采取任何实质性的措施的话，很有可能会受到数据竞争，死锁等问题的困扰。</p>
<p>从性能的角度来讲，最好的情形当然是让所有的线程尽可能没有约束的运行，就像比赛中的赛马或猎犬的一样。除非必要的话，尽可能不要规定一个特定的执行顺序。你需要找到那些确实需要规定执行顺序的地方，并且实现一些必要的同步方法来调整线程间的执行顺序。</p>
<p>拿接力赛跑来说，第一棒的选手会竭尽全力的奔跑。但是为了成功的完成接力赛，第二个，第三个和最后一棒都需要先等到拿到接力棒之后才能开始跑他们的赛段。接力棒的交接就是他们的同步机制，这样就确保了接力过程中的“执行”顺序。</p>
<p><strong>规则七：尽可能使用线程本地存储或者对特定的数据加锁</strong><br />
同步（Synchronization）本身并不属于计算任务，它只是为了确保程序的并行执行能得到正确的结果所产生的额外开销。虽然它产生了额外的开销但是又不可或缺。因此我们还是要尽可能的把同步所产生的开销降低到最低。你可以使用线程私有的存储空间或者独占的内存地址（例如一个用线程ID来进行索引的数组）来达到这个目的。</p>
<p>那些很少需要在线程间共享的临时变量可以被每个线程单独地在本地进行声明或分配。那些存储着每个线程的部分结果（partial result）的变量也应该是线程私有的。但是在把每个线程的部分结果保存到一个共享的变量的时候就需要采取一些适当的同步措施了。如果我们能确保这样的共享更新操作能尽可能少的进行，我们就可以把同步的额外开销降到最低了。如果我们使用显式的线程编程模型的话，我们可以使用那些线程本地存储（Thread Local Storage）的API来保证线程私有变量在多个并行区域的执行过程中，或者在一个并行函数的多次调用的过程中的一致性。</p>
<p>如果线程本地存储不可行，而且你必须用同步的对象（例如锁）来协调对共享资源的访问的话，请确保对数据进行了适当的锁操作。最简单的方法就是对锁和数据对象采取一一对应的分配策略。如果对变量的内存地址的访问都是在同一个临界区进行的话，我们就可以使用一把锁来对多个数据进行保护。</p>
<p>如果你有大量的数据需要保护，例如由一万个数据的数组，我们该怎么办呢？如果我们对整个数组只用一个锁来进行保护的话，很可能会造成严重的锁竞争从而导致性能瓶颈。那么我们是不是可以给每个数组元素创建一个锁呢？然而即使是有32个或者64个线程在同时访问这个数组，这样做看起来也浪费了很多的内存空间来保护那些只有百分之一不到的发生概率的访问冲突。不过有一种折中的解决方案，叫做“取模锁”（modulo lock）。取模锁是用来保护数据集合中的所有的第N个元素，其中N是锁的数量。例如，有两个锁，一个保护所有的奇数个的元素，另一个保护所有的偶数个元素。当需要访问一个被保护的变量时，线程需要先对要访问的地址进行取模操作，然后再去获得对应的取模锁。使用的锁的数量应该是基于线程的数量以及两个线程同时访问相同元素的可能性来决定。</p>
<p>但是，当你决定用锁来对数据进行保护时，请一定不要用多于一个的锁来给一个单独的元素进行加锁。西格尔定律告诉我们“一个人看着一个表能知道现在几点了，但是他要是有两个表那么他就确定不了时间了”。如果两个不同的锁都对同一个变量进行了保护，那么可能出现代码中的某一部分通过第一个锁来进行访问的同时，代码中的另一部分通过第二个锁也进行了访问。正在执行这两个代码段的多个线程就可能发生数据竞争，因为它们都以为它们对这个被保护的变量有独占的访问权限。</p>
<p><strong>规则八：敢于更换更易并行化的算法</strong><br />
当比较串行或者并行程序的性能的时候，运行时间就是衡量的首要标准。程序员会根据算法的时间复杂度来进行选择。时间复杂度和一个程序的性能是息息相关的。它的含义就是，当其他的一切条件都一样时，完成同样功能的时间复杂度为O(NlogN)的算法（例如快速排序）要比O（n^2）的算法（例如选择排序）要快。</p>
<p>在并行程序中，拥有更好的时间复杂度的算法也会更快一些。然而，有些时候时间复杂度更好的算法却不是很容易被并行化。如果算法的热点不太容易被并行化的话（而且在调用栈的更高层中你又找不到能很容易被并行化的热点），那么你可以尝试换一个稍微慢一点但是却更容易被并行化的算法。当然，还有可能一些其他的改动措施也能让你比较轻松的把某一段代码给并行化了。</p>
<p>这里我们可以给出一个线性代数中两个矩阵相乘的例子。Strassen的算法拥有最好的时间复杂度：O(n^2.81)。这当然比传统的三重循环的O(n^3)的算法要好。Strassen的算法把每个分成四部分，然后进行七次递归调用来对n/2 x n/2的子矩阵进行乘运算。如果想把这七次递归调用并行化的话，我们可以在每次的递归调用的时候创建一个新线程来进行运算，直到子矩阵到达一个预设的大小为止。这样的话线程的数量就会指数级的成倍增长。随着子矩阵越来越小，给新创建的线程分配的计算任务就会越来越少。还有另一种方法，就是先创建一个有七个线程的线程池。七次子矩阵相乘的运算任务可以分别分配给这七个线程以完成并行化。这样的话线程池就会跟串行版本的程序一样递归调用Strassen算法来对子矩阵进行乘运算。然而，这种方法的缺点就在于对一个拥有大于八个核的系统来说，永远只有七个核在工作，其他的资源都被浪费了。</p>
<p>另一个更容易被并行化的矩阵乘法就是三重循环的算法了。我们可以有很多方法来对矩阵进行数据分解（按行分解，按列分解或者按块分解）然后再把它们分配给不同的线程。通过用OpenMP在某一层循环中加上编译指示，或者用显式线程模型实现矩阵分割，我们很容易的就能完成并行化。只需要更少的代码改动就可以对这个简单的串行算法完成并行化，并且代码的整体结构改动也会比Strassen算法要少很多。</p>
<p><strong>总结</strong><br />
我们已经列出了八条简单的规则，在把串行程序并行化的过程中你应该时刻记住它们。通过遵循这些规则以及一些实际的编程规则，你应该可以更容易的创造更健壮的并行化解决方案，同时能包含更少的并行化时的问题，以及在更短的时间里得到最好的性能。</p>
<p><strong>原文链接：<a href="http://software.intel.com/en-us/articles/8-simple-rules-for-designing-threaded-applications/">8 Simple Rules for Designing Threaded Applications</a></strong></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%85%AB%E6%9D%A1%E8%AE%BE%E8%AE%A1%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%AE%80%E5%8D%95%E8%A7%84%E5%88%99&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F02%2F18%2F8-simple-rules-for-designing-multithreaded-applications%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%85%AB%E6%9D%A1%E8%AE%BE%E8%AE%A1%E5%A4%9A%E7%BA%BF%E7%A8%8B%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%AE%80%E5%8D%95%E8%A7%84%E5%88%99&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F02%2F18%2F8-simple-rules-for-designing-multithreaded-applications%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li><li>08/27/2011 -- <a href="http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/" title="浅析C++多线程内存模型 ">浅析C++多线程内存模型 </a></li><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>04/15/2010 -- <a href="http://www.parallellabs.com/2010/04/15/atomic-operation-in-multithreaded-application/" title="多线程程序中操作的原子性">多线程程序中操作的原子性</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/02/18/8-simple-rules-for-designing-multithreaded-applications/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>瑞典Ericsson总部Master Thesis面试回忆录</title>
		<link>http://www.parallellabs.com/2010/02/04/ericsson-interview-of-master-thesis-insweden/</link>
		<comments>http://www.parallellabs.com/2010/02/04/ericsson-interview-of-master-thesis-insweden/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 19:53:50 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[职业生涯]]></category>
		<category><![CDATA[Chalmers]]></category>
		<category><![CDATA[Ericsson]]></category>
		<category><![CDATA[Interview]]></category>
		<category><![CDATA[面试]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=323</guid>
		<description><![CDATA[2009 May 5th:

晚上刚从超市回来就发现Gtalk弹出新邮件的消息，第一眼就看见标题中Interview的字眼，立刻欣喜若狂，急急忙忙打开仔细一看，竟然是我最早申请的职位的Interview！我是April 24th投的这个职位(Master Thesis)，另外还投了若干Summer Job（其中就包括我当天刚刚投完的Nema Labs的Summer job，后面会详叙），Volvo的Master Thesis以及其他几个Ericsson的Thesis Position。

 

因为这个是我投出去的第一份申请，当时完全没有任何经验，而且Cover Letter和CV都不是最好，现在回想之所以能够拿到这个Interview，主要因为以下几点原因：

1. 专业对口，GPA够。职位是做Sensor Network的，我的专业是Networks and Distributed Systems，正好对口，而且我在刚刚结束的课程Project中正好做过Sensor Network的一个项目，可谓牛头对上了马嘴，不亦乐乎。另外GPA也是Ericsson非常看重的，很多职位写明必须4.0（满分5.0）以上，个人觉得4.3以上比较保险。

2. 简历虽然有些小纰漏，但是因为当时也有针对职位的要求进行修改，所以还是能给人第一眼的好印象的。

3. Cover Letter写得也还凑合。除了常规介绍外还重点说了说自己对那个Thesis的看法，扯了扯自己的本科毕设。[...]

<a href="http://www.parallellabs.com/2010/02/04/ericsson-interview-of-master-thesis-insweden/" title="http://www.parallellabs.com/2010/02/04/ericsson-interview-of-master-thesis-insweden/">阅读全文>></a> 

<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E7%91%9E%E5%85%B8Ericsson%E6%80%BB%E9%83%A8Master+Thesis%E9%9D%A2%E8%AF%95%E5%9B%9E%E5%BF%86%E5%BD%95&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F02%2F04%2Fericsson-interview-of-master-thesis-insweden%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E7%91%9E%E5%85%B8Ericsson%E6%80%BB%E9%83%A8Master+Thesis%E9%9D%A2%E8%AF%95%E5%9B%9E%E5%BF%86%E5%BD%95&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F02%2F04%2Fericsson-interview-of-master-thesis-insweden%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>前言：去年4月份我申请过一些6月份开始的毕业设计和暑假实习，最终拿到了Ericsson的master thesis offer和另一个哥德堡小公司的summer intern，Volvo在我拿到summer intern后也给了interview。现在应该已经有不少一年级的同学要开始找暑假实习了，我觉得你们可以考虑申请6月份开始的毕设(等毕设结束后再回学校把剩下的课程修完)。下面是我去位于Kista的Ericsson总部面试的经历，希望对大家有用。Summer Intern总体上来讲难度比thesis大很多，因为很多瑞典人也要竞争这种职位，而且那些提供summer intern的小公司也不太喜欢招foreigner。</p>
<p>2009 May 5th:</p>
<p>晚上刚从超市回来就发现Gtalk弹出新邮件的消息，第一眼就看见标题中Interview的字眼，立刻欣喜若狂，急急忙忙打开仔细一看，竟然是我最早申请的职位的Interview！我是April 24th投的这个职位(Master Thesis)，另外还投了若干Summer Job（其中就包括我当天刚刚投完的Nema Labs的Summer job，后面会详叙），Volvo的Master Thesis以及其他几个Ericsson的Thesis Position。</p>
<p>因为这个是我投出去的第一份申请，当时完全没有任何经验，而且Cover Letter和CV都不是最好，现在回想之所以能够拿到这个Interview，主要因为以下几点原因：</p>
<p>1. 专业对口，GPA够。职位是做Sensor Network的，我的专业是Networks and Distributed Systems，正好对口，而且我在刚刚结束的课程Project中正好做过Sensor Network的一个项目，可谓牛头对上了马嘴，不亦乐乎。另外GPA也是Ericsson非常看重的，很多职位写明必须4.0（满分5.0）以上，个人觉得4.3以上比较保险。</p>
<p>2. 简历虽然有些小纰漏，但是因为当时也有针对职位的要求进行修改，所以还是能给人第一眼的好印象的。</p>
<p>3. Cover Letter写得也还凑合。除了常规介绍外还重点说了说自己对那个Thesis的看法，扯了扯自己的本科毕设。</p>
<p>发信人是后来面试我的Dr. V.，我一查竟然是UCxx的出身，心想又是UCxx啊！不禁由衷的仰慕，立刻对之后的Interview十分的向往。事后证明Dr. V.人真的非常的nice，虽然有些许龅牙，但是至少英语听起来比较舒服啊！</p>
<p>之后的信件往来就是确定面试时间之类，定下下下周五之后立刻跟身在Kista的yoan师兄联系商量借住事宜（在此对师兄的热情相助表示深深感谢！是你让我在Kista感受到家的温暖啊！还顺带连累你熬了个通宵 囧），然后就是买往返的火车票之类。一切定好后剩下的两个礼拜就开始拼命准备，囫囵吞枣扫了些论文，再跟着看了些英文面试的资料，甚至还去了Career Office做了一次咨询。</p>
<p>这其中发生了一件比较逗的事情。因为哥德堡到斯德的来回火车票加起来600多SEK，我心想这一趟下去怎么的也得1000块了，要不问问看他们能不能给报销？再加上外国公司以往报销路费的事听了不少，我就借着发信问问题的机会顺带来了句：“I am wondering whether you will undertake my travel fee for this interview?” 猜猜人家怎么回的？</p>
<p>“it&#8217;s not possible to 报销路费， so我们只能电话Interview了”，我心想，大哥我这菜鸟要电话面试不就相当于直接管你要据信么，再说我票都定了大不了当去旅游好了，于是连忙给他发信解释说没关系云云。</p>
<p>2009 May 14th</p>
<p>早上6点的火车去Stockholm，4点半起的，等5点的第一班tram去Central Station。顺利等到4路电车，心想时间肯定来得及，耽误不了。但是不幸恰恰在心情放松麻痹大意的情况下发生了。我在离火车站还有两站路的时候突发奇想拿出口语书开始模拟英语面试，自己边模拟面试官边想着怎么回答，简直就是左右互搏，天人合一，不亦乐乎，十分忘我。练了5，6分钟后我发现不对了：怎么窗外还能看见火车啊？我仔细一看，我靠！还真是Central Station的火车，其中就有我要坐的x2000！我心中大叫不好，刚刚停的那站就是火车站，我给错过了！！我赶紧收拾东西站在门口准备在下站下车赶紧再坐回去，结果老天真给我开了个大玩笑：过了上一站之后Tram就进入郊区了，开了至少5分钟才到下一站！那5分钟简直就是我人生最漫长的一段时间之一，脑子100%运转，不停看表计算时间，同时储备体力随时准备狂奔。</p>
<p>5分钟后终于到达下一站了，赶紧下车，到对面站台看反方向的车几点到：5分钟以后！这意味着我到火车站后离发车只剩10分钟不到！！！而且我还从来没去过火车站都不知道火车在哪！天无绝人之路，我发现旁边竟然还有一个车站！赶紧对了下时间，Tram7马上就到，又多出了5分钟！老天保佑，我心急如焚的等着不紧不慢的7路小电车，来了！上车！走！到！门开的一霎那，我真是卯足了劲往站台冲啊！事后回想我大概只用了1分钟不到就找到了X2000的站台。这还多亏瑞典的火车站不像国内的那么大，还要进候车厅再排队检票上下楼梯什么的，站台离车站正门也就2-3分钟的路，而且上车后再检票。我悬着的心终于放下来了，事后回想就算当天没赶上我也可以再买下一班的，大不了先上车后补票，还好是我之前订的就是周四走周五面试。虽然我这不叫大难不死，但也算是必有后福啊！</p>
<p>顺利到达Stockholm。斯京的火车站和地铁站是连在一起的，下火车后直接就去地铁售票处买了张24h的通票（100SEK），直奔Kista。话说这个Kista号称瑞典最大的科技园区，里面不仅有Ericsson全球总部，华为瑞典分舵等众多IT公司，KTH也有一个分校区在那边。出了Kista地铁站直接就是一个大型Shopping Mall，在把正补觉的师兄吵醒之后顺利放下行李。中午吃了师兄做的红烧肉拌面，话说那个红烧肉确实很够味，真是赞！</p>
<p>下午就出去Kista园区去寻我明天面试的地点去了。来了Kista我最大的感受就是，整个Kista到处都是Ericsson的人。不管是在Shopping Mall里的Restaurant还是在工业园区的大街上，到处都是挂着蓝色Ericsson牌子的人，简直就是Ericsson大山寨。后来听到一个说法，Ericsson这样的国民企业其实更应该被看做一个Community，在Kista的shopping mall里面甚至有专门的Ericsson员工价，由此可见一般。顺便说一句，上次回国刚下飞机在机场大巴上，坐我旁边的竟然是个瑞典小哥，仔细一聊竟然也是学CS的，从Stockholm来中国找他中国女朋友，于是我就问“你是不是给Ericsson工作”，结果竟然猜对了。由此可见爱立信有多庞大。</p>
<p>事实也确实如此。一开始我找到的最显眼的是一栋白色的大型Ericsson办公楼，整个楼占了一个广场的大小，气势直逼瑞典皇宫了（当然更现代点），真不愧是世界级大公司的全球总部啊。于是我就去reception问我的面试官是不是在这栋楼办公，结果人家告诉我：“不好意思，你找的人在对面那栋楼办公，出门后直走就到了”。等我出去仔细一看，原来Ericsson Research是另一栋大红楼。我猜可能那栋大白楼里面应该都是Ericsson负责工业产品的部门吧。踩点完毕后就回家继续做准备去了。Tips：对面试要提前踩点，特别是去不熟悉的地方更要多做准备，因为瑞典人很忌讳迟到（瑞典交通发达，地铁非常准时，也没什么堵车，所以没有迟到的理由）。</p>
<p>虽然最后我拿到了这个Offer，但是说实话在面试之前我还是非常紧张的。这可是我第一次英文面试，两个面试官都是顶尖大学的PHD，还顶着Ericsson总部的光环。我做的主要准备如下：</p>
<p>1）根据Position Description看了几篇该领域的综述型Paper，以到达快速入门的目的；</p>
<p>2）仔细研究该Position的Requirement，结合自己的CV自己进行了若干次模拟面试</p>
<p>3）准备了自己本科毕设的资料（一页A4插图，直观明了）和，因为这个跟该Thesis有点相关</p>
<p>4）给面试专门准备了一份CV，突出了自己项目经验跟该position的相关性</p>
<p>面试的流程大致如下：</p>
<p>跟两份面试官打过招呼后直接把CV和Transcript递上（省了人家自己打印的功夫，而且给你第一印象就是你准备的很充分。“我把简历都给你带过来了，上面的都是你们需要的”）。Dr.V.人非常好的先给我介绍了一下该Thesis的大致背景，很好的帮助我消除了紧张情绪并帮助我快速进入状态。在了解到项目的大致框架后我适时的接过话题（适时把握话题的主动性，不是被人牵着鼻子走。“我对这个很熟，请听听我的想法”），抛出了我对这个项目的具体实现的想法（虽然有些当时我的想法有些许错误，但是很好的表现出自己对这个项目的兴趣，就像是说：“你看，我自己脑子里已经有一个实现了，我很有可能能把这个项目完成的很好”）。</p>
<p>再聊了一些项目的话题后面试官就开始问我的简历上的项目经验了。我就一个一个跟他们解释（“我做过的东西跟这个Thesis都很相关，我很有竞争力”），其中有几个他们比较熟悉的项目他们就会问你一些技术问题或者算法问题。不过只要自己对项目的背景知识和本身的实现比较熟悉基本没什么问题，而且就算真的不会直接说不会也没关系。我其中就有2个问题直接说了不会，很可能他们因为看重我其他的背景和我的学习能力所以没影响我拿offer。</p>
<p>我感觉我整个面试过程中最出彩的地方在介绍我的本科毕设部分。回想当年在白混了3年之后，心想最后一个毕设怎么的也得拿个A做出点像样的东西来，要不大学白过了，于是狠命搞了半年终于如愿以偿。正好毕设跟这个Thesis很相关，当我拿出我做的prototype的照片并向他们介绍它的功能的时候，我分明的感觉到两位Ericsson Researcher都被我打动了（“给我Offer吧！本科毕设我都拿A了，你们这个Thesis我肯定不会让你们失望的！”）。</p>
<p>最后Dr. V.非常Nice的送我下楼，我在电梯里又跟他聊起不能报销差旅费的事情，最后我对他说了我生平最有打动人的效果的一句英语：“I just want to let you know my serious and positive attitude for this position.”结果Dr.V.非常配合的笑着对我说：“Yes！You have！”</p>
<p>The End：May 19th下午正准备跟妞妞mixi，突然接到一个010开头的电话，我还奇怪难道是北京打来的？后来才知道在瑞典Stockholm的区号也是010。也许大家都猜到了，其实就是另一位面试官打来的Offer电话。</p>
<p>P.S. 虽然因为种种原因没去Ericsson，但是我仍然深深的被Ericsson HQ的魅力所吸引，它向我展现了一个世界电信巨头的风采。而Stockholm，它的美丽更是让我留恋。希望下一次妞妞能跟我再一次同游斯德。</p>
<p>P.S.S. 猜猜Kista最大的中国人群体里在哪？不错，就是华为！华为真是牛逼，我问过好几个瑞典人了，华为真的是一个爱立信强有力对手的存在，直接把分舵开到Ericsson老家，有点新东方把分舵开始ETS总部的意思。在此祝华为越来越牛逼！早日出台Kista华为员工价！</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E7%91%9E%E5%85%B8Ericsson%E6%80%BB%E9%83%A8Master+Thesis%E9%9D%A2%E8%AF%95%E5%9B%9E%E5%BF%86%E5%BD%95&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F02%2F04%2Fericsson-interview-of-master-thesis-insweden%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E7%91%9E%E5%85%B8Ericsson%E6%80%BB%E9%83%A8Master+Thesis%E9%9D%A2%E8%AF%95%E5%9B%9E%E5%BF%86%E5%BD%95&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F02%2F04%2Fericsson-interview-of-master-thesis-insweden%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>11/29/2010 -- <a href="http://www.parallellabs.com/2010/11/29/erlang-user-conference-2010-and-some-thoughts-on-career-of-programmers/" title="Erlang User Conference 2010见闻（兼谈程序员职业生涯）">Erlang User Conference 2010见闻（兼谈程序员职业生涯）</a></li><li>10/03/2010 -- <a href="http://www.parallellabs.com/2010/10/03/future-multiprocessors/" title="多核的未来">多核的未来</a></li><li>05/15/2010 -- <a href="http://www.parallellabs.com/2010/05/15/something-about-binary-numeral/" title="二进制的二三事">二进制的二三事</a></li><li>05/04/2010 -- <a href="http://www.parallellabs.com/2010/05/04/swedish-programmer/" title="聊一聊瑞典的程序员">聊一聊瑞典的程序员</a></li><li>12/09/2009 -- <a href="http://www.parallellabs.com/2009/12/09/h1n1-vaccination-in-sweden/" title="在瑞典打甲流疫苗">在瑞典打甲流疫苗</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/02/04/ericsson-interview-of-master-thesis-insweden/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Pthreads并行编程之spin lock与mutex性能对比分析</title>
		<link>http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/</link>
		<comments>http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 19:46:55 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[并行编程]]></category>
		<category><![CDATA[Pthreads]]></category>
		<category><![CDATA[多核]]></category>
		<category><![CDATA[多线程编程]]></category>
		<category><![CDATA[线程同步]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=233</guid>
		<description><![CDATA[POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API。线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段，其中最典型的应用就是用Pthreads提供的锁机制(lock)来对多个线程之间共 享的临界区(Critical Section)进行保护(另一种常用的同步机制是barrier)。

Pthreads提供了多种锁机制：
(1) Mutex（互斥量）：pthread_mutex_***
(2) Spin lock（自旋锁）：pthread_spin_***
(3) Condition Variable（条件变量）：pthread_con_***
(4) Read/Write lock（读写锁）：pthread_rwlock_***

Pthreads提供的Mutex锁操作相关的API主要有：
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_mutex_lock.txt">pthread_mutex_lock (pthread_mutex_t *mutex);</a>
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_mutex_trylock.txt"> pthread_mutex_trylock (pthread_mutex_t *mutex);</a>
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_mutex_unlock.txt"> pthread_mutex_unlock (pthread_mutex_t *mutex);</a>

Pthreads提供的与Spin Lock锁操作相关的API主要有：
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_spin_lock.txt">pthread_spin_lock (pthread_spinlock_t *lock);</a>
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_spin_trylock.txt">pthread_spin_trylock (pthread_spinlock_t *lock);</a>
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_spin_unlock.txt">pthread_spin_unlock (pthread_spinlock_t *lock);</a>

从实现原理上来讲，Mutex是属于sleep-waiting类型 的锁。例如在一个双核的机器上有两个线程(线程A和线程B)，它们分别运行在Core0和Core1上。当线程A想要 pthread_mutex_lock操作去得到一个临界区的锁时，如果这个锁正被线程B所持有，那么线程A就会被阻塞(bolcking)，Core0 会在此时进行上下文切换(Context Switch)，这样Core0就可以运行其他的任务(例如另一个线程C)而不必进行忙等待。而Spin lock则不然，它是属于busy-waiting类型的锁，如果线程A是使用pthread_spin_lock操作去请求锁，那么线程A就会一直在 Core0上进行忙等待并不停的进行锁请求，直到得到这个锁为止。



<a <a href="http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/">阅读全文>></a> 
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Pthreads%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E4%B9%8Bspin+lock%E4%B8%8Emutex%E6%80%A7%E8%83%BD%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F01%2F31%2Fpthreads-programming-spin-lock-vs-mutex-performance-analysis%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Pthreads%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E4%B9%8Bspin+lock%E4%B8%8Emutex%E6%80%A7%E8%83%BD%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F01%2F31%2Fpthreads-programming-spin-lock-vs-mutex-performance-analysis%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>POSIX threads(简称Pthreads)是在多核平台上进行并行编程的一套常用的API。线程同步(Thread Synchronization)是并行编程中非常重要的通讯手段，其中最典型的应用就是用Pthreads提供的锁机制(lock)来对多个线程之间共 享的临界区(Critical Section)进行保护(另一种常用的同步机制是barrier)。</p>
<p>Pthreads提供了多种锁机制：<br />
(1) Mutex（互斥量）：pthread_mutex_***<br />
(2) Spin lock（自旋锁）：pthread_spin_***<br />
(3) Condition Variable（条件变量）：pthread_con_***<br />
(4) Read/Write lock（读写锁）：pthread_rwlock_***</p>
<p>Pthreads提供的Mutex锁操作相关的API主要有：<br />
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_mutex_lock.txt">pthread_mutex_lock (pthread_mutex_t *mutex);</a><br />
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_mutex_trylock.txt"> pthread_mutex_trylock (pthread_mutex_t *mutex);</a><br />
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_mutex_unlock.txt"> pthread_mutex_unlock (pthread_mutex_t *mutex);</a></p>
<p>Pthreads提供的与Spin Lock锁操作相关的API主要有：<br />
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_spin_lock.txt">pthread_spin_lock (pthread_spinlock_t *lock);</a><br />
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_spin_trylock.txt">pthread_spin_trylock (pthread_spinlock_t *lock);</a><br />
<a href="https://computing.llnl.gov/tutorials/pthreads/man/pthread_spin_unlock.txt">pthread_spin_unlock (pthread_spinlock_t *lock);</a></p>
<p>从实现原理上来讲，Mutex属于sleep-waiting类型的锁。例如在一个双核的机器上有两个线程(线程A和线程B)，它们分别运行在Core0和Core1上。假设线程A想要通过pthread_mutex_lock操作去得到一个临界区的锁，而此时这个锁正被线程B所持有，那么线程A就会被阻塞(blocking)，Core0 会在此时进行上下文切换(Context Switch)将线程A置于等待队列中，此时Core0就可以运行其他的任务(例如另一个线程C)而不必进行忙等待。而Spin lock则不然，它属于busy-waiting类型的锁，如果线程A是使用pthread_spin_lock操作去请求锁，那么线程A就会一直在 Core0上进行忙等待并不停的进行锁请求，直到得到这个锁为止。</p>
<p>如果大家去查阅Linux glibc中对pthreads API的实现NPTL(<a id="d6h2" title="Native POSIX Thread Library" href="http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library">Native POSIX Thread Library</a>) 的源码的话(使用”getconf GNU_LIBPTHREAD_VERSION”命令可以得到我们系统中NPTL的版本号)，就会发现pthread_mutex_lock()操作如果没有锁成功的话就会调用system_wait()的系统调用（现在NPTL的实现采用了用户空间的<a href="http://en.wikipedia.org/wiki/Futex">futex</a>，不需要频繁进行系统调用，性能已经大有改善），并将当前线程加入该mutex的等待队列里。而spin lock则可以理解为在一个while(1)循环中用内嵌的汇编代码实现的锁操作(印象中看过一篇论文介绍说在linux内核中spin lock操作只需要两条CPU指令，解锁操作只用一条指令就可以完成)。有兴趣的朋友可以参考另一个名为<a id="g7o." title="sanos" href="http://www.jbox.dk/">sanos</a>的微内核中pthreds API的实现：<a id="hpz5" title="mutex.c" href="http://www.jbox.dk/sanos/source/lib/pthread/mutex.c.html">mutex.c</a> <a id="kpo_" title="spinlock.c" href="http://www.jbox.dk/sanos/source/lib/pthread/spinlock.c.html">spinlock.c</a>，尽管与NPTL中的代码实现不尽相同，但是因为它的实现非常简单易懂，对我们理解spin lock和mutex的特性还是很有帮助的。</p>
<p>那么在实际编程中mutex和spin lcok哪个的性能更好呢？我们知道spin lock在Linux内核中有非常广泛的利用，那么这是不是说明spin lock的性能更好呢？下面让我们来用实际的代码测试一下（请确保你的系统中已经安装了最近的g++）。</p>
<pre class="brush: cpp; title: ; notranslate">
// Name: spinlockvsmutex1.cc
// Source: http://www.alexonlinux.com/pthread-mutex-vs-pthread-spinlock
// Compiler(spin lock version): g++ -o spin_version -DUSE_SPINLOCK spinlockvsmutex1.cc -lpthread
// Compiler(mutex version): g++ -o mutex_version spinlockvsmutex1.cc -lpthread
#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/syscall.h&gt;
#include &lt;errno.h&gt;
#include &lt;sys/time.h&gt;
#include &lt;list&gt;
#include &lt;pthread.h&gt;

#define LOOPS 50000000

using namespace std;

list&lt;int&gt; the_list;

#ifdef USE_SPINLOCK
pthread_spinlock_t spinlock;
#else
pthread_mutex_t mutex;
#endif

//Get the thread id
pid_t gettid() { return syscall( __NR_gettid ); }

void *consumer(void *ptr)
{
    int i;

    printf(&quot;Consumer TID %lun&quot;, (unsigned long)gettid());

    while (1)
    {
#ifdef USE_SPINLOCK
        pthread_spin_lock(&amp;spinlock);
#else
        pthread_mutex_lock(&amp;mutex);
#endif

        if (the_list.empty())
        {
#ifdef USE_SPINLOCK
            pthread_spin_unlock(&amp;spinlock);
#else
            pthread_mutex_unlock(&amp;mutex);
#endif
            break;
        }

        i = the_list.front();
        the_list.pop_front();

#ifdef USE_SPINLOCK
        pthread_spin_unlock(&amp;spinlock);
#else
        pthread_mutex_unlock(&amp;mutex);
#endif
    }

    return NULL;
}

int main()
{
    int i;
    pthread_t thr1, thr2;
    struct timeval tv1, tv2;

#ifdef USE_SPINLOCK
    pthread_spin_init(&amp;spinlock, 0);
#else
    pthread_mutex_init(&amp;mutex, NULL);
#endif

    // Creating the list content...
    for (i = 0; i &lt; LOOPS; i++)
        the_list.push_back(i);

    // Measuring time before starting the threads...
    gettimeofday(&amp;tv1, NULL);

    pthread_create(&amp;thr1, NULL, consumer, NULL);
    pthread_create(&amp;thr2, NULL, consumer, NULL);

    pthread_join(thr1, NULL);
    pthread_join(thr2, NULL);

    // Measuring time after threads finished...
    gettimeofday(&amp;tv2, NULL);

    if (tv1.tv_usec &gt; tv2.tv_usec)
    {
        tv2.tv_sec--;
        tv2.tv_usec += 1000000;
    }

    printf(&quot;Result - %ld.%ldn&quot;, tv2.tv_sec - tv1.tv_sec,
        tv2.tv_usec - tv1.tv_usec);

#ifdef USE_SPINLOCK
    pthread_spin_destroy(&amp;spinlock);
#else
    pthread_mutex_destroy(&amp;mutex);
#endif

    return 0;
}
</pre>
<p>该程序运行过程如下：主线程先初始化一个list结构，并根据LOOPS的值将对应数量的entry插入该list，之后创建两个新线程，它们都执行consumer()这个任务。两个被创建的新线程同时对这个list进行pop操作。主线程会计算从创建两个新线程到两个新线程结束之间所用的时间，输出为下文中的”Result “。</p>
<p>测试机器参数：<br />
Ubuntu 9.04 X86_64<br />
Intel(R) Core(TM)2 Duo CPU     E8400  @ 3.00GHz<br />
4.0 GB Memory</p>
<p>从下面是测试结果：</p>
<pre class="brush: bash; title: ; notranslate">
gchen@gchen-desktop:~/Workspace/mutex$ g++ -o spin_version -DUSE_SPINLOCK spinvsmutex1.cc -lpthread
gchen@gchen-desktop:~/Workspace/mutex$ g++ -o mutex_version spinvsmutex1.cc -lpthread
gchen@gchen-desktop:~/Workspace/mutex$ time ./spin_version
Consumer TID 5520
Consumer TID 5521
Result - 5.888750

real    0m10.918s
user    0m15.601s
sys    0m0.804s

gchen@gchen-desktop:~/Workspace/mutex$ time ./mutex_version
Consumer TID 5691
Consumer TID 5692
Result - 9.116376

real    0m14.031s
user    0m12.245s
sys    0m4.368s
</pre>
<p>可以看见spin lock的版本在该程序中表现出来的性能更好。另外值得注意的是sys时间，mutex版本花费了更多的系统调用时间，这就是因为mutex会在锁冲突时调用system wait造成的。</p>
<p>但是，是不是说spin lock就一定更好了呢？让我们再来看一个锁冲突程度非常剧烈的实例程序：</p>
<pre class="brush: cpp; title: ; notranslate">
//Name: svm2.c
//Source: http://www.solarisinternals.com/wiki/index.php/DTrace_Topics_Locks
//Compile(spin lock version): gcc -o spin -DUSE_SPINLOCK svm2.c -lpthread
//Compile(mutex version): gcc -o mutex svm2.c -lpthread
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;pthread.h&gt;
#include &lt;sys/syscall.h&gt;

#define        THREAD_NUM     2

pthread_t g_thread[THREAD_NUM];
#ifdef USE_SPINLOCK
pthread_spinlock_t g_spin;
#else
pthread_mutex_t g_mutex;
#endif
__uint64_t g_count;

pid_t gettid()
{
    return syscall(SYS_gettid);
}

void *run_amuck(void *arg)
{
       int i, j;

       printf(&quot;Thread %lu started.n&quot;, (unsigned long)gettid());

       for (i = 0; i &lt; 10000; i++) {
#ifdef USE_SPINLOCK
           pthread_spin_lock(&amp;g_spin);
#else
               pthread_mutex_lock(&amp;g_mutex);
#endif
               for (j = 0; j &lt; 100000; j++) {
                       if (g_count++ == 123456789)
                               printf(&quot;Thread %lu wins!n&quot;, (unsigned long)gettid());
               }
#ifdef USE_SPINLOCK
           pthread_spin_unlock(&amp;g_spin);
#else
               pthread_mutex_unlock(&amp;g_mutex);
#endif
       }

       printf(&quot;Thread %lu finished!n&quot;, (unsigned long)gettid());

       return (NULL);
}

int main(int argc, char *argv[])
{
       int i, threads = THREAD_NUM;

       printf(&quot;Creating %d threads...n&quot;, threads);
#ifdef USE_SPINLOCK
       pthread_spin_init(&amp;g_spin, 0);
#else
       pthread_mutex_init(&amp;g_mutex, NULL);
#endif
       for (i = 0; i &lt; threads; i++)
               pthread_create(&amp;g_thread[i], NULL, run_amuck, (void *) i);

       for (i = 0; i &lt; threads; i++)
               pthread_join(g_thread[i], NULL);

       printf(&quot;Done.n&quot;);

       return (0);
}
</pre>
<p>这个程序的特征就是临界区非常大，这样两个线程的锁竞争会非常的剧烈。当然这个是一个极端情况，实际应用程序中临界区不会如此大，锁竞争也不会如此激烈。测试结果显示mutex版本性能更好：</p>
<pre class="brush: bash; title: ; notranslate">
gchen@gchen-desktop:~/Workspace/mutex$ time ./spin
Creating 2 threads...
Thread 31796 started.
Thread 31797 started.
Thread 31797 wins!
Thread 31797 finished!
Thread 31796 finished!
Done.

real    0m5.748s
user    0m10.257s
sys    0m0.004s

gchen@gchen-desktop:~/Workspace/mutex$ time ./mutex
Creating 2 threads...
Thread 31801 started.
Thread 31802 started.
Thread 31802 wins!
Thread 31802 finished!
Thread 31801 finished!
Done.

real    0m4.823s
user    0m4.772s
sys    0m0.032s
</pre>
<p>另外一个值得注意的细节是spin lock耗费了更多的user time。这就是因为两个线程分别运行在两个核上，大部分时间只有一个线程能拿到锁，所以另一个线程就一直在它运行的core上进行忙等待，CPU占用率一直是100%；而mutex则不同，当对锁的请求失败后上下文切换就会发生，这样就能空出一个核来进行别的运算任务了。（其实这种上下文切换对已经拿着锁的那个线程性能也是有影响的，因为当该线程释放该锁时它需要通知操作系统去唤醒那些被阻塞的线程，这也是额外的开销）</p>
<p>总结<br />
（1）Mutex适合对锁操作非常频繁的场景，并且具有更好的适应性。尽管相比spin lock它会花费更多的开销（主要是上下文切换），但是它能适合实际开发中复杂的应用场景，在保证一定性能的前提下提供更大的灵活度。</p>
<p>（2）spin lock的lock/unlock性能更好(花费更少的cpu指令)，但是它只适应用于临界区运行时间很短的场景。而在实际软件开发中，除非程序员对自己的程序的锁操作行为非常的了解，否则使用spin lock不是一个好主意(通常一个多线程程序中对锁的操作有数以万次，如果失败的锁操作(contended lock requests)过多的话就会浪费很多的时间进行空等待)。</p>
<p>（3）更保险的方法或许是先（保守的）使用 Mutex，然后如果对性能还有进一步的需求，可以尝试使用spin lock进行调优。毕竟我们的程序不像Linux kernel那样对性能需求那么高(Linux Kernel最常用的锁操作是spin lock和rw lock)。</p>
<p>2010年3月3日补记：这个观点在<a href="http://www.oracle.com/technology/documentation/berkeley-db/db/programmer_reference/transapp_tune.html">Oracle的文档</a>中得到了支持：</p>
<blockquote><p>During configuration, Berkeley DB selects a mutex implementation for the architecture. Berkeley DB normally prefers blocking-mutex implementations over non-blocking ones. For example, Berkeley DB will select POSIX pthread mutex interfaces rather than assembly-code test-and-set spin mutexes because pthread mutexes are usually more efficient and less likely to waste CPU cycles spinning without getting any work accomplished. </p></blockquote>
<p>p.s.调用syscall(SYS_gettid)和syscall( __NR_gettid )都可以得到当前线程的id:)</p>
<p>转载请注明来自: www.parallellabs.com</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Pthreads%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E4%B9%8Bspin+lock%E4%B8%8Emutex%E6%80%A7%E8%83%BD%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F01%2F31%2Fpthreads-programming-spin-lock-vs-mutex-performance-analysis%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Pthreads%E5%B9%B6%E8%A1%8C%E7%BC%96%E7%A8%8B%E4%B9%8Bspin+lock%E4%B8%8Emutex%E6%80%A7%E8%83%BD%E5%AF%B9%E6%AF%94%E5%88%86%E6%9E%90&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F01%2F31%2Fpthreads-programming-spin-lock-vs-mutex-performance-analysis%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>10/02/2011 -- <a href="http://www.parallellabs.com/2011/10/02/lock-in-parallel-programming/" title="并行编程中的“锁”难题">并行编程中的“锁”难题</a></li><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>08/27/2011 -- <a href="http://www.parallellabs.com/2011/08/27/c-plus-plus-memory-model/" title="浅析C++多线程内存模型 ">浅析C++多线程内存模型 </a></li><li>04/09/2011 -- <a href="http://www.parallellabs.com/2011/04/09/pthread-mutex-lock-and-thread-safety/" title="《程序员的自我修养》中关于加锁不能保证线程安全的一个错误">《程序员的自我修养》中关于加锁不能保证线程安全的一个错误</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>How to do performance analysis on your parallelized program efficiently?</title>
		<link>http://www.parallellabs.com/2010/01/31/how-to-do-performance-analysis-on-your-parallelized-program-efficiently/</link>
		<comments>http://www.parallellabs.com/2010/01/31/how-to-do-performance-analysis-on-your-parallelized-program-efficiently/#comments</comments>
		<pubDate>Sun, 31 Jan 2010 13:45:42 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[性能分析]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=176</guid>
		<description><![CDATA[<em>Be a scientist: Gather data. Analyze it. Especially when it comes to parallelism and scalability, there's just no substitute for the advice to measure, measure, measure, and understand what the results mean. Putting together test harnesses and generating and analyzing numbers is work, but the work will reward you with a priceless understanding of how your code actually runs, especially on parallel hardware—an understanding you will never gain from just reading the code or in any other way. And then, at the end, you will ship high-quality parallel code not because you think it's fast enough, but because you know under what circumstances it is and isn't (there will always be an "isn't"), and why.</em>

--<em>Herb Sutter</em>

<a href="http://www.parallellabs.com/2010/01/31/how-to-do-performance-analysis-on-your-parallelized-program-efficiently/">阅读全文>></a> 

<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=How+to+do+performance+analysis+on+your+parallelized+program+efficiently%3F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F01%2F31%2Fhow-to-do-performance-analysis-on-your-parallelized-program-efficiently%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=How+to+do+performance+analysis+on+your+parallelized+program+efficiently%3F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F01%2F31%2Fhow-to-do-performance-analysis-on-your-parallelized-program-efficiently%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p><em>Be a scientist: Gather data. Analyze it. Especially when it comes to parallelism and scalability, there&#8217;s just no substitute for the advice to measure, measure, measure, and understand what the results mean. Putting together test harnesses and generating and analyzing numbers is work, but the work will reward you with a priceless understanding of how your code actually runs, especially on parallel hardware—an understanding you will never gain from just reading the code or in any other way. And then, at the end, you will ship high-quality parallel code not because you think it&#8217;s fast enough, but because you know under what circumstances it is and isn&#8217;t (there will always be an “isn&#8217;t”), and why.</em></p>
<p>&#8211;<em>Herb Sutter</em></p>
<p><span style="color: #ffffff;">doubanclaim5959b1bcd330f270</span></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=How+to+do+performance+analysis+on+your+parallelized+program+efficiently%3F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F01%2F31%2Fhow-to-do-performance-analysis-on-your-parallelized-program-efficiently%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=How+to+do+performance+analysis+on+your+parallelized+program+efficiently%3F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2010%2F01%2F31%2Fhow-to-do-performance-analysis-on-your-parallelized-program-efficiently%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>10/25/2010 -- <a href="http://www.parallellabs.com/2010/10/25/practical-concurrent-queue-algorithm/" title="多线程队列的算法优化">多线程队列的算法优化</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2010/01/31/how-to-do-performance-analysis-on-your-parallelized-program-efficiently/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>09年感悟</title>
		<link>http://www.parallellabs.com/2009/12/31/09-summary/</link>
		<comments>http://www.parallellabs.com/2009/12/31/09-summary/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 02:01:56 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[生活笔记]]></category>
		<category><![CDATA[年终总结]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=156</guid>
		<description><![CDATA[上半年顺风顺水，有付出也有收获，良好的状态持续到暑假实习结束。下半年压力陡增，主要包括就业压力和毕设压力。一个是因为国内就业竞争的激烈，另一个是因为十分具有挑战性的毕设课题。

<strong>压力。</strong>有压力是好事，在恰当的时候它能转换为我的动力，督促我的行为，间接促进我的进步。但是对待压力也要心态平和，不要过于焦虑、消沉，否则会陷入非常被动的局面。看过一句话，压力大就是因为自信心不足。自信心是建立在刻苦的努力之上的。所以最好的状态还是Take it easy，找准最需要下功夫的地方，多勤奋一点，多努力一点，付出的比别人多自然就有丰厚的回报，而且随着一点一滴的积累，自信心自然也就来了。

<strong>定位。</strong>首先是找到并持续的激发自己的兴趣点，从事自己真正发自内心喜欢并且觉得有意义的事情，这往往是成功的第一步。不要被所谓的“热潮”牵着鼻子走，分散了自己的注意力不说，这些不是自己最感兴趣的事情往往也不太适合自己。最好的学习和工作状态是每天早晨睁开眼就很兴奋很期待今天要做的事情，不管是它能给他人带来很积极的影响，或是能提升自己的专业技能，都能给自己带来满足感、成就感。最怕的就是对事情只有三分钟热情，当几天过去热情不在，或是碰到困难后就放弃，这样往往最后就是竹篮打水一场空。其次就是对症下药，先找自己最薄弱的环节并积极去弥补它。不要左一下右一下，结果等到面对问题的时候那些最需要的技能还没准备好那就完了。这里引出了另一个话题，专注。


<a href="http://www.parallellabs.com/2009/12/31/09-summary/">阅读全文>></a> 
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=09%E5%B9%B4%E6%84%9F%E6%82%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F31%2F09-summary%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=09%E5%B9%B4%E6%84%9F%E6%82%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F31%2F09-summary%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>上半年顺风顺水，有付出也有收获，良好的状态持续到暑假实习结束。下半年压力陡增，主要包括就业压力和毕设压力。一个是因为国内就业竞争的激烈，另一个是因为十分具有挑战性的毕设课题。</p>
<p><strong>压力。</strong>有压力是好事，在恰当的时候它能转换为我的动力，督促我的行为，间接促进我的进步。但是对待压力也要心态平和，不要过于焦虑、消沉，否则会陷入非常被动的局面。看过一句话，压力大就是因为自信心不足。自信心是建立在刻苦的努力之上的。所以最好的状态还是Take it easy，找准最需要下功夫的地方，多勤奋一点，多努力一点，付出的比别人多自然就有丰厚的回报，而且随着一点一滴的积累，自信心自然也就来了。</p>
<p><strong>定位。</strong>首先是找到并持续的激发自己的兴趣点，从事自己真正发自内心喜欢并且觉得有意义的事情，这往往是成功的第一步。不要被所谓的“热潮”牵着鼻子走，分散了自己的注意力不说，这些不是自己最感兴趣的事情往往也不太适合自己。最好的学习和工作状态是每天早晨睁开眼就很兴奋很期待今天要做的事情，不管是它能给他人带来很积极的影响，或是能提升自己的专业技能，都能给自己带来满足感、成就感。最怕的就是对事情只有三分钟热情，当几天过去热情不在，或是碰到困难后就放弃，这样往往最后就是竹篮打水一场空。其次就是对症下药，先找自己最薄弱的环节并积极去弥补它。不要左一下右一下，结果等到面对问题的时候那些最需要的技能还没准备好那就完了。这里引出了另一个话题，专注。</p>
<p><strong>专注。</strong>提高学习效率最有效的办法就是专注。首先从生活习惯上改善，每天划出几大块完整的学习时间段有助于保持专注。把学习的精力集中在能提升自己核心竞争力的技能上，而不是“花拳绣腿”，看上去新鲜实际上没啥用处。其次，注意任务切换（Context Switch）是要花费时间和精力的。这体现在学习的过程中，例如你学着学着突然想上下网，结果这一上就是十几二十分钟，等你再切回学习这个进程，你得先花十几分钟找回刚刚学习的感觉，才能继续开始，这样宝贵的三十分钟就没了。解决办法就是尽量减少Context Switch的次数。</p>
<p><strong>计划。</strong>短期来看，给事情安排好优先级，给每天的工作都制定好计划；长期来看，给职业生涯做好规划。这样能有效的减少学习时的无所事事的（idle）时间（参考<a href="http://mindhacks.cn/2009/12/20/dark-time/">暗时间</a>一文），有效的提升productivity。以前我不相信我可以同时做好两三件大事，但是2010年我想挑战一下自己，从每天的时间安排做起，争取高效率快节奏的同时把两到三件事情给同时做好，因为我<a href="http://www.ce.chalmers.se/~pers/">导师</a>就是这么干的。我问过我导师你这么忙胆识还能把事情安排的井井有条（又是搞研究开会又是开公司）是不是因为你已经成功的把自己并行化了，他笑说他希望他有One million cores，这样他就能把所有的事情都处理的来。当然了，其实我发现一个重要原因是因为他有严格的时间管理方法，以小时为单位来详细安排自己每天的行程。</p>
<p><strong>思考。</strong>如果每天只是忙忙碌碌但是不进行足够深入的思考并总结自己得到的经验教训，所能得到的进步就会不够多。每天起床吃饭学习然后睡觉，但是不思考，就会停滞在一个思维水平上，往往不能得到大突破。<a href="http://mindhacks.cn/">刘未鹏</a>的博客有很多关于“思考”的好文，今年我的目标就是多思考，多总结，从而多进步。</p>
<p><strong>宠辱不惊。</strong>心智的成熟体现在“不以物喜，不以己悲”，抗压能力，调整能力等等上。我现在这个阶段，开始从校园走向社会，各方面的压力会迎面而来。这个时候更需要自己有良好的心态，积极的调整自己，善于化解压力，善于自我激励，时刻把握住自己的目标，不迷失自己的方向。</p>
<p><strong>眼光。</strong>眼光放长远些，明年的目标只是第一步，五年乃至十年的目标才是更值得关注的。当然，第一步的起点如果够高会很有帮助。</p>
<h3>09年大事记：</h3>
<p>09 Jan - 09 Mar</p>
<p>TDA297 Distributed Systems II, EDA281 Parallel Computer Organization and Design</p>
<p>09 Mar - 09 May</p>
<p>TIN092 Algorithm, EDA203 Unix Internal, Internship Applications &amp; Interviews</p>
<p>09 Jun - 09 Jul</p>
<p>Summer Intern at Nema Labs</p>
<p>09 Aug</p>
<p>Summer vacation in China</p>
<p>09 Sep - 09 Oct</p>
<p>TDA381 Concurrent Programming (pending), DAT145 Advanced topic in NDS</p>
<p>09 Oct - 09 Dec</p>
<p>DAT105 Computer Architecture, Master Thesis</p>
<h3>10年计划：</h3>
<p>09 Jan - 09 Mar</p>
<p>TDA231 - Algorithms for machine learning and inference</p>
<p>09 Jan - 09 Sep</p>
<p>Master Thesis</p>
<p>09 Jun - 09 Aug</p>
<p>Summer Internship</p>
<p>09 Fall</p>
<p>To be continued.</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=09%E5%B9%B4%E6%84%9F%E6%82%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F31%2F09-summary%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=09%E5%B9%B4%E6%84%9F%E6%82%9F&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F31%2F09-summary%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/01/2011 -- <a href="http://www.parallellabs.com/2011/01/01/hello-2011/" title="你好，2011！">你好，2011！</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2009/12/31/09-summary/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Proposal for the “Search and sort” competition of Findwise</title>
		<link>http://www.parallellabs.com/2009/12/30/proposal-for-the-search-and-sort-competition-of-findwise/</link>
		<comments>http://www.parallellabs.com/2009/12/30/proposal-for-the-search-and-sort-competition-of-findwise/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 01:26:54 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[业界评论]]></category>
		<category><![CDATA[互联网]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=146</guid>
		<description><![CDATA[In this April I took part in a competition hold by <a href="http://www.findwise.se" target="_blank">Findwise</a> and <a href="http://www.mriday.com" target="_blank">Mriday</a> which is about search technology.
<blockquote>Search and Sort &#124; Findwise

Current, Search and Sort &#124; Findwise April 25th, 2009

We are constantly acquiring innovative ideas and solutions in the field of search technology. Therefore we have created the following contest to discover people who are interested in joining Findwise and build next generation’s search technology.

Project overview

The name of this contest is called Search and Sort. We can start by looking at an example which everybody is familiar with, Google. The Google search engine is the most used search engine on the Web. The search results generated from it includes webpages, PDF, Word documents, Excel spreadsheets, Flash, videos etc. For any query, up to the first 1000 results can be shown with a maximum of 100 displayed per page.

</blockquote>
<a href="http://www.parallellabs.com/2009/12/30/proposal-for-the-search-and-sort-competition-of-findwise/">阅读全文>></a> 
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Proposal+for+the+%E2%80%9CSearch+and+sort%E2%80%9D+competition+of+Findwise&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F30%2Fproposal-for-the-search-and-sort-competition-of-findwise%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Proposal+for+the+%E2%80%9CSearch+and+sort%E2%80%9D+competition+of+Findwise&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F30%2Fproposal-for-the-search-and-sort-competition-of-findwise%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>In this April I took part in a competition hold by <a href="http://www.findwise.se" target="_blank">Findwise</a> and <a href="http://www.mriday.com" target="_blank">Mriday</a> which is about search technology.</p>
<blockquote><p>Search and Sort | Findwise</p>
<p>Current, Search and Sort | Findwise April 25th, 2009</p>
<p>We are constantly acquiring innovative ideas and solutions in the field of search technology. Therefore we have created the following contest to discover people who are interested in joining Findwise and build next generation’s search technology.</p>
<p>Project overview</p>
<p>The name of this contest is called Search and Sort. We can start by looking at an example which everybody is familiar with, Google. The Google search engine is the most used search engine on the Web. The search results generated from it includes webpages, PDF, Word documents, Excel spreadsheets, Flash, videos etc. For any query, up to the first 1000 results can be shown with a maximum of 100 displayed per page.</p>
<p>Despite all this power, it is still sometimes time consuming to find the exact piece of information you are looking for. This is because although the different results are ranked, they are not well organized. For the average user, wouldn’t it be neat if different types of search results are categorized and displayed in different<br />
groups?</p>
<p>Submission</p>
<p>Your submission for this contest should contain two parts</p>
<p>Think of a search engine based on the concept of Search and Sort. Come up with a user interface design including two pages. One welcome page with the search box (and whatever else you think is suitable), and one page with the different types of results categorized, sorted, and presented in a userfriendly fashion. There is no strict requirements on exactly how the results will be categorized. It is entirely up to you to decide the types of categories. In fact, this will be a key deciding factor when your contest submission is being reviewed.</p>
<p>The second part of the contest is to discuss the framework behind your graphical user interface. What programming language and platform do you suggest for building the system? How would you extract information from different types of results and use that information to categorize them? Describe the plan to develop and implement it. The key for this part is to show a good understanding of the basics of a search engine, and a passion to innovate new ideas.</p>
<p>Searching has become the standard way for Internet users to find information. This contest gives you the chance to take Searching to the next level. If you are interested in search technology and would like to join the leading vendor independent company within this segment in Sweden, then send us your ideas. We will carefully review your submission and provide feedback. Your submission should be in PDF or DOC format.</p>
<p>The deadline for submission is 2009-04-30</p>
<p>Reward</p>
<p>The top 5 submissions will be invited to Findwise and receive a learning session about the company and the future of search technology. The most outstanding submission will receive a monetary reward of 10 000 SEK. Job offers will be presented to qualified individuals if requirements are met.</p></blockquote>
<p>I spent a whole Sunday to write down a proposal for this topic. That&#8217;s the first time for me to write down something on “search technology” which is a very interesting and hot area nowdays. Even though this paper looks a lit bit naive now, I still like it since I enjoy the feeling of writing down something interesting very much.</p>
<p>You can find and download my proposal from the link below:</p>
<p><a href="http://docs.google.com/fileview?id=0B3e2Z4tVgRpsN2E3ZGZmNDQtNmFiYS00YjI0LWFiYzgtMWUzMDNkMjM1MWJi&amp;hl=en" target="_blank"><em><strong>Search and sort.pdf</strong></em></a></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Proposal+for+the+%E2%80%9CSearch+and+sort%E2%80%9D+competition+of+Findwise&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F30%2Fproposal-for-the-search-and-sort-competition-of-findwise%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Proposal+for+the+%E2%80%9CSearch+and+sort%E2%80%9D+competition+of+Findwise&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F30%2Fproposal-for-the-search-and-sort-competition-of-findwise%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>01/22/2012 -- <a href="http://www.parallellabs.com/2012/01/22/multicore-programming-in-cloud-era/" title="云计算时代的多核开发">云计算时代的多核开发</a></li><li>01/09/2012 -- <a href="http://www.parallellabs.com/2012/01/09/xrime/" title="X-RIME: 基于Hadoop的开源大规模社交网络分析工具">X-RIME: 基于Hadoop的开源大规模社交网络分析工具</a></li><li>12/28/2010 -- <a href="http://www.parallellabs.com/2010/12/28/multicore-and-mobile-devices/" title="移动设备进入多核时代！">移动设备进入多核时代！</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2009/12/30/proposal-for-the-search-and-sort-competition-of-findwise/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在瑞典打甲流疫苗</title>
		<link>http://www.parallellabs.com/2009/12/09/h1n1-vaccination-in-sweden/</link>
		<comments>http://www.parallellabs.com/2009/12/09/h1n1-vaccination-in-sweden/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 09:49:00 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[生活笔记]]></category>
		<category><![CDATA[Chalmers]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=132</guid>
		<description><![CDATA[如果在哥德堡想打甲流H1N1疫苗的话可以参考这里： 在页面左侧栏列出了哥德堡不同的地区的Vårdcentraler，离Chalmers最近的Vårdcentraler是属于Centrum地区。我去的是Vårdcentralen Gibraltargatan，就在图书馆旁边。打开Vårdcentralen Gibraltargatan的页面后有专门的接种时间等信息： Våra vaccinationstider För information om influensan och vaccineringen 一般他们都是8点开门，但是疫苗现在还是比较抢手，昨天11点到的时候已经没有了，所以今天我是早上8点到的，排到了24号，等了半个多小时轮到了我。等待时填了个人信息表，然后进去打针，打完后医生会给你写好一个小卡片让你留底。但是个人信息表是瑞典语的，以下是粗略翻译（仅供参考）： underlag för pandemivaccination (pandemrix) för patienten inför vaccinationen mot den pandemiska influensan ber vi dig svara på följande frågor 1. har du tidigare fatt nagon allvarlig reaktion (som yrsel, svimning, andnod eller utslag) ja/nej/vet ej 2. ar du allergisk mot agg 3. [...]
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%9C%A8%E7%91%9E%E5%85%B8%E6%89%93%E7%94%B2%E6%B5%81%E7%96%AB%E8%8B%97&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F09%2Fh1n1-vaccination-in-sweden%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%9C%A8%E7%91%9E%E5%85%B8%E6%89%93%E7%94%B2%E6%B5%81%E7%96%AB%E8%8B%97&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F09%2Fh1n1-vaccination-in-sweden%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>如果在哥德堡想打甲流H1N1疫苗的话可以参考<a href="http://primarvardengoteborg.vgregion.se/sv/Primar--och-tandvardsforvaltningen/Vara-omraden/Primarvarden-Goteborg/Vardcentraler/" target="_blank">这里</a>：</p>
<p>在页面左侧栏列出了哥德堡不同的地区的Vårdcentraler，离Chalmers最近的Vårdcentraler是属于<a href="http://primarvardengoteborg.vgregion.se/sv/Primar--och-tandvardsforvaltningen/Vara-omraden/Primarvarden-Goteborg/Vardcentraler/Centrum/" target="_blank">Centrum</a>地区。我去的是<a href="http://primarvardengoteborg.vgregion.se/sv/Primar--och-tandvardsforvaltningen/Vara-omraden/Primarvarden-Goteborg/Vardcentraler/Centrum/Gibraltargatan1/" target="_blank">Vårdcentralen Gibraltargatan</a>，就在图书馆旁边。打开Vårdcentralen Gibraltargatan的页面后有专门的接种时间等信息：</p>
<h2 style="margin-top: 0.6em; margin-right: 0px; margin-bottom: 0.2em; margin-left: 0px; font-family: Arial, Verdana, Helvetica, sans-serif; font-weight: bold; color: #005dab; font-size: 1.4em; padding: 0px;"><span style="color: #000000; font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-weight: normal; font-size: 13px;"><a style="font-family: Arial, Verdana, Helvetica, sans-serif; font-size: 1em; color: #005195; text-decoration: none;" href="http://hittavard.vgregion.se/hriv/HRIV.Search.searchunit-flow.flow?unitName=v%C3%A5rdcentralen+gibraltargatan&amp;healthcareType=18&amp;municipality=1480&amp;resultType=1&amp;noHeader=&amp;sortOrder=UNIT_NAME" target="_top">Våra vaccinationstider</a></span></h2>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; line-height: 1.5em; padding: 0px;"><a style="font-family: Arial, Verdana, Helvetica, sans-serif; font-size: 1em; color: #005195; text-decoration: none;" href="http://vard.vgregion.se/sv/" target="_blank">För information om influensan och vaccineringen</a></p>
<p style="margin-top: 0px; margin-right: 0px; margin-bottom: 1em; margin-left: 0px; line-height: 1.5em; padding: 0px;">一般他们都是8点开门，但是疫苗现在还是比较抢手，昨天11点到的时候已经没有了，所以今天我是早上8点到的，排到了24号，等了半个多小时轮到了我。等待时填了个人信息表，然后进去打针，打完后医生会给你写好一个小卡片让你留底。但是个人信息表是瑞典语的，以下是粗略翻译（仅供参考）：</p>
<blockquote><p>underlag för pandemivaccination (pandemrix)</p>
<p>för patienten</p>
<p>inför vaccinationen mot den pandemiska influensan ber vi dig svara på följande frågor</p>
<p>1. har du tidigare fatt nagon allvarlig reaktion (som yrsel, svimning, andnod eller utslag)</p>
<p>ja/nej/vet ej</p>
<p>2. ar du allergisk mot agg</p>
<p>3. medicinerar du med nagon blodfortunnande medicin, t.ex. waran eller fragmin? (galler ej trombyl)</p>
<p>4. har du nagon sjukdom eller medicin som påverkar ditt immunforsvar</p>
<p>5. har du nyligen (inom 1 manad) fatt nagot annat vaccin</p>
<p>6. tillhor du nagon medicinsk riskgrupp for den pandemiska flu</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>basis for pandemic vaccination (Pandemrix)<br />
the patient</p>
<p>for vaccination against pandemic influenza, please answer the following questions<br />
1. have you ever had any severe reaction (such as dizziness, fainting, shortness of breath or a rash)<br />
yes/no/do not know<br />
2nd Are you allergic to eggs<br />
3rd medication you with any blood-thinning medicine, such as warfarin or Fragmin? (Not Trombyl)<br />
4th you have an illness or medication that affects your immune system<br />
5th have you recently (within 1 month) received any other vaccine<br />
6th you belong to any medical risk groups for pandemic flu</p></blockquote>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=%E5%9C%A8%E7%91%9E%E5%85%B8%E6%89%93%E7%94%B2%E6%B5%81%E7%96%AB%E8%8B%97&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F09%2Fh1n1-vaccination-in-sweden%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=%E5%9C%A8%E7%91%9E%E5%85%B8%E6%89%93%E7%94%B2%E6%B5%81%E7%96%AB%E8%8B%97&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F12%2F09%2Fh1n1-vaccination-in-sweden%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>10/03/2010 -- <a href="http://www.parallellabs.com/2010/10/03/future-multiprocessors/" title="多核的未来">多核的未来</a></li><li>05/04/2010 -- <a href="http://www.parallellabs.com/2010/05/04/swedish-programmer/" title="聊一聊瑞典的程序员">聊一聊瑞典的程序员</a></li><li>02/04/2010 -- <a href="http://www.parallellabs.com/2010/02/04/ericsson-interview-of-master-thesis-insweden/" title="瑞典Ericsson总部Master Thesis面试回忆录">瑞典Ericsson总部Master Thesis面试回忆录</a></li><li>11/04/2009 -- <a href="http://www.parallellabs.com/2009/11/04/launched-my-master-thesis-finally/" title="Launched my master thesis finally">Launched my master thesis finally</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2009/12/09/h1n1-vaccination-in-sweden/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An interesting algorithm problem: the longest plateau</title>
		<link>http://www.parallellabs.com/2009/11/12/algorithm-the-longest-plateau/</link>
		<comments>http://www.parallellabs.com/2009/11/12/algorithm-the-longest-plateau/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 22:30:15 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[算法学习]]></category>
		<category><![CDATA[Algorithm]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=59</guid>
		<description><![CDATA[Recently I met an interesting algorithm problem: Problem: Given an array, try to develop an efficient algorithm which can compute the length of the longest plateau. A plateau is a consecutive segment of an array with equal contents. For example, if x[] = {1, 2, 3, 4, 4, 4, 5, 5, 6}, then we have [...]
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=An+interesting+algorithm+problem%3A+the+longest+plateau&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F11%2F12%2Falgorithm-the-longest-plateau%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=An+interesting+algorithm+problem%3A+the+longest+plateau&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F11%2F12%2Falgorithm-the-longest-plateau%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>Recently I met an interesting algorithm problem:</p>
<h4>Problem:</h4>
<p>Given an array, try to develop an efficient algorithm which can compute the length of <em>the longest plateau</em>. A plateau is a consecutive segment of an array with equal contents. For example, if x[] = {1, 2, 3, 4, 4, 4, 5, 5, 6}, then we have six plateaus which are 1, 2, 3, 4-4-4, 5-5 and 6. And obviously the length of the longest plateaus is 3.</p>
<h4>Analysis:</h4>
<p>Well, a straightforward idea is try to firstly compute all the length of different plateaus from left to right and then select the longest length. The pseudo-code is like this:</p>
<pre class="brush: cpp; title: ; notranslate">
for each element in the array a[]
     if a[i] is equal to a[i-1]
          add 1 to the length for the current plateau
          check whether the current length is the longest one so far
     else
          reset length to 1 // plateau length is at least 1
</pre>
<p>Whether we need line 5&amp;6 depends on whether we need to store the length of every plateau. If we just want to calculate the longest length then we can keep the code and use the “length” as a temp variable which is only used inside the loop. On the other hand, if we need to keep track of the length of all plateaus, we need to use an array of “length[]” to store the needed information.</p>
<pre class="brush: cpp; title: ; notranslate">
/*
 * input: an array a[], the length of the array n
 * output: the length of the longest plateau
 */
int longestPlateau (int a[], int n)
{
	if (n == 0)
 		return 0;

	int length = 1;
	int longestLength = 1;

	for (int i = 1; i&lt;n; i++)
 	{
		if (a[i] == a[i-1])
 		{
 			length++;
			longestLength = max(longestLength, length);
 		}
 		else
 			length = 1;
	}
	return longestLength;
}
</pre>
<h4>Some more:</h4>
<p>What if the given array is <em>sorted</em> (in the increasing order) already?</p>
<p>Actually if the array is sorted, the algorithm can be much simpler:</p>
<p>assume the longest length now is L, then we just need to compare a[i] and a[i-L], if they are equal then all the elements between them are also equal (since this is a sorted array!), and we can add 1 to the current longest length. The code looks like this:</p>
<pre class="brush: cpp; title: ; notranslate">
/*
 * input: an sorted array a[] (increasing order), the length of the array n
 * output: the length of the longest plateau
 */
int longestPlateau (int a[], int n)
{
	if (n == 0)
 		return 0;

	int length = 1;
	for (int i = 1; i&lt;n; i++)
 	{
		if (a[i] == a[i-length])
 			length++;
	}
	return length;
}
</pre>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=An+interesting+algorithm+problem%3A+the+longest+plateau&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F11%2F12%2Falgorithm-the-longest-plateau%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=An+interesting+algorithm+problem%3A+the+longest+plateau&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F11%2F12%2Falgorithm-the-longest-plateau%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>10/25/2010 -- <a href="http://www.parallellabs.com/2010/10/25/practical-concurrent-queue-algorithm/" title="多线程队列的算法优化">多线程队列的算法优化</a></li><li>05/15/2010 -- <a href="http://www.parallellabs.com/2010/05/15/something-about-binary-numeral/" title="二进制的二三事">二进制的二三事</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2009/11/12/algorithm-the-longest-plateau/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Launched my master thesis finally</title>
		<link>http://www.parallellabs.com/2009/11/04/launched-my-master-thesis-finally/</link>
		<comments>http://www.parallellabs.com/2009/11/04/launched-my-master-thesis-finally/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 18:33:38 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[职业生涯]]></category>
		<category><![CDATA[Chalmers]]></category>
		<category><![CDATA[Thesis]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=42</guid>
		<description><![CDATA[Today I talked with my supervisor again and finally and officially launched my Master Thesis! The next coming 12 months I will focus on developing a methodology on analyzing the performance bottleneck of large-scale multi-threaded software. I am really excited in the challenging problem about how to find the performance bottleneck when we are moving to many-core [...]
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Launched+my+master+thesis+finally&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F11%2F04%2Flaunched-my-master-thesis-finally%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Launched+my+master+thesis+finally&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F11%2F04%2Flaunched-my-master-thesis-finally%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>Today I talked with my supervisor again and finally and officially launched my Master Thesis!</p>
<p>The next coming 12 months I will focus on developing a methodology on analyzing the performance bottleneck of large-scale multi-threaded software. I am really excited in the challenging problem about how to find the performance bottleneck when we are moving to many-core systems with hundreds of threads running concurrently. There will be a lot of fun and I believe I can learn a lot from it.</p>
<p>Another fun thing is, in the project plan written by my supervisor, the total budget is written as “81 000 KSEK” incorrectly, I hope Ericsson will not notice that mistake and if so, they have to pay a lot of  money to us since they have approved this project:)</p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Launched+my+master+thesis+finally&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F11%2F04%2Flaunched-my-master-thesis-finally%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Launched+my+master+thesis+finally&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F11%2F04%2Flaunched-my-master-thesis-finally%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">相关日志</h2><ul class="related_post"><li>10/03/2010 -- <a href="http://www.parallellabs.com/2010/10/03/future-multiprocessors/" title="多核的未来">多核的未来</a></li><li>05/04/2010 -- <a href="http://www.parallellabs.com/2010/05/04/swedish-programmer/" title="聊一聊瑞典的程序员">聊一聊瑞典的程序员</a></li><li>02/04/2010 -- <a href="http://www.parallellabs.com/2010/02/04/ericsson-interview-of-master-thesis-insweden/" title="瑞典Ericsson总部Master Thesis面试回忆录">瑞典Ericsson总部Master Thesis面试回忆录</a></li><li>12/09/2009 -- <a href="http://www.parallellabs.com/2009/12/09/h1n1-vaccination-in-sweden/" title="在瑞典打甲流疫苗">在瑞典打甲流疫苗</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2009/11/04/launched-my-master-thesis-finally/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Hello world!</title>
		<link>http://www.parallellabs.com/2009/09/25/hello-world/</link>
		<comments>http://www.parallellabs.com/2009/09/25/hello-world/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 15:15:38 +0000</pubDate>
		<dc:creator>Guancheng</dc:creator>
				<category><![CDATA[生活笔记]]></category>

		<guid isPermaLink="false">http://www.parallellabs.com/?p=1</guid>
		<description><![CDATA[Hello world! “This is Parallel Labs speaking!” 关于作者 冠诚, IBM中国研究院, 研究员 关注大规模分布式系统、并行计算。 任何与多核、并行、多线程有关的话题都可以找我聊聊:-) 我的邮箱是chenguancheng AT gmail.com Buzz 豆瓣 新浪微博 Twitter LinkedIn 向文章付费 请作者吃饭 最多留言日志03/06/2010 -- 为什么程序员需要关心顺序一致性（Sequential Consistency）而不是Cache一致性（Cache Coherence？）12/04/2010 -- 剖析为什么在多核多线程程序中要慎用volatile关键字？10/25/2010 -- 多线程队列的算法优化11/29/2010 -- Erlang User Conference 2010见闻（兼谈程序员职业生涯）04/09/2011 -- 《程序员的自我修养》中关于加锁不能保证线程安全的一个错误
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;"><div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div><div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"/></a><div style="text-align:left;line-height:23px;margin-right:226px"><div style="padding:5px 10px"><div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div><div style="clear:left">关注大规模分布式系统、并行计算。
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)
我的邮箱是chenguancheng AT gmail.com</div></div></div></div><div style="text-align:right;border-top:1px dotted #ccc;padding:10px;"><div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div><div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Hello+world%21&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F09%2F25%2Fhello-world%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Hello+world%21&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F09%2F25%2Fhello-world%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div></div></div>
	]]></description>
			<content:encoded><![CDATA[<p>Hello world!</p>
<p><strong><em>“This is Parallel Labs speaking!”</em></strong></p>
<div id="qu42" style="border:1px solid #ccc;font-size:14px;margin:27px auto;font-family:Verdana;">
<div style="padding:7px 10px;border-bottom:1px dotted #ccc"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;">关于作者</a></div>
<div style="height:129px;overflow:hidden"><a target="_blank" href="http://42qu.com/guancheng" style="color:#000;text-decoration:none;"><img src="http://p4.42qu.us/219/545/11809.jpg" style="float:right;padding:3px;width:219px;height:123px;margin:0;background:transparent;border:0;border-left:1px dotted #ccc"></a>
<div style="text-align:left;line-height:23px;margin-right:226px">
<div style="padding:5px 10px">
<div style="overflow:hidden;margin:2px 0;float:left;font-size: 14px;"><a target="_blank" href="http://42qu.com/guancheng" style="text-decoration:none;">冠诚</a>, IBM中国研究院, 研究员</div>
<div style="clear:left">关注大规模分布式系统、并行计算。<br />
任何与多核、并行、多线程有关的话题都可以找我聊聊:-)<br />
我的邮箱是chenguancheng AT gmail.com</div>
</div>
</div>
</div>
<div style="text-align:right;border-top:1px dotted #ccc;padding:10px;">
<div style="float:left;"><a target="_blank" href="http://guancheng.42qu.com/link/2427" style="margin-right:7px;text-decoration:none;">Buzz</a> <a target="_blank" href="http://guancheng.42qu.com/link/2428" style="margin-right:7px;text-decoration:none;">豆瓣</a> <a target="_blank" href="http://guancheng.42qu.com/link/2431" style="margin-right:7px;text-decoration:none;">新浪微博</a> <a target="_blank" href="http://guancheng.42qu.com/link/2429" style="margin-right:7px;text-decoration:none;">Twitter</a> <a target="_blank" href="http://guancheng.42qu.com/link/2430" style="margin-right:7px;text-decoration:none;">LinkedIn</a> </div>
<div><a target="_blank" href="http://42qu.com/guancheng/pay?title=Hello+world%21&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F09%2F25%2Fhello-world%2F&#038;rel=blog" style="text-decoration:none;margin-right:17px">向文章付费</a> <a href="http://42qu.com/guancheng/pay?title=Hello+world%21&#038;url=http%3A%2F%2Fwww.parallellabs.com%2F2009%2F09%2F25%2Fhello-world%2F&#038;cid=1&#038;rel=blog" style="text-decoration:none;margin-right:16px" target="_blank">请作者吃饭</a></div>
</div>
</div>
<h2  class="related_post_title">最多留言日志</h2><ul class="related_post"><li>03/06/2010 -- <a href="http://www.parallellabs.com/2010/03/06/why-should-programmer-care-about-sequential-consistency-rather-than-cache-coherence/" title="为什么程序员需要关心顺序一致性（Sequential Consistency）而不是Cache一致性（Cache Coherence？）">为什么程序员需要关心顺序一致性（Sequential Consistency）而不是Cache一致性（Cache Coherence？）</a></li><li>12/04/2010 -- <a href="http://www.parallellabs.com/2010/12/04/why-should-we-be-care-of-volatile-keyword-in-multithreaded-applications/" title="剖析为什么在多核多线程程序中要慎用volatile关键字？">剖析为什么在多核多线程程序中要慎用volatile关键字？</a></li><li>10/25/2010 -- <a href="http://www.parallellabs.com/2010/10/25/practical-concurrent-queue-algorithm/" title="多线程队列的算法优化">多线程队列的算法优化</a></li><li>11/29/2010 -- <a href="http://www.parallellabs.com/2010/11/29/erlang-user-conference-2010-and-some-thoughts-on-career-of-programmers/" title="Erlang User Conference 2010见闻（兼谈程序员职业生涯）">Erlang User Conference 2010见闻（兼谈程序员职业生涯）</a></li><li>04/09/2011 -- <a href="http://www.parallellabs.com/2011/04/09/pthread-mutex-lock-and-thread-safety/" title="《程序员的自我修养》中关于加锁不能保证线程安全的一个错误">《程序员的自我修养》中关于加锁不能保证线程安全的一个错误</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.parallellabs.com/2009/09/25/hello-world/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 54/287 queries in 0.786 seconds using disk: basic
Object Caching 3604/4011 objects using disk: basic

Served from: www.parallellabs.com @ 2012-02-23 19:36:03 -->
