C++多核高级编程 - 02 并行程序设计中系统的任务及挑战

来源:互联网 发布:汽车维修自学软件 编辑:程序博客网 时间:2024/06/08 00:39

一,并行的概念

如果两个事件在相同的时间间隔内发生,则我们称他们是并发的。两个或多个任务在相同时间间隔内执行,则我们称他们是并行的。如果两个任务在同一秒并行,但其实两个任务可能在同一秒的不同部分执行。例如第一任务在第一个十分之一秒运行第二个任务则在第二个十分之一秒运行,之后又是第一个任务.... 交替运行。但由于时间较短给人的感觉还是两个任务在同时进行。时间的间隔可以放大,也可以缩小。无论任务间是不是同时进行,我们都可以认为他们是并行的。


二,并行程序设计的挑战

软件开发本身就是一种挑战。在开发过程中是否使用多核编程,如何选择多核编程都是对开发人员的一种挑战。

1,挑战 1   -   软件分解,任务分解

多线程或多处理的需要多数情况是在分解任务的过程中发现的。分解就是对于一个问题或解决方案划分成基本部分的过程。

在分解的过程中找出正确的多线程模型,对于整个软件非常重要。

一个简单的实例:

问题:我们要在规定的时间内粉刷房子内所有的房间。

问题分解

1,  油漆的颜色

2,  刷油漆的工具

3,  刷房间的先后顺序

4,  刷油漆的时间

解决方案

1,  颜色选择与家具搭配的颜色

2,  工具使用自动刷漆机, 一台或多台

3,  可以选择同时刷多个房间,也可以选择顺序一个一个刷

4,  工作时间 9:00  -   18:00

从解决方案中可以看出如果采用多台刷漆机,同时刷多个房间是一种并发的解决方法。

在任务分解的过程中可以发现多个任务之间存在着并行的可能性。通过分解方案选择

正确的模型对后续的开发有着非常重要的影响。 

2,挑战 2   -   任务间通信

如果有两个任务A和B,其中一个任务依赖于另一个任务的信息,那么2个任务间需要有一种通信的渠道。如果任务间共享某些资源,而且该资源在某一时刻只支持一个任务对它访问,那么任务间需要提供对于资源访问的信息。如果任务是独立的操作系统进程那么任务间通信被称为进程间通信 IPC(Interprocess Communication)。

POSIX规范提供6种用于完成进程间通信的基本机制。

-  具有加锁和解锁能力的文件

-  管道(无名管道,命名管道)

-  共享内存

-  POSIX消息队列

-  Socket

-  信号量

此表包含了各种通信方式的一个简单概述

POSIX进程间通信概   述命令行参 数
可以在调用exec或spawn函数时传递给子进程
环境变量/文件描述符
子进程可以收到父进程的环境数据和文件描述符的副本,父进程可以设置变量,子进程可读入变量值;父进程可以打开文件并前向移动文件指针位置,子进程可以同样的偏移量来访问
具有加锁功能的文件
用于在2个进程间传输数据;加锁功能用于对2个进程对文件的访问进行同步
管道
在进程间形成一种通信信道的形式;通常使用文件读写功能进行访问同步。
共享内存
被多个进程访问,位于他们地址空间以外的内存块
消息队列
可以在进程间共享的消息列表
信号量
用于同步线程或进程对资源的同步访问的变量
Socket
进程间利用端口和IP地址的双向通信链路

每种IPC机制都有各自的优势和缺陷,开发人员必须完善的管理IPC机制防止对软件造成伤害。

利用IPC机制的挑战:

-  必须正确的创建IPC,否则应用程序会失败

-  它们的使用要求有适当的用户权限

-  它们的使用要求有适当的文件权限

-  某些情况下,它们有着严格的命名约定

-  它们不是对象有好的 (它们使用底层的字符表示)

-  它们必须被恰当的释放,否则会造成资源的泄漏

-  在它们的使用中,源进程和目标进程不容易识别

-  软件的初始配置可能很棘手,因为IPC并不是兼容所有的环境

-  接收和发送机制对数据的大小是否正确非常敏感

-  错误的数据类型或大小可能导致程序锁住和失败

-  清空机制(Flushing) 并不总是非常直观

-  部分机制在使用用户实用工具时并不可见

-  依据类型,一个进程所能访问的IPC数量可能会受限


3,挑战 3   -   多个任务或Agent 对数据或资源的并发访问

当并发执行的指令,任务,应用程序被要求共享数据,设备或其他资源时3种常见的问题会发生。

    -    数据竞争
    -    死锁
    -    无限延期


4,挑战 4   -   识别并发执行的任务之间的关系

数据竞争,死锁,和无限延迟的同步问题,有时候会被建立线程或进程之间的正确执行关系的挑战所放大。
基本的同步关系:

同步关系描        述Start to Start一个任务不能启动,除非另一个任务启动。Finish to Start一个任务不能结束,除非另一个任务启动。Start to Finish一个任务不能启动,除非另一个任务结束。Finish to Finish一个任务不能结束,除非另一个任务结束。

5,挑战 5   -   需要多少个进程或线程

线程间的通信或处理器的同步都有一定的成本。任务间同步的复杂性或任务间通信的数量可能需要大量的运算,会使得任务本身的工作效率大大的降低。此时便存在一个临界点,管理多个处理器的开销会超过采用并行处理在速度优势方面带来的收益。“处理器多多益善” 并不是一个恰当的说法。在处理实际问题的过程中,采用什么样的模型,有多少个任务并行,都是很重要的。而且在解决程序失败处理的过程中,随着并行任务的增加,其难度成指数级增加。


6,挑战 6   -   寻找可靠的,可重现的调试和测试

当测试顺序程序时,可以利用设置断点,逐步跟踪程序逻辑。如果以相同的数据启动,可以确保程序处于相对稳定的状态。但在处于多进程或线程的环境中,情况则完全不同。由于操作系统的调度策略,计算机的动态负载,处理器的时间片,进程线程的优先级,通信的延迟,执行的延迟和并行环境中的随机因素,使得我们很难重现并行或并发任务的上下文。


7,挑战 7   -   与拥有多进程组件的设计的相关人员进行沟通

在文档的编制中精确的捕捉并行设计也是对多核开发的一大挑战。文档中必须要描述出任务,对象,进程,线程之间的同步和通信。设计人员必须和开发人员有效的沟通,开发人员必须和设备管理人员有效的沟通。



原创粉丝点击