好文档 - 专业文书写作范文服务资料分享网站

并行程序设计心得

天下 分享 时间: 加入收藏 我要投稿 点赞

1、MPI实质上是多进程,并且不支持多线程;

2、初始化时在每个处理机(结点)上创建一个进程,执行期间进程数不能动态改变; 3、MPI其实就是一种在各进程之间进行通讯的标准; 4、并行程序设计最常用的两种方法:

1、共享变量方法——利用共享存储器中共享变量来实现处理机间的通信,它主要用在共享存储结构中(OpenMP)

2、消息传递方法——主要特点是不同处理机间必须通过网络传送消息来相互通信,并达到任务间需要的同步操作,它主要应用于分布式存储结构中(MPI) 5、一个基本的MPI 程序的流程图

对于多核程序设计的一点总结

多核下的多线程程序设计与传统的单核下的多线程程序设计有着一定的差别,在单CPU下,是多个线程在同一个CPU上并发地执行,而在多核下,则是由多个线程在多个核上并行地执行。

但是,目前的程序设计中对于多核的利用并没有达到预期的效果。因此,为了能够在多核的环境下设计出更适合多核系统的程序,则是一个挑战。 要做到这一点,就必须将应用程序看做是众多相互依赖的任务的集合,将应用程序划分成多个独立的任务,并确定这些任务之间的相互依赖关系,这就称为分解(decomposition)。如下如示:

分解方式 设计 说明

任务分解 不同的程序行为采用不同的线程实现 常用于GUI应用程序

数据分解 多个线程对不同的数据块执行相同的操作 常用于音频、图像处理和科学计算应用程序

数据流分解 一个线程的输出作为另一个线程的输入 应注意尽量避免延迟

任务分解:对应用程序根据其执行的功能进行分解的过程称为任务分解

(task decomposition)。根据这种方法,就能够对众多的独立任务进行分类。如果其中两个任务能够同时运行,那么开发人员就应该对其进行调度,形成二者之间的并行执行。

数据分解:数据分解也称为数据级并行(data-level parallelism)。是将应用程序根据各任务所处理的数据而非按任务来进行分解的方法,即以数据为中心。一般而言,能够按照数据分

解方式进行分解的应用程序都包含多个线程,这些线程分别对不同的数据对象执行相同的操作。

数据流分解:在很多情况下,当对一个问题进行分解时,关键问题不在于采用一些什么任务来完成这个工作,而在于数据在这些任务之间是如何流动的。这个时候就要采用数据流分解方式,如典型的生产者/消费者问题。

对于任务分解,有两个需要注意的地方:

1. 划分的对象是计算,将计算划分为不同的任务

2. 划分后,研究不同任务所需的数据,如果这些数据不相交,则证明划分是成功的,如果数据有相当程序的相交,意味着要重新进行数据划分和功能划分。

如在一个气候模型中,需要考虑到地表模型、水文模型与海洋模型等多种情况,那么就应该将这几种模型划分成不同的任务,再分别进行并行地运算。

对于数据分解,划分的对象是数据,可以是算法的输入数据、中间处理数据和输出数据。在划分时应该考虑到数据上的相应操作。

最简单的情况下,比如对1000万个数进行相加,可以对其进行数据上的分解,用多个线程来分别计算不同批次的数据。然后再将计算的中间数据加到一起成为最终的结果。

1. 线程过多

线程并不是越多越好,对于某个程序,如果线程过多反而会严重地降低程序的性能。这种影响主要在于:

将给定的工作量划分给过多的线程会造成每个线程的工作量过少,因此可能导致线程启动和终止的开销比程序实际工作的时间还要多。 同时,太多并发线程的存在将导致共享有限硬件资源的开销增大。如保存和恢复寄存器状态的开销、保存和恢复线程cache状态的开销、废除虚存的开销、线程聚集在一起等待获取某个锁。

怎样解决这个问题: 限制可运行线程的个数

将计算线程与I/O线程分离开

使用已有的技术,如OpenMP,线程池等

2. 数据竞争、死锁

死锁,想必大家都很熟悉。这里谈谈一些简单的避免死锁的规则: 加锁的顺序是关键,使用嵌套的锁时必须保证以相同的顺序获取锁 防止发生饥饿:即这个代码的执行是否一定会结束。 不要重复请求同一个锁

越复杂的加锁方案越有可能造成死锁—设计应力求简单

3. 竞争激烈的锁

即使是正确使用锁来避免数据竞争,但如果各线程对锁的竞争很激烈,那么也会引发性能问题。即很多个线程来竞争同一个锁。在这个情况下,可以考虑将资源划分成若干个部分,然后用彼此独立的锁分别保护各个部分。即合理地安排加锁粒度的问题。在早期的Linux内核

中就使用了大内核锁,现在已经把锁给细划到不同的子系统中去了。

如果一个数据结构被频繁读取但不被频繁写入,就可以使用读写锁来解决竞争。

4. 线程安全函数

已有的一些函数并不是线程安全的,具体的线程安全函数可以参考APUE2上面的线程一章。

5. 存储效率问题 目前,处理器的速度已经比存储器快很多,一个处理器从内存中读或写一个值的时间内可以完成上百次的操作。因此,现在的程序往往受限于存储器的瓶颈。

首先,可以通过节省带宽,可以减少与存储器的数据交换数量,要节省带宽就要将数据压缩得更加紧凑。

其次是cache的利用。可以减少数据在不同CPU的cache间的移动。CPU亲合力(CPU Affinity)就是指在Linux系统中能够将一个或多个进程绑定到一个或多个处理器上运行。一个进程的CPU亲合力掩码决定了该进程将在哪个或哪几个CPU上运行,在一个多处理器系统中,设置CPU亲合力的掩码可能会获得更好的性能。

在下面的例子中讲解了如何利用将某个进程绑定以某个CPU上运行的实例。

http://linux.chinaunix.net/bbs/viewthread.php?tid=904906&extra=page=1&filter=digest

目前双核心的 CPU 当道,AMD 的 Athlon64x2、Intel 的 Pentium-D、Core Duo,以及即将上市的 Core 2 Duo,俨然将成为下一代电脑的主流(尤其是超低价的 Pentium D,绝对是现阶段 C/P 值极高的双核心 CPU)。但是双核心有什麼用呢?

对於一般单一执行绪(single thread)的程式,多核心的处理器并没有办法提升它的处理效能;不过对於多执行绪(multi thread)的程式,就可以透过不同的核心同时计算,来达到加速的目的了!简单的例子,以单执行绪的程式来说,一件事做一次要十秒的话,要做十次,都丢给同一颗核心做的话,自然就是 10 秒 * 10 次,也就是 100 秒了;但是以多执行绪的程式来说,它可以把这一件事,分给两颗核心各自做,每颗核心各做 5 次,所以所需要的时间就只需要 50 秒!

并行程序设计心得

1、MPI实质上是多进程,并且不支持多线程;2、初始化时在每个处理机(结点)上创建一个进程,执行期间进程数不能动态改变;3、MPI其实就是一种在各进程之间进行通讯的标准;4、并行程序设计最常用的两种方法:1、共享变量方法——利用共享存储器中共享变量来实现处理机间的通信,它主要用在共享存储结构中(OpenMP)2、消息传递方法——
推荐度:
点击下载文档文档为doc格式
7hfsh9rthn9nplx1m22b
领取福利

微信扫码领取福利

微信扫码分享