最近在看多核编程。简单来说,由于现在电脑CPU一般都有两个核,4核与8核的CPU也逐渐走入了寻常百姓家,传统的单线程编程方式难以发挥多核CPU的强大功能,于是多核编程应运而生。按照我的理解,多核编程可以认为是对多线程编程做了一定程度的抽象,提供一些简单的API,使得用户不必花费太多精力来了解多线程的底层知识,从而提高编程效率。
OpenMp提供了对并行算法的高层的抽象描述,程序员通过在源代码中加入专用的pragma来指明自己的意图,由此编译器可以自动将程序进行并行化,并在必要之处加入同步互斥以及通信。当选择忽略这些pragma,或者编译器不支持OpenMp时,程序又可退化为通常的程序(一般为串行),代码仍然可以正常运作,只是不能利用多线程来加速程序执行。
OpenMp提供的这种对于并行描述的高层抽象降低了并行编程的难度和复杂度,这样程序员可以把更多的精力投入到并行算法本身,而非其具体实现细节。
对于新手而言,可能要问的第一个问题是:OpenMP与MPI有什么区别?
OpenMP和MPI是并行编程的两个手段,对比如下:
- OpenMP:线程级(并行粒度);共享存储;隐式(数据分配方式);可扩展性差;
- MPI:进程级;分布式存储;显式;可扩展性好。
这里提到了可扩展性,简单谈一谈。可扩展性好是说,计算节点越多,则效率越高,狭义上说就是运行所需要用的时间越少。扩展性差,则说明不适合在多机上运行。
OpenMP采用共享存储,意味着它只适应于SMP,DSM机器,不适合于集群。MPI虽适合于各种机器,但它的编程模型复杂:
- 需要分析及划分应用程序问题,并将问题映射到分布式进程集合;
- 需要解决通信延迟大和负载不平衡两个主要问题;
- 调试MPI程序麻烦;
- MPI程序可靠性差,一个进程出问题,整个程序将错误;
附:
- SMP(Symmetric multi-processing),共享总线与内存,单一操作系统映象。在软件上是可扩展的,而硬件上不能。
- DSM(distributed shared memory),SMP的扩展。物理上分布存储;单一内存地址空间;非一致内存访问;单一操作系统映象。
OpenMP在科学计算方面居于统治地位,对于多线程方面(包括多核)有很大的优势。
OpenMP+MPI的组合方式在集群方面有很成熟的案例。
OpenMP可以和MPI组合使用,OpenMP完成单机上的多核并行,MPI完成集群上机器间的通信。这是一种适合计算密集型的框架。
常采用mpi而不用openmp的原因是:openmp扩展性差,对机器要求高,要想运算的快点,机器就要很贵。
一般双核,用openmp。因为mpi用于分布式机器之间数据传输,单机内用mpi的时间开销大于OpenMP。
在一台机器中有很多CPU共享其中的内存条,叫共享内存并行机(如今天的双核CPU台式机),它适合OpenMP,而把这样的机器用专用高速网连接就形成了分布式内存并行机,它适合于MPI。此时,可以混合OpenMP,能提高一定的运行速度。