精华内容
下载资源
问答
  • 并行程序设计

    2015-11-06 15:11:31
    并行程序设计PPT,与并行程序设计配套使用.
  • 并行程序设计导论(英文版)》CHAPTER 1 Why Parallel Computing? 11.1 Why We Need Ever-Increasing Performance 21.2 Why We’re Building Parallel Systems 31.3 Why We Need to Write Parallel Programs 31.4 ...

    《并行程序设计导论(英文版)》

    CHAPTER 1 Why Parallel Computing? 1

    1.1 Why We Need Ever-Increasing Performance 2

    1.2 Why We’re Building Parallel Systems 3

    1.3 Why We Need to Write Parallel Programs 3

    1.4 How Do We Write Parallel Programs? 6

    1.5 What We’ll Be Doing 8

    1.6 Concurrent, Parallel, Distributed 9

    1.7 The Rest of the Book 10

    1.8 A Word of Warning 10

    1.9 Typographical Conventions 11

    1.10 Summary 12

    1.11 Exercises 12

    CHAPTER 2 Parallel Hardware and Parallel Software 15

    《并行程序设计导论(英文版)》

    CHAPTER 1 Why Parallel Computing? 1

    1.1 Why We Need Ever-Increasing Performance 2

    1.2 Why We’re Building Parallel Systems 3

    1.3 Why We Need to Write Parallel Programs 3

    1.4 How Do We Write Parallel Programs? 6

    1.5 What We’ll Be Doing 8

    1.6 Concurrent, Parallel, Distributed 9

    1.7 The Rest of the Book 10

    1.8 A Word of Warning 10

    1.9 Typographical Conventions 11

    1.10 Summary 12

    1.11 Exercises 12

    CHAPTER 2 Parallel Hardware and Parallel Software 15

    2.1 Some Background15

    2.1.1 The von Neumann architecture 15

    2.1.2 Processes, multitasking, and threads 17

    2.2 Modifications to the von Neumann Model 18

    2.2.1 The basics of caching 19

    2.2.2 Cache mappings 20

    2.2.3 Caches and programs: an example 22

    2.2.4 Virtual memory 23

    2.2.5 Instruction-level parallelism 25

    2.2.6 Hardware multithreading 28

    2.3 Parallel Hardware 29

    2.3.1 SIMD systems 29

    2.3.2 MIMD systems 32

    2.3.3 Interconnection networks 35

    2.3.4 Cache coherence 43

    2.3.5 Shared-memory versus distributed-memory 46

    2.4 Parallel Software 47

    2.4.1 Caveats 47

    2.4.2 Coordinating the processes/threads 48

    2.4.3 Shared-memory 49

    2.4.4 Distributed-memory 53

    2.4.5 Programming hybrid systems 56

    2.5 Input and Output 56

    2.6 Performance 58

    2.6.1 Speedup and efficiency 58

    2.6.2 Amdahl’s law 61

    2.6.3 Scalability 62

    2.6.4 Taking timings 63

    2.7 Parallel Program Design 65

    2.7.1 An example 66

    2.8 Writing and Running Parallel Programs 70

    2.9 Assumptions 70

    2.10 Summary 71

    2.10.1 Serial systems 71

    2.10.2 Parallel hardware 73

    2.10.3 Parallel software 74

    2.10.4 Input and output 75

    2.10.5 Performance 75

    2.10.6 Parallel program design 76

    2.10.7 Assumptions 76

    2.11 Exercises 77

    CHAPTER 3 Distributed-Memory Programming with MPI 83

    3.1 Getting Started84

    3.1.1 Compilation and execution 84

    3.1.2 MPI programs 86

    3.1.3 MPI Init and MPI Finalize 86

    3.1.4 Communicators, MPI Comm size and MPI Comm rank 87

    3.1.5 SPMD programs 88

    3.1.6 Communication 88

    3.1.7 MPI Send 88

    3.1.8 MPI Recv 90

    3.1.9 Message matching 91

    3.1.10 The status p argument 92

    3.1.11 Semantics of MPI Send and MPI Recv 93

    3.1.12 Some potential pitfalls 94

    3.2 The Trapezoidal Rule in MPI 94

    3.2.1 The trapezoidal rule 94

    3.2.2 Parallelizing the trapezoidal rule 96

    Contents xiii

    3.3 Dealing with I/O 97

    3.3.1 Output 97

    3.3.2 Input 100

    3.4 Collective Communication101

    3.4.1 Tree-structured communication 102

    3.4.2 MPI Reduce 103

    3.4.3 Collective vspoint-to-point communications 105

    3.4.4 MPI Allreduce 106

    3.4.5 Broadcast 106

    3.4.6 Data distributions 109

    3.4.7 Scatter 110

    3.4.8 Gather 112

    3.4.9 Allgather 113

    3.5 MPI Derived Datatypes 116

    3.6 Performance Evaluation of MPI Programs119

    3.6.1 Taking timings 119

    3.6.2 Results 122

    3.6.3 Speedup and efficiency 125

    3.6.4 Scalability 126

    3.7 A Parallel Sorting Algorithm 127

    3.7.1 Some simple serial sorting algorithms 127

    3.7.2 Parallel odd-even transposition sort 129

    3.7.3 Safety in MPI programs 132

    3.7.4 Final details of parallel odd-even sort 134

    3.8 Summary 136

    3.9 Exercises 140

    3.10 Programming Assignments 147

    CHAPTER 4 Shared-Memory Programming with Pthreads 151

    4.1 Processes, Threads, and Pthreads 151

    4.2 Hello, World 153

    4.2.1 Execution 153

    4.2.2 Preliminaries 155

    4.2.3 Starting the threads 156

    4.2.4 Running the threads 157

    4.2.5 Stopping the threads 158

    4.2.6 Error checking 158

    4.2.7 Other approaches to thread startup159

    4.3 Matrix-Vector Multiplication 159

    4.4 Critical Sections 162

    xiv Contents

    4.5 Busy-Waiting 165

    4.6 Mutexes 168

    4.7 Producer-Consumer Synchronization and Semaphores171

    4.8 Barriers and Condition Variables 176

    4.8.1 Busy-waiting and a mutex 177

    4.8.2 Semaphores 177

    4.8.3 Condition variables 179

    4.8.4 Pthreads barriers 181

    4.9 Read-Write Locks 181

    4.9.1 Linked list functions 181

    4.9.2 A multi-threaded linked list 183

    4.9.3 Pthreads read-write locks 187

    4.9.4 Performance of the various implementations 188

    4.9.5 Implementing read-write locks 190

    4.10 Caches, Cache Coherence, and False Sharing 190

    4.11 Thread-Safety 195

    4.11.1 Incorrect programs can produce correct output

    展开全文
  • C++并行程序设计

    2018-09-08 18:32:02
    C++并行程序设计 仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
  • 第一个分太高了要50,过分,通过阅读和学习,读者可以掌握基于多种平台(多核、多处理器、集群和GPU等),利用多项技术(Matlab并行计算工具箱、多线程MEX文件、OpenMP和GPU等),学习理解Matlab并行程序设计的原理、...
  • 并行程序设计导论> 一些笔记与思考 ,后续基本都会同步到知乎~这两天重新看了《并行程序设计导论》,以前看过编程范式里的一些泛型编程,对于编程模型有些浅薄的思路,趁机记录一下。有经验的大神可以直接跳到第...

    3eca8faff91ac47d5890c04221ac0b18.png

    个人blog原址:<并行程序设计导论> 一些笔记与思考 ,后续基本都会同步到知乎~

    这两天重新看了《并行程序设计导论》,以前看过编程范式里的一些泛型编程,对于编程模型有些浅薄的思路,趁机记录一下。有经验的大神可以直接跳到第四部分看看本鶸的一些思路。


    一、背景介绍

    计算机比较原始的三大领域:存储通讯计算

    几年前老大做了分布式存储,去年做了异步通信,最近他要做并行计算了。

    于是我上周学着以前做过的MIT 6.824课设的做法给做了个demo,老大不满意,说这个模型不希望上来就考虑存储,要把最抽象的语义提炼出来。我想了想,这其实就是hadoop与MPI的关系。

    同样作为分布式框架,MPI的想法是计算和存储分离的,而hadoop因为有hdfs,所以属于计算向存储的迁移。可以说后者是前者的演进,但是MPI更为通用。

    我们的workflow里的算法工厂一直秉承着这样的设计思想:所有基本算法任务都是符合通用算法的,进而在上面做行为派生。那么在我们想设计一类基本算法任务(比如排序、合并、归约),它的最小需求集是什么?

    带着这个问题我看着书写了如下笔记与思考。

    二、本书纲要

    我看的英文版,几大章节分别是:

    Chapter 1 Why Parallel Computing?

    Chapter 2 Parallel Hardware and Parallel Software

    Chapter 3 Distributed-Memory Programming with MPI

    Chapter 4 Shared-Memory Programming with Pthreads

    Chapter 5 Shared-Memory Programming with OpenMP

    Chapter 6 Parallel Program Development

    可以看到,并行计算可以按照内存中的并行或者分布式机器上的并行进行划分。本书介绍的pthreads,OpenMP,还有先前从入门到放弃的cuda编程都是属于前者,而MPI hadoop spark都属于后者。

    第六章里有非常实用的例子是分别用这两种类型的编程思想去拆解n体问题和树型搜索问题。

    三、MPI基本笔记

    1. 启动

    MPI是纯数据消息传递的,所有节点执行相同的代码,由执行时附带的参数来指定全局个数:

    // 编译由mpicc为C编译器包了一层
    mpicc -g -Wall -o mpi_hello mip_hello.o
    
    // 起4个一样的程序作为一个小并行集群
    mpiexec -n 4 ./mpi_hello
    

    并行的语句都会写在MPI_Init(&argc, &argv)MPI_Finalize()之间。

    2. Communicator

    既然是基于消息传递,MPI_Comm就很重要了,它是内部的通信器,从它那可以那到全局整体个数comm_sz和自己是第几个的my_rank,全局Communicator可以通过MPI_COMM_WORLD拿到。my_rank范围是0 ~ comm_sz - 1。

    3. Send and Recv

    直接看两个程序如何做收发:

    // called by process q
    MPI_Send(send_buf_p, send_buf_sz, send_type, dest, send_tag, send_comm);
    
    // called by process r
    MPI_Recv(recv_buf_p, recv_buf_sz, recv_type, src, recv_tag, recv_comm, &status);
    

    则q发送r可以收到的条件至少满足:

    • recv_comm == send_comm
    • recv_tag == send_tag
    • dest == r
    • src == q

    收发消息的语义上两个重要的点:

    1. 点到点之间的消息保序,但是全局不保序。(这个最简单的做法大概是每个点之间建立一个连接就可以了,如果要连接池,则对同一个target要分配一个队列去管理来做到保序)
    2. MPI_Send()包括了bufferblock模式,应该就是我们的非阻塞与阻塞模式,而MPI_Recv()则总是等着的,所以这对于用户的编程要求其实很高,当然灵活度也很高,即你可能因为Recv不到东西而hang住,或者Send的东西没人收而会丢失。

    4. collective communication

    点对点发送只是一种简单的模式,还有没有其他模式呢?collective communication就是了。不太好翻译这个应该叫什么,意思是所有人都要参与计算、并最终由一个人去收集的通信模式(相比之下,send-recv的模式是point-to-point)。感觉现在才正式进入并行计算的用法。

    我们先借用我们最熟悉的归约来做详解:

    int MPI_Reduce(
        void *          input_data_p,
        void *          output_data_p,
        int             count,
        MPI_Datatype    data_type,       // MPI内部的char,int之类
        MPI_Op          operator,        // 内部提供了MAX SUM,还可以自行派生实现
        int             dest_process,    // 大家计算完发给一个人去收集
        MPI_Comm        communicator
    );
    

    一些特点:

    • 所有人都调用同样的collective函数(比如不能有人在这一步做reduce有人做recv);
    • 所有人指定的这一轮的收集者必须是同一个;
    • 虽然只有收集的那个人需要output,但大家都要传;
    • send-recv模式有tag去指定,而collective communication没有,所以这里是通过communicator来寻找collect的节点们的对应关系的,并通过函数调用的顺序(而非参数本身)来决定结果。

    其他类似的api还有:

    MPI_Allreduce(): 这个跟reduce比没有dest_process,即每个人都可以收集结果数据;

    MPI_Bcast(): 参数只有input,没有output,顾名思义,把input发给所有人;

    5. data distribution

    这个有点类似我们做cuda编程时的分thread、分block概念,对于一份数据,我们必须很清晰它可以如何被并行处理,分块方式有block partitioncyclic partitionblock-cyclic partition,概念很简单不细介绍,重点介绍下这个api,可以自动为我们把数据分comm_sz份分发:

    int MPI_Scatter(
        void*           send_buf_p,
        int             send_count,     // 这个send_count可以不被comm_sz整除
        MPI_Datatype    send_type,
        void*           recv_buf_p,
        int             recv_count,
        MPI_Datatype    recv_type,
        int             src_process,    // 由哪号节点分发
        MPI_Comm        comm
    );
    

    与之对称的功能就是MPI_Gather()了,对应的参数时dest_process,指定由哪个节点做收集。通过buf数组的索引可以拿到具体的要分发给某个节点/来自某个节点的数据。

    四、一些想象

    第三章的重要概念就介绍完了,以下是我基于这些外层所想象的一些实现,这些思考不一定都是对的。

    1. communicator通信管理

    这个communicator看上去可以得知所有节点的ip:port,有点像侵入式的服务发现,mpi自身是个框架很容易做这个事情,类似于workflow的client端的upstream。

    2. MPI_Send()/MPI_Recv()的错误处理

    对用户的编程要求是比较高的,但是框架可以做一些事情来发现Send的数据没人收或者等在Recv上卡住的事情。对于workflow来说可以是接收时设置receive_timeout,send没人接收更简单,错误会在callback()返回给用户。再长远点来说,如果我们接管了语言层面,或许还可以在用户编译阶段画出DAG提前分析出这样的错误情况。

    3. DAG

    其实所有的计算步骤都是可以画成DAG的,从DAG的依赖上就很清楚可以看出哪些步骤可以并行。workflow现在的异步任务调度也是通用的道理,只是目前只能算shared-memory的parallel programming,所以才需要进一步提取像MPI这样的接口来为用户封装更抽象的并行计算模型。

    4. 泛型编程

    以前看过一系列泛型编程的文章,提到C++对于泛型的进一步抽象,与MPI面对的问题是比较像的,另外加上google的mapreduce的paper也提到过。我在此总结了下是包括这三点:迭代器、operator、归约函数

    举个例子,以上的MPI_Reduce中接口都可以这样映射到C++中实现:

    template<class DATA_ITERATOR, class DATA_TYPE, class OPERATOR>
    int cpp_reduce(DATA_ITERATOR i_begin,      // 由于数据不一定是数组遍历,
                   DATA_ITERATOR i_end,        // 所以需要input_data的迭代器begin和end
                   DATA_ITERATOR o_begin,
                   /* DATA_ITERATOR o_end, */
                   DATA_TYPE data_default,     // 基本的数据初始化类型
                   OPERATOR op,                // 基本的MAX SUM,也可以自定义
                   int dest_process,           // 大家计算完发给一个人去收集
                   Communicator *comm)
    {
        DATA_TYPE data = data_default;
        DATA_ITERATOR in_iter = i_begin;
        DATA_ITERATOR out_iter = o_begin;
    
        while (in_iter != i_end)
        {
            data = op(*in_iter);
            if (data == data_default)
                return -1;
    
            *out_iter = std::move(data);
            out_iter++;
            in_iter++;
        }
    
        return comm->send(dest_process, o_begin, out_iter);
    }
    
    // 对比看下
    int MPI_Reduce(
        void *          input_data_p,
        void *          output_data_p,
        int             count,
        MPI_Datatype    data_type,       // MPI内部的char,int之类
        MPI_Op          operator,        // 内部提供了MAX SUM,还可以自行派生实现
        int             dest_process,    // 大家计算完发给一个人去收集
        MPI_Comm        communicator
    );
    

    这么写完发现MPI有些接口是不太通用的,比如input_data和output_data的类型和个数都必须一致。这些在我们做自己的算法任务时必须去想清楚。

    五、最后

    事实进一步证明,欠下的技术债迟早都要还。这本书印象很深刻三年前就很喜欢,去夏威夷旅游的时候还非要带在身边,然而根本没有消化。其实这本书对于三年前的我来说还是太抽象了。

    现在我比较适合看的书,必须能有一些定义引领我的思路,然后最重要是不要太具体,能给我留有充分的想象空间,让我去思考现有的东西如何实现,或者我是否还需要开发新的东西去实现这样的模型/机制。而这本书现在看就正正好。昨晚看了一宿兴奋得没睡。最近杂事多,只能草草记录。希望最近能抓紧把这本书消化完,充分想象并行计算。

    展开全文
  • 高性能计算并行编程技术MPI并行程序设计
  • 基于Fortran语言的并行程序设计例子,可以用于课程报告参考,期末考试复习以及理解Fortran语言下的并行程序优化。
  • MPI并行程序设计

    2020-04-15 19:48:26
    MPI并行程序设计 MPI并行程序设计,与其说是语言不如说是一个库 直接上一个MPI比较权威的资料,值得大家学习 链接: [link](链接:https://pan.baidu.com/s/1o5yB10JadQlM6RsatIVvSw 密码:s7bu). ...

    MPI并行程序设计

    MPI并行程序设计,与其说是语言不如说是一个库
    直接上一个MPI比较权威的资料,值得大家学习

    链接: [link](链接:https://pan.baidu.com/s/1o5yB10JadQlM6RsatIVvSw 密码:s7bu).

    展开全文
  • 实战MATLAB之并行程序设计

    热门讨论 2014-11-17 11:44:05
    实战MATLAB之并行程序设计
  • OpenMP并行程序设计

    2019-09-30 21:08:04
    1、fork/join并行执行模式的概念 2、OpenMP指令和库函数介绍 ... OpenMP是一个编译器指令和库函数的集合,主要是为共享式存储计算机上的并行程序设计使用的。 前面一篇文章中已经试用了Open...


    1、fork/join并行执行模式的概念

    2、OpenMP指令和库函数介绍

    3、parallel 指令的用法

    4、for指令的使用方法

    5 sections和section指令的用法

    1、fork/join并行执行模式的概念

    OpenMP是一个编译器指令和库函数的集合,主要是为共享式存储计算机上的并行程序设计使用的。

    前面一篇文章中已经试用了OpenMP的一个Parallel for指令。从上篇文章中我们也可以发现OpenMP并行执行的程序要全部结束后才能执行后面的非并行部分的代码。这就是标准的并行模式fork/join式并行模式,共享存储式并行程序就是使用fork/join式并行的。

    标准并行模式执行代码的基本思想是,程序开始时只有一个主线程,程序中的串行部分都由主线程执行,并行的部分是通过派生其他线程来执行,但是如果并行部分没有结束时是不会执行串行部分的,如上一篇文章中的以下代码:

    int main(int argc, char* argv[])

    {

         clock_t t1 = clock();

    #pragma omp parallel for

    for ( int j = 0; j < 2; j++ ){

             test();

         }

         clock_t t2 = clock();

         printf("Total time = %d\n", t2-t1);

         test();

    return 0;

    }

    在没有执行完for循环中的代码之前,后面的clock_t t2 = clock();这行代码是不会执行的,如果和调用线程创建函数相比,它相当于先创建线程,并等待线程执行完,所以这种并行模式中在主线程里创建的线程并没有和主线程并行运行。

    2、OpenMP指令和库函数介绍

    下面来介绍OpenMP的基本指令和常用指令的用法,

    在C/C++中,OpenMP指令使用的格式为

    #pragma omp 指令 [子句[子句]…]

    前面提到的parallel for就是一条指令,有些书中也将OpenMP的“指令”叫做“编译指导语句”,后面的子句是可选的。例如:

    #pragma omp parallel private(i, j)

    parallel 就是指令, private是子句

    为叙述方便把包含#pragma和OpenMP指令的一行叫做语句,如上面那行叫parallel语句。

    OpenMP的指令有以下一些:

    parallel,用在一个代码段之前,表示这段代码将被多个线程并行执行

    for,用于for循环之前,将循环分配到多个线程中并行执行,必须保证每次循环之间无相关性。

    parallel for, parallel 和 for语句的结合,也是用在一个for循环之前,表示for循环的代码将被多个线程并行执行。

    sections,用在可能会被并行执行的代码段之前

    parallel sections,parallel和sections两个语句的结合

    critical,用在一段代码临界区之前

    single,用在一段只被单个线程执行的代码段之前,表示后面的代码段将被单线程执行。

           flush,

    barrier,用于并行区内代码的线程同步,所有线程执行到barrier时要停止,直到所有线程都执行到barrier时才继续往下执行。

    atomic,用于指定一块内存区域被制动更新

    master,用于指定一段代码块由主线程执行

    ordered, 用于指定并行区域的循环按顺序执行

    threadprivate, 用于指定一个变量是线程私有的。

    OpenMP除上述指令外,还有一些库函数,下面列出几个常用的库函数:

    omp_get_num_procs, 返回运行本线程的多处理机的处理器个数。

    omp_get_num_threads, 返回当前并行区域中的活动线程个数。

    omp_get_thread_num, 返回线程号

    omp_set_num_threads, 设置并行执行代码时的线程个数

    omp_init_lock, 初始化一个简单锁

    omp_set_lock, 上锁操作

    omp_unset_lock, 解锁操作,要和omp_set_lock函数配对使用。

    omp_destroy_lock, omp_init_lock函数的配对操作函数,关闭一个锁

    OpenMP的子句有以下一些

    private, 指定每个线程都有它自己的变量私有副本。

    firstprivate,指定每个线程都有它自己的变量私有副本,并且变量要被继承主线程中的初值。

    lastprivate,主要是用来指定将线程中的私有变量的值在并行处理结束后复制回主线程中的对应变量。

    reduce,用来指定一个或多个变量是私有的,并且在并行处理结束后这些变量要执行指定的运算。

    nowait,忽略指定中暗含的等待

    num_threads,指定线程的个数

    schedule,指定如何调度for循环迭代

    shared,指定一个或多个变量为多个线程间的共享变量

    ordered,用来指定for循环的执行要按顺序执行

    copyprivate,用于single指令中的指定变量为多个线程的共享变量

    copyin,用来指定一个threadprivate的变量的值要用主线程的值进行初始化。

    default,用来指定并行处理区域内的变量的使用方式,缺省是shared

    3、parallel 指令的用法

    parallel 是用来构造一个并行块的,也可以使用其他指令如for、sections等和它配合使用。

    在C/C++中,parallel的使用方法如下:

    #pragma omp parallel [for | sections] [子句[子句]…]

    {

           //代码

    }

    parallel语句后面要跟一个大括号对将要并行执行的代码括起来。

    void main(int argc, char *argv[]) {

    #pragma omp parallel

    {

                  printf(“Hello, World!\n”);

    }

    }

    执行以上代码将会打印出以下结果

    Hello, World!

    Hello, World!

    Hello, World!

    Hello, World!

    可以看得出parallel语句中的代码被执行了四次,说明总共创建了4个线程去执行parallel语句中的代码。

    也可以指定使用多少个线程来执行,需要使用num_threads子句:

    void main(int argc, char *argv[]) {

    #pragma omp parallel num_threads(8)

    {

                  printf(“Hello, World!, ThreadId=%d\n”, omp_get_thread_num() );

    }

    }

    执行以上代码,将会打印出以下结果:

    Hello, World!, ThreadId = 2

    Hello, World!, ThreadId = 6

    Hello, World!, ThreadId = 4

    Hello, World!, ThreadId = 0

    Hello, World!, ThreadId = 5

    Hello, World!, ThreadId = 7

    Hello, World!, ThreadId = 1

    Hello, World!, ThreadId = 3

    从ThreadId的不同可以看出创建了8个线程来执行以上代码。所以parallel指令是用来为一段代码创建多个线程来执行它的。parallel块中的每行代码都被多个线程重复执行。

    和传统的创建线程函数比起来,相当于为一个线程入口函数重复调用创建线程函数来创建线程并等待线程执行完。

    4、for指令的使用方法

    for指令则是用来将一个for循环分配到多个线程中执行。for指令一般可以和parallel指令合起来形成parallel for指令使用,也可以单独用在parallel语句的并行块中。

    #pragma omp [parallel] for [子句]

    for循环语句

    先看看单独使用for语句时是什么效果:

    int j = 0;

    #pragma omp for

    for ( j = 0; j < 4; j++ ){

             printf(“j = %d, ThreadId = %d\n”, j, omp_get_thread_num());

         }

    执行以上代码后打印出以下结果

    j = 0, ThreadId = 0

    j = 1, ThreadId = 0

    j = 2, ThreadId = 0

    j = 3, ThreadId = 0

    从结果可以看出四次循环都在一个线程里执行,可见for指令要和parallel指令结合起来使用才有效果:

    如以下代码就是parallel 和for一起结合成parallel for的形式使用的:

    int j = 0;

    #pragma omp parallel for

    for ( j = 0; j < 4; j++ ){

             printf(“j = %d, ThreadId = %d\n”, j, omp_get_thread_num());

         }

    执行后会打印出以下结果:

    j = 0, ThreadId = 0

    j = 2, ThreadId = 2

    j = 1, ThreadId = 1

    j = 3, ThreadId = 3

    可见循环被分配到四个不同的线程中执行。

    上面这段代码也可以改写成以下形式:

    int j = 0;

    #pragma omp parallel

    {

    #pragma omp for

    for ( j = 0; j < 4; j++ ){

             printf(“j = %d, ThreadId = %d\n”, j, omp_get_thread_num());

         }

    }

    执行以上代码会打印出以下结果:

    j = 1, ThreadId = 1

    j = 3, ThreadId = 3

    j = 2, ThreadId = 2

    j = 0, ThreadId = 0

    在一个parallel 块中也可以有多个for语句,如:

    int j;

    #pragma omp parallel

    {

    #pragma omp for

    for ( j = 0; j < 100; j++ ){

         }

    #pragma omp for

    for ( j = 0; j < 100; j++ ){

         }

    }

    for 循环语句中,书写是需要按照一定规范来写才可以的,即for循环小括号内的语句要按照一定的规范进行书写,for语句小括号里共有三条语句

    for( i=start; i < end; i++)

    i=start; 是for循环里的第一条语句,必须写成 “变量=初值” 的方式。如 i=0

    i < end;是for循环里的第二条语句,这个语句里可以写成以下4种形式之一:

    变量 < 边界值

    变量 <= 边界值

    变量 > 边界值

    变量 >= 边界值

    如 i>10 i< 10   i>=10 i>10 等等

    最后一条语句i++可以有以下9种写法之一
    i++

    ++i

    i--

    --i

    i += inc

    i -= inc

    i = i + inc

    i = inc + i

    i = i –inc

    例如i += 2; i -= 2;i = i + 2;i = i - 2;都是符合规范的写法。

    5 sections和section指令的用法

    section语句是用在sections语句里用来将sections语句里的代码划分成几个不同的段,每段都并行执行。用法如下:

    #pragma omp [parallel] sections [子句]

    {

       #pragma omp section

       {

    代码块

       }

    }

    先看一下以下的例子代码:

    void main(int argc, char *argv)

    {

    #pragma omp parallel sections {

    #pragma omp section

        printf(“section 1 ThreadId = %d\n”, omp_get_thread_num());

    #pragma omp section

        printf(“section 2 ThreadId = %d\n”, omp_get_thread_num());

    #pragma omp section

        printf(“section 3 ThreadId = %d\n”, omp_get_thread_num());

    #pragma omp section

        printf(“section 4 ThreadId = %d\n”, omp_get_thread_num());

    }

    执行后将打印出以下结果:

    section 1 ThreadId = 0

    section 2 ThreadId = 2

    section 4 ThreadId = 3

    section 3 ThreadId = 1

    从结果中可以发现第4段代码执行比第3段代码早,说明各个section里的代码都是并行执行的,并且各个section被分配到不同的线程执行。

    使用section语句时,需要注意的是这种方式需要保证各个section里的代码执行时间相差不大,否则某个section执行时间比其他section过长就达不到并行执行的效果了。

    上面的代码也可以改写成以下形式:

    void main(int argc, char *argv)

    {

    #pragma omp parallel {

    #pragma omp sections

    {

    #pragma omp section

           printf(“section 1 ThreadId = %d\n”, omp_get_thread_num());

    #pragma omp section

           printf(“section 2 ThreadId = %d\n”, omp_get_thread_num());

    }

    #pragma omp sections

    {

    #pragma omp section

           printf(“section 3 ThreadId = %d\n”, omp_get_thread_num());

    #pragma omp section

           printf(“section 4 ThreadId = %d\n”, omp_get_thread_num());

    }

    }

    执行后将打印出以下结果:

    section 1 ThreadId = 0

    section 2 ThreadId = 3

    section 3 ThreadId = 3

    section 4 ThreadId = 1

    这种方式和前面那种方式的区别是,两个sections语句是串行执行的,即第二个sections语句里的代码要等第一个sections语句里的代码执行完后才能执行。

    用for语句来分摊是由系统自动进行,只要每次循环间没有时间上的差距,那么分摊是很均匀的,使用section来划分线程是一种手工划分线程的方式,最终并行性的好坏得依赖于程序员。

    本篇文章中讲的几个OpenMP指令parallel, for, sections, section实际上都是用来如何创建线程的,这种创建线程的方式比起传统调用创建线程函数创建线程要更方便,并且更高效。

    当然,创建线程后,线程里的变量是共享的还是其他方式,主线程中定义的变量到了并行块内后还是和传统创建线程那种方式一样的吗?创建的线程是如何调度的?等等诸如此类的问题到下一篇文章中进行讲解。

     

    转载于:https://www.cnblogs.com/fuhaots2009/p/3473094.html

    展开全文
  • 并行程序设计导论
  • 2018年东北大学并行程序设计试题 供大家复习参考 瑟瑟发抖
  • 并行程序设计导论 基本术语 (Basic Terminology) Before we start the technicalities of our topic, let us understand some very basics. 在开始本主题的技术介绍之前,让我们了解一些非常基础的知识。 What is ...
  • 2018年东北大学并行程序设计真题,供大家参考-
  • 并行程序设计的入门之作, 大概从入门到中级的水平, 包括了 Pthread, OpenMP, MPI. 英文版和随书示例代码
  • MPI与OpenMP并行程序设计中文电子书,讲得很不错
  • 并行程序设计 假期突然延长,为了不荒废人生,决定趁这两天补一下课,把之前没有修过的并行与分布式计算补习一下。 这门课主要教了MPI, Pthread, OpenMP和CUDA,内容围绕着并行计算和高性能计算展开,比较繁杂,知识...
  • CUDA并行程序设计:GPU编程指南共分为12章。 第1章 超级计算简史 第2章 使用GPU理解并行计算 第3章 CUDA硬件概述 第4章 CUDA环境搭建 第5章 线程网格、线程块以及线程 第6章 CUDA内存处理 第7章 CUDA实践之道 ...
  • 并行程序设计模型

    千次阅读 2016-07-04 21:28:50
    并行程序设计模型 并行程序设计模型(Parallel Program Model)是一种程序抽象的集合,是建立在硬件和内存体系结构层次之上的概念[26]。比较常用的模型有:数据并行模型、消息传递模型和共享存储模型。 数据并行...
  • 并行程序设计模式

    2017-08-15 14:45:23
    并行程序设计模式一般有Future模式、Master-Slave模式、保护暂停模式、不变模式、生产者/消费者模式等。1. Future模式Future模式有点类似商品订单。比如在进行网上购物时,当看中某一件商品时,就可以提交订单。当...
  • CUDA并行程序设计 GPU编程指南 PDF 中文 完整 高清扫描 + 英文版
  • 本书对基于Matlab 的并行程序设计的原理进行了深入的剖析,并结合各章给出的大量实例对基于Mat—lab 的并行计算程序设计方法和技巧给出了详细的说明。通过阅读和学习本书的内容,读者可以掌握基于多种平台(多核、多...
  • 实战Matlab之并行程序设计pdf及其代码
  • “高性能计算之并行编程技术 —— MPI并行程序设计”是天河二号官方高性能编程指导性文档,对于天河二号的使用者来说,可能有一定的帮助。
  • 《实战Matlab之并行程序设计》通过阅读和学习,读者可以掌握基于多种平台(多核、多处理器、集群和GPU等),利用多项技术(Matlab并行计算工具箱、多线程MEX文件、OpenMP和GPU等),学习理解Matlab并行程序设计的原理、...
  • 并行程序设计入门

    千次阅读 2018-04-14 12:47:46
    来自教材《并行程序设计导论》 mpi的helloworld程序 //test3_1.c #include #include string.h> #include const int MAX_STRING = 100; int main(void){ char greeting[MAX_STRING]; int comm_sz; int my_...
  • 中科大并行程序设计作业答案

    热门讨论 2012-10-16 23:14:44
    中国科学技术大学并行程序设计作业答案 并行编译部分

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,063
精华内容 2,025
关键字:

并行程序设计