声明:
这篇文章主要想描述一下该怎样以一种安全和可伸缩性的方式使得程序并行化。在多核的今天,我们可能更加需要思考如何编写一个良好的并行程序。文中有相当的内容来自《Intel Threading Building Blocks》,虽说它针对 C++ 讲解,但原理通用,在跟语言,平台有关联的时候,楼主会使用 .NET 阐述。
每个软件开发人员都不得不面对并行编程。以前以及现在,我们在完成任务时,首先会考虑选择最佳算法,实现语言等。但现在我们必须首先考虑任务的内在并行性。而这反过来又会影响我们对算法和实现的抉择。如果试着在最后考虑并行,还不如不要思考并行。程序也不能很好的工作。
现实中,我们每天都在并行思考。举两个例子:
长时间等待。比如生病了,要去医院看医生。挂完号到门诊前时,发现排起了一条长龙,需要很长时间才能就诊。这时,我不会傻站着干等。在病情无大碍的情况下,我会一边做一些耗时更短的事情,一边等待就诊。比如打开 MP3 听听音乐,跟周围的病友们聊天,诸如此类。
大量重复性工作。当手头有个繁重的重复性任务,而周围又有多位相熟的朋友很悠闲,那我肯定希望这些人来帮忙以便更快的完成任务。比如搬家,网络管理员要在每台机器上安装同一个软件等。
我们对并行并不陌生。实际上,并行是相当自然的思维方式。只是似乎开发人员并不常用这种方式。一旦关注并且使用并行编程,那我们便会思考并行。那时我们将会首先思考整个项目的并行性,然后才考虑如何进行编码。
应该怎样来实现程序并行呢?本文将讲述一种重要的思维方式:并行分解。
应用程序有多种并行方式,下面将分别描述。
数据并行
如图1所示,它是一种很典型的数据并行示例:拥有大量的数据,并且这些数据都采取同一种操作来转换每一块数据。
图1
图1表示,把数据集中的每一个英文小写字母均转换成相对应的英文大写字母。这个很简单的示例向我们展示了要操作的数据集和同时应用于每个元素的转换操作。那些为超级计算机编码的开发人员最喜欢碰到这种问题,因为要使其并行化实在简单。