精华内容
下载资源
问答
  • 并行网关

    千次阅读 2020-06-24 20:52:22
    并行网关在实际运用中的重要性,本文通过一个做饭的例子形象说明,这也是工作流引擎、工作流系统中比较重要的环节。

    1、并行网关

    假设现在我们想在旁边放一份沙拉。无论如何,如果你想要沙拉,你可以像我们在图1.1中所做的那样建模。

    图1.1:准备沙拉和主菜。

    在这里,我们介绍了另一个符号:(文本)注释;这是一个您可以与任何流对象(在本例中是任务)关联的工件。你可以输入任何文本;在我们的示例中,我们输入了执行相关任务的平均时间。任务时间的总和等于流程的运行时间,意大利面的运行时间为48分钟,牛排的运行时间为43分钟。祝贺您:您已经基于关键数据分析了您的第一个流程!

    不过,这意味着要等23分钟甚至28分钟才能开始吃东西。难以忍受的!你真的很饿,但你能做什么?也许你不会先准备沙拉,然后再做意大利面或牛排,但你会同时做这两件事——同时做。适当的符号是并行网关,或简称和网关,如图1.2所示。

    图1.2:同时准备沙拉和主菜。

    将任务画成并行并不意味着必须同时处理。与图1.1所示的示例相反,在开始其他任务之前也不是必须准备沙拉。然而,并行准备确实使我们的总时间减少了10分钟。使任务尽可能并行化是经典的流程优化。

    如示例所示,该进程不仅是并行的(它使用了and split),而且路径稍后还会同步(an and merge)。原因很容易理解:你只能在主菜和配菜都准备好之后才能开始吃。

    令牌的概念如何应用于此流程的实例?令牌在开始事件时产生,它运行choose recipe任务,然后插入and split。每个路径都从网关中出现一个令牌。这意味着在本例中有两个令牌:第一个令牌进入xor分割,其传出路径取决于所选的菜谱。

    假设我们想做意大利面。令牌进入任务并停留15分钟。同时,第二个令牌进入第二个,准备沙拉任务,它只停留10分钟。10分钟后,它移到合并处。传入路径的数量决定了网关正在等待的相关令牌的数量,因此在这里,它等待相同流程实例的两个令牌。

    在我们的场景中,第二个令牌在10分钟后到达and merge,而第一个令牌在cook pasta中总共停留了15分钟。这意味着and合并将等待到第一个令牌到达—额外的5分钟。此时,令牌愉快地合并为单个令牌,该令牌将继续沿着传出路径运行。

    这听起来是不是太抽象或太专业了?它不是,这和你自己的做法是一样的:沙拉准备好了,但意大利面还没有,所以你等着。当意大利面最终做好时,你就可以吃了。

    那么,为什么使用这个看似复杂的符号概念呢?例如,每年信用机构创建9000万个流程实例,这些并不是按照严格的顺序执行的,他们有重叠,为了每天正确地定义和执行这种复杂的流程及其各种并行操作、分支、合并和同步,令牌方法就对对概念设计和实现是非常有帮助,而且非常必要。我们希望到目前为止,流程实例与令牌并不完全相同:许多令牌可以在单个流程实例的范围内运行。

    用下面的问题检查你的理解:

    问题:图1.3显示了相同的过程,但是由于缺少空间,省略了and merge,并且从prepare沙拉任务的路径直接通向xor合并。如果我们实例化这个过程,并决定支持意大利面,会发生什么?

    图1.3:在这个过程中发生了什么?

    答:在and分割时生成令牌,然后像往常一样进行克隆。当我们完成准备沙拉,令牌通过xor合并和吃饭执行,五分钟后,意大利面也做好了,它的令牌通过xor合并,并再次执行!这不是我们想要的行为。

    问题:图1.4显示了一个只包含两个任务的流程。实例化后,流程实例存活多久?

    图1.4:流程实例存在多长时间?

    答:它存在45天,这与进程的运行时间相对应。即使在and split中生成的令牌在30天后通过task 1,然后被上端事件使用,第二个令牌仍然在task 2中驻留15天,流程实例继续存在,直到低端事件使用第二个令牌为止。

    注意:只要流程中有一个令牌存在,流程实例就存在!在使用所有生成的令牌之前,该实例无法完成。

     


    本文会持续更新,欢迎关注,技术支持:盘古BPM 

    展开全文
  • 并行计算及并行算法

    万次阅读 多人点赞 2018-06-13 22:27:31
    一、并行计算  简单地说,并行计算就是在并行计算机上所做的计算。从普通意义上讲,它和常说的高性能计算、超级计算等是同义词。并行计算的初衷是为了努力仿真自然世界中一个序列中含有众多同时发生的、复杂且相关...

    一、并行计算

      简单地说,并行计算就是在并行计算机上所做的计算。从普通意义上讲,它和常说的高性能计算超级计算等是同义词。并行计算的初衷是为了努力仿真自然世界中一个序列中含有众多同时发生的、复杂且相关事件的事务状态。
      为了利用并行计算求解一个计算问题,通常基于以下考虑:1.将计算任务分解成多个子任务,有助于同时解决;2.在同一时间,由不同的执行部件可同时执行多个子任务;3.多计算资源下解决问题的耗时要少于单个计算资源下的耗时。
      并行计算可分为:1.计算密集型:如大型科学工程计算与数值模拟等;2.数据密集型:如数字图书馆、数据仓库、数据挖掘和计算可视化等;3.网络密集型:如协同计算和远程诊断等。

    二、并行计算机体系结构

    1.并行计算机结构模型

    (1)结构类型

    • SISD:单指令流单数据流计算机(冯诺依曼机)
    • SIMD:单指令流多数据流计算机
    • MISD:多指令流单数据流计算机
    • MIMD:多指令流多数据流计算机

    (2)几种MIMD

    • PVP并行向量处理机:多VP(向量处理器)通过交叉开关和多个SM(共享内存)相连
    • SMP对称多处理机:多P/C(商品微处理器)通过交叉开关/总线和多个SM(共享内存)相连
    • MPP大规模并行处理机:处理节点有商品微处理器+LM(分布式本地内存),节点间通过高带宽低延迟定制网络互联,异步MIMD,多个进程有自己的地址空间,通过消息传递机制通信
    • COW工作站机群:节点是完整操作系统的工作站,且有磁盘
    • DSM分布共享存储处理机:高速缓存目录DIR确保缓存一致性,将物理分布式LM组成逻辑共享SM从而提供统一地址的编程空间

    注:对称指所有处理器都能同等地访问I/O很同样的运行程序(如OS和I/O服务程序),而非对称主从式是仅有主处理器运行OS和控制访问I/O并监控从处理器执行

    2.并行计算机访存模型

    UMA(Uniform Memory Access)均匀存储访问:物理存储器被所有处理器均匀共享,所有处理器对所有SM访存时间相同,每台处理器可带有高速私有缓存,外围设备共享。
    - NUMA非均匀存储访问:共享的SM是由物理分布式的LM逻辑构成,处理器访存时间不一样,访问LM或CSM(群内共享存储器)内存储器比访问GSM(群间共享存储器)快
    - COMA(Cache-Only MA)全高速缓存存储访问:NUMA的特例、全高速缓存实现
    - CC-NUMA(Coherent-Cache NUMA)高速缓存一致性NUMA:NUMA+高速缓存一致性协议
    - NORMA(No-Remote MA)非远程存储访问:无SM,所有LM私有,通过消息传递通信

    3.Cache一致性协议

    • 监听总线协议:总线连接通信,写无效和写更新策略
    • 基于目录的协议:目录记录共享数据缓存状态,读缺失时查看目录D,写更新时通知目录D

    4.其他并行计算概念

    衡量并行计算机性能单位:

    • PFLOPS:每秒1千万亿 (=10^15) 次的浮点运算
    • TFLOPS:每秒1万亿 (=10^12) 次的浮点运算
    • GFLOPS:每秒10亿 (=10^9) 次的浮点运算

    TOP500前500名超级计算机排名指标(GFLOPS):
    Rmax:Maximal LINPACK(Linear system package) performance achieved
    Rpeak:Theoretical peak performance

    三、并行计算性能评测

    1、机器级的性能测评

    主要包括CPU和存储器的某些基本性能指标,并行通信开销以及机器的成本、价格和性能价格比等。
    (1)CPU和存储器的某些基本性能指标

    • 工作负载:指计算操作的数目,通常可用执行时间、所执行的指令数目和所完成的浮点运算数3个物理量来度量。
    • 并行执行时间:Tn=Tcomput+Tparo+Tcomm。其中Tcomput 为计算时间,Tparo 为并行开销时间,包括进程管理(生成、切换和结束等)、组操作(进程组的生成与消亡等)时间,和进程查询(询问进程的标志、等级和组大小等)时间;Tcomm 为相互通信时间,包括同步(如路障、临界区、事件等)、通信(如点到点通信、整体通信、读/写共享变量等)时间和聚操作(如归约和前缀运算等)时间。

    • 存储器的层次结构:各层存储器的容量、延迟和带宽。

    • 存储器带宽的估算

    (2)通信开销Tcomm

    (3)机器的成本、价格和性能价格比

    2、算法级的性能测评

    包括加速、效率和可扩放性等。

    (1)并行系统的加速(比)
    指对于一个给定的应用,并行算法(或并行程序)的执行速度相对于串行算法(或串行程序)的执行速度加快了多少倍。

    加速比性能定律
    Amdahl加速定律(固定计算负载)
    Gustafson定律(适用于可扩放问题)
    Sun&Ni定律(受限于存储器)

    约定:

    • p是处理器数
    • 问题规模W=程序中串行分量Ws+可并行部分Wh
    • f为串行部分比例,f=Ws/W
    • S为加速比

    (2)扩放性
    最朴素的含义是在确定的应用背景下,计算机系统(或算法或编程等)性能随处理器数的增加而按比例提高的能力。被广泛用来描述并行算法能否有效利用可扩充的处理器的能力。

    3、程序级的性能测评

    基本测试程序、数学库测试程序和并行测试程序等

    四、并行计算理论基础:并行算法设计

    1、并行算法

    并行算法是一些可同时执行的诸进行的集合,这些进程互相作用和协调动作从而实现给定问题的求解。
    从不同角度分类成数值计算和非数值计算的并行算法;同步、异步和分布的并行算法;共享存储和分布存储的并行算法;确定的和随机的并行算法等。

    2、并行算法的表达

    (1)par-do

    n个节点并行完成for循环(每个节点不同,和i相关):

    for i = 1 to n par-do
        ...
    endfor

    (2)for all

    所有节点都执行相同语句:

    for all Pi, where 0 <= i <= k do
        ...
    endfor

    3、并行算法的复杂度

    通常分析以下指标:

    • 运行时间t(n):求解问题的时间,包括计算时间和通信时间
    • 处理器数目p(n):求解给定问题所用的处理器数目
    • 成本c(n):c(n) = t(n)*p(n)
    • 成本最优——并行算法的成本在数量级上等于最坏情况下串行求解次问题所需要的执行步数
    • 工作量W(n):并行算法完成的总的操作数量
    • 工作量最优:功耗低、环保

    并行算法的WT表示——Brent定理:

    令W(n)是并行算法A在运行时间T(n)内所执行的运算量,则A使用p台处理器可在t(n) = O(W(n)/p + T(n))时间内执行完毕

    4、并行计算模型

    1.PRAM模型(SIMD-SM)

    PRAM(Parallel Random Access Machine)并行随机存取机器,是一种抽象并行计算模型,它假设:

    • 存在容量无限大的SM
    • 有限或无限个功能相同的处理器,且均有简单算术运算和逻辑判断功能
    • 任何时刻各处理器可通过SM交换数据

    根据并发访问机制,又分为:

    • 不允许同时读和同时写的PRAM-EREW
    • 允许同时读但不允许同时写的PRAM-CREW
    • 允许同时读和同时写的PRAM-CRCW

    PRAM-CRCW又分为:

    • 只允许同时写相同的数CPRAM-CRCW
    • 只允许优先处理器先写PPRAM-CRCW
    • 允许任意处理器自由写APRAM-CRCW

    PRAM优点:

    • 适合并行算法表达、分析和比较
    • 使用简单,屏蔽了通信、存储管理、进程同步等并行细节
    • 易于修改算法设计以适应不同并行机

    PRAM缺点:

    • PRAM是同步模型,同步锁费时
    • 不适用于MIMD和DM
    • 假设任何处理器可在单位时间内访问任何处理单元而不考虑竞争和带宽,不现实

    2.异步APRAM模型(MIMD-SM)

    异步APRAM模型假设:

    • 每个处理器有LM、局部时钟、局部程序
    • 处理器通信经过SM
    • 无全局时钟,各处理器异步执行各自指令
    • 处理器之间的指令相互依赖关系必须显式加入同步障
    • 一条指令可以在非确定但有界时间内完成

    指令类型有:

    • 全局读:从SM读到LM
    • 局部操作:LM操作存入LM
    • 全局写:LM写入SM
    • 同步:各处理器需等到其他处理器到达后才能继续执行

    APRAM比PRAM更加接近实际并行机

    3.BSP模型(MIMD-DM)

    BSP(Bulk Synchronous Parallel)大同步并行机(APRAM算作轻量)是一个分布式存储的MIMD模型,它的计算由若干全局同步分开的、周期为L的超级步组成,各超级步中处理器做LM操作并通过选路器接收和发送消息;然后做一次全局检查,以确定该超级步是否已经完成(块内异步并行,块间显式同步)

    参数:处理器数p、选路器吞吐率g、全局同步间隔L、一个超级步中一个处理器至多发送或接收h条消息

    4.LogP模型:MIMD-DM,点到点通讯

    LogP模型是分布式存储、点到点通信的MIMD模型

    LogP采取隐式同步,而不显式同步障

    5、并行算法基本设计策略

    1 、串改并
    发掘和利用现有串行算法中的并行性,直接将串行算法改造为并行算法

    最常用的设计思路但并不普适,好的串行算法一般无法并行化(数值串行算法可以)

    快速排序的串改并
    SISD上串行执行,最坏情况下O(n^2),理想情况下O(nlogn)

    思路:将O(n)的划分(Partition)并行化是关键,算法:

    • 构造一棵二叉排序树,主元是根
    • 小于等于主元素处于左子树,大于主元素处于右子树
    • 左右子树均是二叉排序树

    在CRCW模型上,用伪代码描述如下:

    //A[1...n]排序用n个处理器,处理器i中存有A[i]
    //f[i]中存有其元素是主元素的处理器号
    //LC[1...n]和RC[1...n]分别记录给定主元素的左儿子和右儿子
    
    for each processor i par-do
        root = i    //所有处理器竞争,只有一个写入root
        f[i] = root //所有处理器都把root写入自己的f[i]
        LC[i] = RC[i] = n + 1   //初始值
    endfor
    
    repeat for each processor i != root do
        if (A[i] < A[f[i]]) || (A[i] == A[f[i]] && i < f[i])
            LC[f[i]] = i    //并发写,所有满足条件的i只有一个写入LC[f[i]]作为左子树的根,也就是下一次循环的主元素
            if i == LC[f[i]] then
                exit        //若当前处理器写入则什么也不做
            else
                f[i] = LC[f[i]] //若当前处理器没有写入,那么它只能当LC[f[i]]的字节点了
            endif
        else
            RC[f[i]] = i    //并发写,所有满足条件的i只有一个写入RC[f[i]]作为右子树的根,也就是下一次循环的主元素
            if i == RC[f[i]] then
                exit        //若当前处理器写入则什么也不做
            else
                f[i] = RC[f[i]] //若当前处理器没有写入,那么它只能当RC[f[i]]的字节点了
            endif
        endif
    endrepeat

    每次迭代构造一层排序二叉树花费O(1)时间,在基本平衡的情况下树高O(logn),则算法复杂度为O(logn)

    2 、全新设计
    从问题本身描述出发,不考虑相应的串行算法,设计 一个全新的并行算法

    有向环K着色算法的并行化设计
    问题:有向环顶点着色,一共K种颜色,相邻顶点不允许同色

    串行算法(3着色):交替2种颜色,若顶点是奇数则需要用到第3种颜色(难以并行化)

    SIMD-EREW上的并行K着色算法:

    //初始随机着色为c[i],每个顶点着色不同
    //输出着色方案为nc[i]
    for i = 1 to n par-do
        k = c[i]和c[i的后继]的最低的不同二进制位
        nc[i] = 2 * k + c[i]的二进制第k位
    endfor

    O(1)时间完成,需要算法正确性证明

    3、借用法
    找出求解问题和某个已解决问题之间的联系,改造或利用已知算法应用到求解问题上

    利用矩阵乘法求所有点对间最短路径
    d[k][i][j]表示从vi到vj**至多**经过k-1个中间顶点时的最短路径,d[k][i][j] = min{d[k/2][i][l]+d[k/2][l][j]}

    那么可以用矩阵乘法的改进(乘变加,求和变min)做logn次矩阵乘法即可

    思路是这样,具体伪代码略,需要O(n^3)个节点,时间复杂度为O(log^2(n))

    6、并行算法常用设计技术

    1、划分设计技术

    使用划分法把问题求解分成两步:

    • 把给定问题划分成p个几乎等尺寸的子问题
    • 用p台处理器并行求解子问题

    (1)均匀划分(PSRS排序)

    长度为n的待处理序列均匀划分给p个处理器,每个处理器处理n/p个元素

    MIMD机器上的PSRS排序算法:

    (1)均匀划分:将n个元素A[1..n]均匀划分成p段,分配给p个处理器
    (2)局部排序:pi调用串行排序算法对A[(i-1)n/p+1..in/p]排序
    (3)选取样本:pi从其有序子序列A[(i-1)n/p+1..in/p]中选取p个样本元素
    (4)样本排序:用一台处理器对p2个样本元素进行串行排序
    (5)选择主元:用一台处理器从排好序的样本序列中选取p-1个主元,并播送给其他pi 
    (6)主元划分:pi按主元将有序段A[(i-1)n/p+1..in/p]划分成p段
    (7)全局交换:各处理器将其有序段按段号交换到对应的处理器中(一定保证均匀划分??)
    (8)归并排序:各处理器对接收到的元素进行归并排序

    (2)方根划分(Valiant归并排序)

    长度为n的待处理序列,取i*sqrt(n)为划分元,将元素划分成若干段交给处理器处理

    SIMD-CREW机器上的Valiant归并排序:

    (1)方根划分:把A和B(长n有序段)的第i*sqrt(n)元素作为划分元,把A和B分成若干段
    (2)段间比较:A中的所有划分元和B中的所有划分元比较,确定A中划分元应插入B中的哪一段
    (3)段内比较:A中的划分元和B中相应段比较并确定插入位置,这些插入位置又将B重新划分成了若干段
    (4)段组合并:插入A划分元后,又得到若干有序段组需要归并,递归直到有一组(A)的长度为0

    使用n个处理器可以在O(loglogn)内完成

    (3)对数划分(并行归并排序)

    取i*logn作为划分元划分

    定义位序rank(x,X)为X中小于等于x的元素个数,则有PRAM-CREW上的对数划分:

    //非降有序的A={a[1],...,a[n]}和B={b[1],...,b[m]}归并
    //假设log(m)和k=m/log(m)均为整数
    j[0]=0
    j[k]=n
    
    for i = 1 to k - 1 par-do
        j[i] = rank(b[ilogm], A)
    endfor
    
    for i = 1 to k - 1 par-do
        Bi = {b[ilogm+1], ..., b[(i+1)logm]}
        Ai = {a[j[i]+1], ..., a[j[i+1]]}
    endfor
    
    //将原问题转化为子序列组Bi和Ai的归并,那么同样可以递归调用完成整个序列的归并
    //对数划分保证Bi和Ai中的元素均大于Bi-1和Ai-1中的元素

    (4)功能划分( (m,n)-选择)

    功能划分是根据特定问题而把序列分成p个等长组,每组符合问题特性的一种划分方法

    (m,n)-选择问题是将长为n的序列中选取前m个较小的元素,利用功能划分来实现并行化的(m,n)-选择问题求解:

    (1)功能划分:将A划分成g=n/m组,每组含m个元素
    (2)局部排序:使用Batcher排序网络将各组并行排序
    (3)两两比较:将所排序的各组两两比较,从而形成MIN序列
    (4)排序-比较:对各个MIN序列,重复执行第(2)和第(3)步,直至选出m个最小者

    2、分治设计技术

    分治将复杂问题划分成较小规模特性相同的子问题,且子问题类型和原问题类型相同,通常用递归完成分治算法

    3、平衡树设计技术

    以树的叶结点为输入,中间结点为处理结点,由叶向根或由根向叶逐层进行并行处理

    4、倍增设计技术

    递归调用时,所要处理数据之间的距离逐步加倍, 经过k步后即可完成距离为2^k的所有数据的计算

    5、流水线技术

    将算法路程分成p个前后衔接的任务片段,一个任务片段完成之后其后继任务片段可以立即开始,那么久可以引入流水线的思想来处理多条数据

    五、并行计算软件支撑:并行编程

    1、并行程序设计基础

    1.1 并行语言构造方法

    • 库例程:MPI、Pthreads
    • 扩展串行语言:Fortran90
    • 加编译注释构造:OpenMP

    1.2 并行性问题

    可利用SPMD来伪造MPMD

    需要运行MPMD:parbegin S1 S2 S3 parend
    可以改造成SPMD:

    for i = 1 to 3 par-do
        if i == 1 then S1
        else if i == 2 then S2
        else if i == 3 then S3
    endfor

    那么并行扩展至需要支持SPMD即可

    1.3 交互/通信

    (1)交互类型

    • 通信:进程间传数(共享变量、消息传递、参数传递[父进程传给子进程])
    • 同步:进程间相互等待或继续执行的操作(原子同步、控制同步[同步障、临界区]、数据同步[锁、condition、监控程序和事件])
    • 聚合:将分进程所计算的的结果整合起来(规约、扫描)

    (2)交互方式

    • 同步交互:所有参与者全部到达后继续执行
    • 异步交互:任意进程到达后不必等待其他进程即可继续执行

    (3)交互模式

    按编译时是否能确定交互模式可分为静态的、动态的

    按多少发送者和接收者:

    • 一对一:点到点通信
    • 一对多:广播、散播
    • 多对一:收集、规约
    • 多对多:全交换、扫描、置换、移位

    1.4 并行编程风范

    • 相并行:BSP模式,程序由一组超级步组成,步内各自并行计算,步间通信同步
    • 主从并行:主进程串行执行并且协调任务,子进程计算任务,需要划分设计并结合相并行
    • 分治并行:父进程把负载分割并指派给子进程,难以平衡负载
    • 流水线并行:进程划分成流水线,依次依赖,数据开始流动
    • 工作池并行:进程从工作池中取任务执行

    1.5 并行程序设计模型

    (1)隐式并行

    用串行语言编程,编译器货操作系统自动转化成并行代码

    特点:语义简单、可以执行好、易调试易验证、but效率低

    (2)数据并行

    SIMD模型,包括数据选路和局部计算,特点:但现场、松散同步、常用聚合操作

    数据并行计算π:

    long i,j,t,N=100000;
    double local[N], temp[N], pi, w;
    w = 1.0/N;
    
    forall (i = 0; i < N; i++) {
        local[i] = (i + 0.5) * w;
        temp[i] = 4.0 / (1.0 + local[i] * local[i]);
    }
    
    pi = reduce(temp, +);

    (3)消息传递

    MPP、COW自然模型,MPI广泛应用:多线程异步并行、地址空间分开、常用SPMD形式编码

    MPI消息传递计算π:

    #define N 100000
    main(){
        double local=0.0,pi,w,temp=0.0;
        long i,taskid,numtask;
    
        w=1.0/N;
    
        MPI_Init(&argc,&argv);
        MPI_Comm_rank(MPI_COMM_WORLD,&taskid);
        MPI_Comm_Size(MPI_COMM_WORLD,&numtask);
    
        for (i = taskid; i < N; i=i + numtask){
            temp = (i+0.5)*w;
            local = 4.0/(1.0+temp*temp)+local; 
        }
    
        MPI_Reduce(&local,&pi,1,MPI_Double,MPI_MAX,0, MPI_COMM_WORLD);
    
        if (taskid == 0) printf(“pi is %f \n”,pi*w); 
    
        MPI_Finalize() ;
    }

    (4)共享变量

    PVP、SMP、DSM自然模型,多线程异步,显示同步而隐式通信

    OpenMP使用共享变量计算π:

    #define N 100000
    main(){
        double local,pi=0.0,w;
        long i;
    
        w=1.0/N;
    
        #pragma parallel
        #pragma shared(pi, w)
        #pragma local(i, local) 
        {
            #pragma parallel for (i = 0; i < N; i++)
            {
                local = (i + 0.5) * w;
                local = 4.0 / (1.0 + local * local);
            }
            #pragma critical
            {
                pi = pi + local
            }
        }
    }

    六、共享存储系统并行编程——OpenMP编程

    OpenMP是FORK-JOIN模型,主线程串行执行,直到编译制导并行域出现

    七、分布存储系统并行编程——MPI编程

    MPI是一种消息传递接口的标准,适用于分布式存储系统的编程模型

    与OpenMP不同的是,MPI是多进程的并行模式,运行时需要在外部指定开启进程数,并且是用SPMD的编程风格去模拟MPMD的编程风格(用进程号区别),不会FORK-JOIN而是通过消息传递同步

    八、GPU体系结构及编程——CUDA编程

    展开全文
  • C#并行编程(3):并行循环

    万次阅读 2019-04-13 08:43:57
    C#并行编程(3):并行循环 初识并行循环 并行循环主要用来处理数据并行的,如,同时对数组或列表中的多个数据执行相同的操作。 在C#编程中,我们使用并行类System.Threading.Tasks.Parallel提供的静态方法...

    C#并行编程(3):并行循环

    初识并行循环

    并行循环主要用来处理数据并行的,如,同时对数组或列表中的多个数据执行相同的操作。

    在C#编程中,我们使用并行类System.Threading.Tasks.Parallel提供的静态方法Parallel.ForParallel.ForEach来实现并行循环。从方法名可以看出,这两个方法是对常规循环forforeach的并行化。

    简单用法

    使用并行循环时需要传入循环范围(集合)和操作数据的委托Action<T>

    Parallel.For(0, 100, i => { Console.WriteLine(i); });
    
    Parallel.ForEach(Enumerable.Range(0, 100), i => { Console.WriteLine(i); });

    使用场景

    对于数据的处理需要耗费较长时间的循环适宜使用并行循环,利用多线程加快执行速度。

    对于简单的迭代操作,且迭代范围较小,使用常规循环更好好,因为并行循环涉及到线程的创建、上下文切换和销毁,使用并行循环反而影响执行效率。

    对于迭代操作简单但迭代范围很大的情况,我们可以对数据进行分区,再执行并行循环,减少线程数量。

    循环结果

    Parallel.ForParallel.ForEach方法的所有重载有着同样的返回值类型ParallelLoopResult,并行循环结果包含循环是否完成以及最低迭代次数两项信息。

    下面的例子使用Parallel.ForEach展示了并行循环的结果。

    ParallelLoopResult result = Parallel.ForEach(Enumerable.Range(0, 100), (i,loop) =>
    {// 委托传入ParallelLoopState,用来控制循环执行
        Console.WriteLine(i + 1);
        Thread.Sleep(100);
        if (i == 30) // 此处设置循环停止的确切条件
        {
            loop.Break();
            //loop.Stop();
        }
    });
    Console.WriteLine($"{result.IsCompleted}-{result.LowestBreakIteration}");

    值得一提的是,循环的Break()Stop()只能尽早地跳出或者停止循环,而不能立即停止。

    取消循环操作

    有时候,我们需要在中途取消循环操作,但又不知道确切条件是什么,比如用户触发的取消。这时候,可以利用循环的ParallelOptions传入一个CancellationToken,同时使用异常处理捕获OperationCanceledException以进行取消后的处理。下面是一个简单的例子。

    /// <summary>
    /// 取消通知者
    /// </summary>
    public static CancellationTokenSource CTSource { get; set; } = new CancellationTokenSource();
    
    /// <summary>
    /// 取消并行循环
    /// </summary>
    public static void CancelParallelLoop()
    {
        Task.Factory.StartNew(() =>
        {
            try
            {
                Parallel.ForEach(Enumerable.Range(0, 100), new ParallelOptions { CancellationToken = CTSource.Token },
                    i =>
                    {
                        Console.WriteLine(i + 1);
                        Thread.Sleep(1000);
                    });
            }
            catch (OperationCanceledException oce)
            {
                Console.WriteLine(oce.Message);
            }
        });
    }
    static void Main(string[] args)
    {
        ParallelDemo.CancelParallelLoop();
        Thread.Sleep(3000);
        ParallelDemo.CTSource.Cancel();
    
        Console.ReadKey();
    }

    循环异常收集

    并行循环执行过程中,可以捕获并收集迭代操作引发的异常,循环结束时抛出一个AggregateException异常,并将收集到的异常赋给它的内部异常集合InnerExceptions。外部使用时,捕获AggregateException,即可进行并行循环的异常处理。

    下面的例子模拟了并行循环的异常抛出、收集及处理的过程。

    /// <summary>
    /// 捕获循环异常
    /// </summary>
    public static void CaptureTheLoopExceptions()
    {
        ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();
        Parallel.ForEach(Enumerable.Range(0, 100), i =>
        {
            try
            {
                if (i % 10 == 0)
                {//模拟抛出异常
                    throw new Exception($"{DateTime.Now}=> Thread-[{Thread.CurrentThread.ManagedThreadId}] had thrown a exception. [{i}]");
                }
                Console.WriteLine(i + 1);
                Thread.Sleep(100);
            }
            catch (Exception ex)
            {//捕获并收集异常
                exceptions.Enqueue(ex);
            }
        });
    
        if (!exceptions.IsEmpty)
        {// 方法内部可直接进行异常处理,若需外部处理,将收集到的循环异常抛出
            throw new AggregateException(exceptions);
        }
    }

    外部处理方式

    try
    {
        ParallelDemo.CaptureTheLoopExceptions();
    }
    catch (AggregateException aex)
    {
        foreach (Exception ex in aex.InnerExceptions)
        {// 模拟异常处理
            Console.WriteLine(ex.Message);
        }
    }

    分区并行处理

    当循环操作很简单,迭代范围很大的时候,ParallelLoop提供一种分区的方式来优化循环性能。下面的例子展示了分区循环的使用,同时也能比较几种循环方式的执行效率。

    /// <summary>
    /// 分区并行处理,顺便比较各种循环的效率
    /// </summary>
    /// <param name="rangeSize">迭代范围</param>
    /// <param name="opDuration">操作耗时</param>
    public static void PartationParallelLoop(int rangeSize = 10000, int opDuration = 1)
    {
        //PartationParallelLoopWithBuffer
        Stopwatch watch0 = Stopwatch.StartNew();
        Parallel.ForEach(Partitioner.Create(Enumerable.Range(0, rangeSize), EnumerablePartitionerOptions.None),
            i =>
            {//模拟操作
                Console.WriteLine($"{DateTime.Now}=> Thread-[{Thread.CurrentThread.ManagedThreadId}] was running. [{i}]");
                Thread.Sleep(opDuration);
            });
        watch0.Stop();
    
        //PartationParallelLoopWithoutBuffer
        Stopwatch watch1 = Stopwatch.StartNew();
        Parallel.ForEach(Partitioner.Create(Enumerable.Range(0, rangeSize),EnumerablePartitionerOptions.NoBuffering),
            i =>
            {//模拟操作
                Console.WriteLine($"{DateTime.Now}=> Thread-[{Thread.CurrentThread.ManagedThreadId}] was running. [{i}]");
                Thread.Sleep(opDuration);
            });
        watch1.Stop();
    
        //NormalParallelLoop
        Stopwatch watch2 = Stopwatch.StartNew();
        Parallel.ForEach(Enumerable.Range(0, rangeSize),
            i =>
            {//模拟操作
                Console.WriteLine($"{DateTime.Now}=> Thread-[{Thread.CurrentThread.ManagedThreadId}] was running. [{i}]");
                Thread.Sleep(opDuration);
            });
        watch2.Stop();
    
        //NormalLoop
        Stopwatch watch3 = Stopwatch.StartNew();
        foreach (int i in Enumerable.Range(0, rangeSize))
        {//模拟操作
            Console.WriteLine($"{DateTime.Now}=> Thread-[{Thread.CurrentThread.ManagedThreadId}] was running. [{i}]");
            Thread.Sleep(opDuration);
        }
        watch2.Stop();
                
        Console.WriteLine();
        Console.WriteLine($"PartationParallelLoopWithBuffer    => {watch0.ElapsedMilliseconds}ms");
        Console.WriteLine($"PartationParallelLoopWithoutBuffer => {watch1.ElapsedMilliseconds}ms");
        Console.WriteLine($"NormalParallelLoop                 => {watch2.ElapsedMilliseconds}ms");
        Console.WriteLine($"NormalLoop                         => {watch3.ElapsedMilliseconds}ms");
    }

    在 I7-7700HQ + 16GB 配置 VS调试模式下得到下面一组测试结果。

    Loop Condition PartationParallelLoop WithBuffer PartationParallelLoop WithoutBuffer Normal ParallelLoop Normal Loop
    10000,1 10527 11799 11155 19434
    10000,1 9513 11442 11048 19354
    10000,1 9871 11391 14782 19154
    100,1000 9107 5951 5081 100363
    100,1000 9086 5974 5187 100162
    100,1000 9208 5125 5255 100239
    100,1 350 439 243 200
    100,1 390 227 166 198
    100,1 466 225 84 197

    应该根据不同的应用场景选择合适的循环策略,具体如何选择,朋友们可自行体会~

    作  者:LayShun
    出  处:http://cnblogs.com/chenbaoshun/ 。
    版权声明:本文原创发表于 博客园,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。

    分类: [01]技术沉淀

    标签: 并行编程

    展开全文
  • 任务并行VS数据并行

    2019-09-29 05:34:03
    并行计算中,有两种并行的方法:任务并行(task-parallelism)和数据并行(data-parallelism)。 任务并行:将许多可以解决问题的任务分割,然后分布在一个或者多个核上进行程序的执行。 数据并行:将可以解决问题...
    并行计算中,有两种并行的方法:任务并行(task-parallelism)和数据并行(data-parallelism)。
    任务并行:将许多可以解决问题的任务分割,然后分布在一个或者多个核上进行程序的执行。
    数据并行:将可以解决问题的数据进行分割,将分割好的数据放在一个或者多个核上进行执行;每一个核对这些数据都进行类似的操作。
     
    例:
    有一个professor P,他在给本科生上一门课,一共有300个本科生,考试的试卷上有15到题目。有三个助教来帮助Professor P修改试卷。
    那么,这三个助教可以采用数据并行或者任务并行的方法来完成任务。
    数据并行:
    每个人平均看100份试卷,然后分别对自己的试卷的15到题目打分。
    任务并行:
    每个人分别负责5个题目。
     

    转载于:https://www.cnblogs.com/SevenwindMa/p/4366218.html

    展开全文
  • C#并行编程(1):理解并行

    万次阅读 2019-04-13 08:41:12
    C#并行编程(1):理解并行 什么是并行 并行是指两个或者多个事件在同一时刻发生。 在程序运行中,并行指多个CPU核心同时执行不同的任务;对于单核心CPU,严格来说是没有程序并行的。并行是为了提高任务执行效率...
  • 并行软件 在运行共享内存系统时,会启动一个单独的进程,然后派生(fork)出多个线程,所以当我们谈论共享内存程序时,我们指的是正在执行任务的线程。 需要在进程、线程之间平均分配的任务从而满足使得每个进程/...
  • 并行Linq

    千次阅读 2020-04-15 08:57:57
    并行LINQ 并行查询 .NET4在System.Linq名称空间中包含一个新类ParalleIEnumerable ,可以分解查询的工作使其分布在多个线程上。尽管Enmerable类给IEnunerable<T>接口定义了扩展方法,但 ParalleIEnumerable 类...
  • 并发和并行区别秒懂

    万次阅读 多人点赞 2018-06-19 12:04:45
    你吃饭吃到一半,电话来了,你一直到吃完了以后才去接,这就说明你不支持并发也不支持并行。 你吃饭吃到一半,电话来了,你停了下来接了电话,接完后继续吃饭,这说明你支持并发。(不一定是同时的) 你吃饭吃到...
  • 并行算法

    千次阅读 2019-04-23 19:22:44
    并行算法就是用多台处理机联合求解问题的方法和步骤,其运行过程是将给定的问题首先分解成若干个尽量相互独立的子问题,然后使用多台计算机同时求解他,从而最终求得原问题的解。 1.并行算法设计 并行算法设计...
  • 此文翻译自[1],[1]对数据并行和模型并行进行了很好地区分,因此这里推荐给大家。 介绍 现在深度学习模型的参数量已经变得越来越多了,数据集的尺寸也随之疯狂地增长。为了在一个巨大的数据集上训练一个复杂的深度...
  • 并行排序

    千次阅读 2019-04-20 14:05:34
    并行排序算法是计算机并行计算能力大大发展之后,为了提高排序效率而提出的算法。 原有的的排序算法都是给定了数据再进行排序,排序的效率很大程度上取决于数据的好坏,例如快速排序、归并排序。并行排序则是一类...
  • [并行计算] 1. 并行计算简介

    万次阅读 多人点赞 2017-07-20 15:30:07
    这篇帖子旨在为并行计算这一广泛而宏大的话题提供一个非常快速的概述,作为随后教程的先导。因此,它只涵盖了并行计算的基础知识,实用于刚刚开始熟悉该主题的初学者。
  • 并行加速

    2017-03-29 21:53:56
    并行加速平台 hadoop spark cuda MPI openMPI opencl 深度学习框架 tensorflow 支持多GPU并行计算 数据并行和模型并行 caffe 不支持数据并行和模型并行 单GPU计算 caffe-MPI 支持集群GPU计算 支持数据并行、模型...
  • OpenCL并行加减乘除示例——数据并行与任务并行 ==============================================================目录结构1、数据并行2、任务并行3、参考 =====================================================...
  • 并行计算和并行计算机体系结构

    千次阅读 2017-12-27 09:39:59
    关于并行你知道多少思考多少 冯诺依曼计算机体系结构 什么是并行计算 为什么用并行计算 谁在用并行计算 硬件提供了哪些支持 软件提供了哪些支持 总结 参考资料关于并行,你知道多少?思考多少?听到“并行”这个词汇...
  • 并行查询允许将一个SQL SELECT语句划分为多个较小的查询,每个部分的查询并发地运行,然后会将各个部分的结果组合起来,提供最终的答案。 1、执行sql:select /*+ parallel(a,4) */ * from tf_f_user a where ...
  • Python并行执行for循环

    万次阅读 2018-12-04 20:52:55
    在介绍如何最简单地利用 python 实现并行前,我们先来看一个简单的代码。 words = ['apple', 'bananan', 'cake', 'dumpling'] for word in words: print word 上面的例子中,我们用一个 for 循环打印出 words ...
  • 并行区内没有调用函数的指令,结果在并行部分之外的部分也被并行了,求大神解答
  • 并行or串行

    2019-01-15 08:30:41
    记得在很小的时候,就读过一个著名的烧水泡茶的例子,例子的细节自己记不太清楚了,但这个例子的结论,就是做事情时应该尽可能的让能并行的事情并行进行,这样以提高工作效率。 然而,到真正参加工作之后,特别是...
  • matlab并行不启动 关闭默认并行

    千次阅读 2019-08-08 09:46:44
    matlab并行是给常简单地,但是有的时候使用parfor并不能开始并行。 命令行如果提示: Starting parallel pool (parpool) using the 'local' profile ... Preserving jobs with IDs: 1 because they contain crash ...
  • 并行计算

    2017-05-07 20:06:50
    维基百科: ...并行计算(英语:parallel computing)一般是指许多指令得以同时进行的计算模式。在同时进行的前提下,可以将计算的过程分解成小部分,之后以并发方式...相对于串行计算,并行计算可以划分成时间并行和空间
  • activiti实战系列 并行网关(parallelGateWay)

    万次阅读 多人点赞 2016-04-16 08:43:09
    流程图 13.2:部署流程定义+启动流程实例 13.3:查询我的个人任务 ...2) 并行网关的功能是基于进入和外出的顺序流的: ...分支(fork): 并行后的...汇聚(join): 所有到达并行网关,在此等待的进入分支, 直到所...
  • CPU并行与GPU并行联系及区别

    千次阅读 2018-12-27 00:16:36
    应用特点:GPU并行吞吐量大,适合大数据并行处理;CPU适合逻辑处理和串行计算,适合多任务并行处理; GPU工作模式 1)CPU 具有独立的内存和寄存器,GPU也具有独立的显存和寄存器。CPU作为主控制器,CPU和 GPU ...
  • 所谓并行性包含同时性和并发性。 同时性是指两个或两个以上的事件在同一时刻发生,并发性是指两个或多个事件在同一时间段发生。即在同一时刻或同一时间段内完成两个或两个以上性质相同或性质不同的功能,只要在时间...
  • 并行转串行 串行转并行输出模块

    千次阅读 2018-12-28 17:50:02
    并行转串行 串行转并行输出模块 夏宇闻Verilog 第15章学习笔记 通信协议:scl为高,sda由高跳变低,start;scl为高,sda由低跳变为高,stop;scl为低,sda数据位才能变化 两个模块ptosda和out16hi,将ptosda并转串...
  • python并行计算

    千次阅读 2019-04-02 10:18:41
    Python】【并行计算】Python 多核并行计算 快速掌握用python写并行程序 转载python并行运算实例 Python并行(parallel)之谈 python基于multiprocessing的通用的并行计算框架 Parallel Python——一个简单的...
  • 并行计算复习第一篇 并行计算硬件平台:并行计算机
  • 并行计算复习第四篇 并行计算软件支撑:并行编程
  • 并行和串行

    千次阅读 2019-04-07 15:08:26
    并行和串行都是通讯中数据传输的方式,二者有着本质的不同。 1.并行通讯:同一时刻,可以传输多个bit位的信号,有多少个信号位就需要多少根信号线。 2.串行通讯:同一时刻,只能传输一个bit位的信号,只需要一根...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 117,297
精华内容 46,918
关键字:

并行