OpenMP与Cilk比较

比较一下Cilk Plus和OpenMP,以便我们在多线程编程时作出最恰当的选择。 

一般我们把并行方式划分为两种:数据并行和任务并行。我们来看一下Cilk Plus和OpenMP在这两种并行方式下有什么不同的特点。
 
首先,在数据并行方面,使用OpenMP的相当容易上手,而且并行的效率也颇高,这也是OpenMP在HPC领域得到广泛应用的原因。OpenMP提供三种工作量的划分与调度:静态方式、动态方式和Guided方式。我们开发人员可以根据循环迭代的工作量分布情况选择最合适的调度方式。如果工作量的分布比较固定而且均匀(每个迭代花费的时间基本相同),我们可以选择静态方式。如果工作量分布是不确定的,或者工作量非常不均衡,就需要选择另外两种调度方式了。否则,将导致多线程负载不均衡。相对来说,静态方式的开销非常小。另外两种方式在底层实现中需要维护一个队列,并提供入队、出队和派发的功能,以便将总的工作量分块并入队,然后派发给空闲线程。因此,这两种方式的开销要大于静态方式的开销。


Cilk Plus在数据并行时对程序源代码的改动非常小,只需要将for改写成clik_for即可,Cilk Plus的底层运行库能高效地完成工作量的划分、调度,不需要我们开发人员的干预。空闲线程通过Cilk Plus的工作密取(Work-Stealing)从其他线程获取一部分工作量,同时运行库能将密取的次数控制在最低水平,减少密取带来的性能开销。如下图所示,线程A首先开始执行这个循环,它会将工作量不断按照循环控制变量x来平均分块,直到每块的大小足够小为止,这样就得到下面这个类似二叉树的图,每一个右侧分支都表示一部分可以被密取的工作。因此在循环迭代的工作量分布均匀的情况下,线程B只需要密取一次就可以了。而在分布不均匀的情况下,线程B从顶部开始密取,这是因为越接近顶部的密取能获得的工作量越多,接近底部的密取能获得的工作量则相对较少。这种自顶向下的策略能有效地减少密取次数。可以想象,自顶向下在性能上要优于自底向上。


在任务并行方面,Cilk Plus提供cilk_spawn和cilk_sync这两个关键字,我们可以很灵活地将基于任务的串行代码并行化,比如递归函数。一般来说,一次cilk_spawn的开销仅相当于一次函数调用开销的3至5倍,一次密取的开销则比较高。因此,cilk_spawn不会给程序带来很大的开销。经过精心设计,我们可以将串行代码转化为高效的Cilk Plus并行代码,使密取次数尽可能的少,获得相当不错的性能加速比。


OpenMP 3.0标准中增加了对任务并行的支持,使用#pragma omp task来创建任务。语法也比较简单,但是对代码的可读性略有影响,不如Cilk Plus代码直观易读。


另外,Cilk Plus与OpenMP还有一些不同,包括:
l  Cilk Plus还提供了一些向量化方面的支持,包括Elemental Function、Array Notation,开发人员可以使用这些功能,将向量操作以自然方式来书写,极大的增强程序的可读性,编译器也更容易将向量操作向量化。

l  主流编译器均已支持OpenMP,VS 2010还不支持OpenMP 3.0。目前仅有Intel编译器支持Cilk Plus。英特尔已将Cilk Plus开源,在GCC 4.7的分支中已支持Cilk Plus。



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值