华南农业大学 《并行计算》课程复习纲要
答:并行:单机多核,问题并行编程;分布:多机网络连接,对外以整体提供服务
答:并发:支持同时存在;并行:支持同时执行。并行是并发的一个子集。
并发是指一个处理器同时处理多个任务。 并行是指多个处理器或者是多核的处理器同时处理多个不同的任务。 并发是逻辑上的同时发生,而并行是物理上的同时发生。
答:进程是操作系统的资源分配的基本单位,线程是处理器任务调度的基本单位。
答:消息传递和分布式内存。
答:并行计算的核心内容是指计算机能够以任何顺序来执行的独立计算
答: 【1】寻找并发性 【2】设置算法结构支持结构实现机制
任务并行和数据并行的观点:
答:分析,设计实现,测试正确性,性能调优
答:指令核数据,单流,多流。
SISD: (Uint改正:Unit) SIMD: GPUs 都采用SIMD并行。
MIMD:
答:共享内存:每个内存区域都能被每个处理器访问的到。分布式内存是内存独立,但是大家能通过网络访问。
共享内存: 一组自治的处理器通过互联网络与内存系统相连接,每个处理器能访问每个内存区域,每个处理器都可以访问每个存储单元,处理器通过访问共享的数据结构来隐式通信
分布式内存:
答:,
寻找并发性设计空间,如果从分解的角度去看问题的话:任务分解和数据分解,还有数据流分解。如果从依赖性分析的话:任务的分组,任务的排序,数据的共享。
答:任务分解:计算被分解为一组独立的任务,多个线程可以用任意顺序执行这些任务。
例子:如果两个园丁到达一个客户家,一个修剪草坪,另一个铲除杂草。修剪草坪和铲除杂草是两个被分开的功能。
答:数据分解:应用程序需要处理一个大型数据集,并且可以对数据集中的每个元素进行独立计算。
例子:如果园丁应用数据分解来分解他们的任务,他们两个会同时修剪一半的草坪,然后两个人分别铲除一半的杂草
任务分解:识别出多个可以并发执行的任务; 数据分解:识别出每个任务所需要的局部数据
答:把问题分解为一个能够并发执行的任务集合。
一块草坪,需要完成修剪和除杂草的任务,现在两个园丁分配到不同的任务去完成。当然这个过程需要协调的,因为两个人不可能说同时处理一块地方的。
答:几何分解模式基于正在解决问题的数据结构的并行化。在几何分解中,每个线程负责操作数据块
几何分解实际上就是数据的并行化,我们的园丁分到这块草坪的两半,每人负责一半,然后都同时完成:除草和修剪的任务。
答:流水线模式的意思类似于一条工厂的产品装配线。这种寻找并发的方式使计算被分割成一系列阶段,每个线程在不同的阶段同时工作。
生产者消费者的实现就是典型的流水线模式。一块草坪,我们把需要完成的任务进行步骤的分解,比如:拿出除草剂,插电,推动,每一步都由不同的园丁来完成。工厂的流水线就是一个最好的理解例子。
答:定义任务,表示事件流,强制执行事件的顺序,避免死锁,调度和处理器分配,事件的高效通信
当一个人完成了工作,就通知他人开始他的任务,这样可以做到很好的协作。
在SPMD程序中,所有UE并行执行同一个程序(单程序),但每个UE都拥有自己的私有数据集(多数据)
答:主进程为从进程建立一个工作池和一个任务包。所有从进程并发执行,每个从进程迭代的从任务包中移除一个任务并处理它,指导所有任务都处理完毕或到达某些终止条件为止
核心思想是基于分而治之的思想,将一个原始任务分解为若干个语义等同的子任务,并由专门的工作者线程来并行执行这些任务,原始任务的结果是通过整合各个子任务的处理结果形成。
比如Master:RW,那么他的Slave是R和W,也就是我们常说的读写分离。
这个可以用线程池的思想去理解。
百度一下:Fork/Join 模式即可理解。
一个主UE里面Fork出多个子的UE,这些子UE并行完成任务,的一部分,等待这一步的全部子UE完成了这些任务之后,我们再继续分支。
答:共享队列:使用“线程安全”实现,即使并发执行的多个UE共同使用时,该实现也能保证正确。
如果使用共享数据的话,需要考虑:确保需要这种模式,定义抽象数据类型,实现一种合理的并发控制协议,一次执行一个操作,非干扰的操作集合,读访问者/写访问者,缩减临界区大小,嵌套锁,特定应用的语义释放,回顾其他考虑事项,任务调度
答:一维或多维数组,被划分为多个子数组,并在进程或线程间进行分配
消息传递,集合通信,其他通信构造。 消息是最基本的通信元素,包含信息标识。 广播:发送单条消息给所有UE 栅栏:程序中的同步点,所有UE都必须到达该点,然后才能继续向后执行 归约:获得一个对象集合,每个对象映射到一个UE,操作把它们组合为位于一个UE的单个对象,或组合它们并将结果广播到每个UE上
三个实验例子:生命游戏,PAI计算,日志挖掘。
生命游戏的分解:如果从任务分解的角度去想的话,我们的对于每一个格子都需要判断多个条件,那么这些条件就是我们的任务步骤,也是我们可以对其进行分解的地方。如果从数据分解的角度去思考的话,我们把一个棋盘分为多块,那么我们就完成了数据分解。
计算π的分解: 首先,我们对于算出:每个进行步骤分解,这样就是任务分解,单很明显这个不大适合进行任务分解,因为每一个任务都非常小。我们进行数据分解,线程1计算,线程2计算 如此类推,同时进行。
日志挖掘:文件读取的数据并行和处理数据时的任务并行。
关于线程池:
在处理迭代生命游戏的时候,由于我们采用派生聚合的模式去完成任务,因此,我们在每迭代一次的时候同步一次再发起一次并行迭代,因此需要重复创建,销毁线程,需要消耗大量的资源,因此,更适合用线程池。
对于计算问题,我们可以指定多个线程同时计算多个任务,只需要最后一次合并,无需多次创建消耗资源,因此,我们使用线程池效率不见得比直接手动使用多线程效率高。
但在实际开发当中,为了安全考虑,我们是不应该直接手动创建多线程去处理问题的。(原因参见阿里的编程规范)
xxxxxxxxxx
global Var
lock = new Lock()
Thread:
while(True):
if lock.is_alive == False:
lock.Lock()
#do something fo Var
lock.unLock()
else:
sleep(random)
continue
T1 = Thread().start()
T2 = Thread().start()
我们需要考虑是读取数据部分和处理数据部分。比如说,我们可以根据等长数据进行划分,或者根据日期数据进行划分。
数据分块存储,分块读取。
(分别对应生产者消费者实验)。