Electronic Joint Business

Solution for E-Business

并行程序中的同步与通讯

在任何程序中,总会有些执行阶段要等待操作系统或者其他进程完成 I/O 操作或者同步操作。这时候,程序就无法处理其它工作,因为实际上是操作系统或者其它进程占用了宝贵的 CPU 时间。这就是滥用文件读/写操作的程序会如此之慢的原因。1 这时候进程不得不等待操作系统服务例程将 CPU 从其他进程那里释放出来。这种等待也被称为进程处于阻塞状态。诸如 EDA 这类串行计算,整个算法作为单个任务被执行,如果该进程在等待任一种阻塞操作,整个算法就会完全停顿。在处于阻塞状态的这段时间里,另一个进程占用了 CPU 的所有权,所以算法根本没办法进行。 并行程序提供了一种手段,能在同一计算中调用另一个进程以提高 CPU 利用率,当一个进程被阻塞的时候(如等待 I/O 操作或者同步操作),另一个进程则继续处理共同工作的其它部分。这种情况在单 CPU 或者多 CPU 机器上皆可发生。 反之,对于串行程序(即非并行算法)来说,而无论有多少可用的 CPU ,在任何情况下都只能用到单个 CPU。除非有编译器将源程序从串行转成并行,不过能实现这一目标的实属特例。 因此如果想同时利用多个 CPU ,编码时要手工运用某种并行技术。(在源代码中采用特殊指令,如 OpenMP)。 并行程序能将工作划分为较小的部分,因此多个进程可以一起工作并互相协作以便能在更短的时间内计算出同样的结果。这时,在等待 I/O 设备完成操作的同时,并行程序能可以继续处理另一部分工作。此外,并行程序还可以同时使用系统所有可用的 CPU。 不幸的是,将工作划分到不同进程以便分别运行,需要对串行程序进行改写,甚至需要从头设计并行版本。这不是简单的事情,因为需要考虑多个方面,如:选择进程间通信机制(这也要消耗了一些额外的执行时间)、选择进程间同步机制、以及确认串行程序中能候选为并行版本的部分。最后这点非常重要,因为多数串行程序中总有些部分必须按次序执行的,而不能并行执行。最简单的例子就是,在所有工作进程结束并将结果都被归拢合并时,这种合并工作通常都由独一个进程来完成,其它的进程这时只是在等待,别无它事。 进程与线程 在传统操作系统中,“进程”这一概念被用来描述可执行程序的实例。一个进程只能包含一个正在运行的程序,只有单一的执行流,也就是说,任何时候,只能执行程序中的一条指令。这意味着在传统操作系统中,进程被表示为单一的执行单元,在任何特定时间只能在单个 CPU 上被执行。 此外,在传统操作系统中,分配给进程的存储空间被定义为私有:其它进程不允许访问另一个进程的内存空间。在这些系统中进程间没有共享内存可用,因此唯一的可用于编程的进程间通信机制是利用消息传递原语,另一种可能的机制则是使用磁盘文件,但这非常低效。只有操作系统可以利用共享变量用于其内部组件之间的通信。 近年来,一些操作系统(如 UNIX)包含了特定系统调用,可以从用户地址空间中分配及释放共享内存,使得进程之间能使用共享变量(比如共享缓冲区)来作为进程间通信机制。但是,如今这种机制在 UNIX 中被滥用,人们转而倾向更高效且用户友好的机制。 操作系统发展的下一站是多线程操作系统。这种“线程”的新构想允许一个程序可以同时在相同的内存空间中运行多个内部函数。作为结果,一个进程现在可以有多个执行流,所以现在同一程序可以在不同的 CPU 上同时执行多个指令行。多线程操作系统提供专用系统调用,来创建、管理并执行线程,同时还包括创建和管理进程。在多线程操作系统中,对其他进程来说,每个进程的内存地址空间仍然是私有的,但是一个进程可以有多个执行线程,而一个执行线程只能属于一个进程,进程内的执行线程可以使用该进程的整个存储空间,而同一进程中的两个线程可在该进程的内存空间内使用全局共享变量进行通信。但是,不同进程中的线程不能共享任何内存空间,消息传递仍是它们唯一的沟通机制。 现在,所有的商业及通用操作系统都是多线程的。当我们写一个串行(即非并行)程序时,编译器会创建一个可执行文件,并以传统的方式执行,每个进程只有一个线程或执行单元。但是,我们可以在编程语言之下,利用操作系统所提供的特定系统调用,编译出能创建多个线程的程序。不幸的是,没一种可以适用于所有操作系统的标准系统接口来进行线程管理。就是 UNIX 中也有许多不同的且不兼容的接口。近年来 POSIX 标准的 pthread 的接口库似乎是最广泛使用的,你甚至可以在互联网上找到针对 Windows 操作系统的实现。 […]

, , , , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.