• C++ -- OpenMP 笔记


    @toc

    OMP

    CMake Setup

    set(CMAKE_CXX_STANDARD 14)
    set(CMAKE_CXX_STANDARD_REQUIRED ON)
    find_package(OpenMP REQUIRED)
    
    # Set Flags
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    
    # Header Path
    include_directories(
        ${OpenMP_CXX_INCLUDE_DIRS}
    )
    
    # Link 
    target_link_libraries(target ${OpenMP_CXX_LIBRARIES})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    Directive

    openmp 代码段的起始符号

    #pragma omp directive-name [clause[ [,] clause]...] new-line
    
    • 1
    • directive-name 只能有一个;
    • directive 只作用后面一行(或者一个代码块)的代码。
    • directive 可以嵌套。

    directive-name 选择:

    1. parallel
    #pragma omp parallel [clause[ [, ]clause] ...] new-line 
    	structured-block
    
    • 1
    • 2

    structured-block 中的代码会被并行执行;

    但是并不代表 block 中的代码会被执行 N 次。针对 for loop 会被执行循环次数;针对 sections 只会执行一次。

    1. for
    #pragma omp for [clause[[,] clause] ... ] new-line 
    	for-loop
    
    • 1
    • 2

    for 属于 Work-sharing Constructs,本身并不会启动新的线程,只是将后续的代码分配到不同的线程;因此需要在 parallel 环境下使用。

    for-loop 需要采用最普遍的写法 — for(int i = 0; i < 100; i++)

    for 循环的末尾默认有一个 barrier (保证所有线程同时结束并入主线程),除非 clause 包含 nowait

    1. parallel for

    clause 包含前两者的 clause,除了 nowait

    #pragma omp parallel for [clause[[,] clause] ...] new-line 
    	for-loop
    
    • 1
    • 2
    1. parallel sections & section

    section 之间是并行的。但是 sections 后的代码块只执行一次

    #pragma omp parallel sections
       {
    	[#pragma omp section new-line
    		structured-block]
    	
    	[#pragma omp section new-line
    		structured-block]
    	... 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    1. single & master & critical & atomic

    single 后的代码块只被分配到一个线程(不一定是主线程),只执行一次。

    master 后的代码块被分配到主线程。( single 特殊形式)

    critical 后的代码块同一时间只有一个在执行。

    atomic 后的代码块中访问的内存同一时间只暴露给一个线程。

    部分编译器会把 atomic 当作 critical 处理,但是两者是有细微差别的。在进行原子操作时,atomic 的优化会比 critical 更好。

    1. barrier & flush

      • barrier 同步所有线程;

      • flush:同步数据:CPU 将寄存器中的值写回内存,保证数据一致。

    #pragma omp flush [(variable-list)] new-line
    
    • 1

    variable-list 为空,则等同于 barrier;

    1. ordered

    ordered 必须和 for 使用;ordered 后的代码块会按照 for 循环中的顺序执行。

    同时 for 后的 clause 中需要有 ordered

    共享数据与私有数据

    部分 directive 允许用户通过 clause 更改后续代码块中变量的属性。这些改变仅在后续代码块中生效。当一个变量在 Construct 构建时是可见的,如果它既没有在 shared 也没有在 threadprivate 中出现,那么则是 shared。动态申请的(堆中的)内存是 shared (但是指针变量不一定是)。代码块中定义的变量是 private

    • shared clause

    • private clause:

    每个线程都会调用默认构造函数构造一个相同类的实例。

    • copyin clause:

    会将主线程中的对象复制到线程的私有变量中。

  • 相关阅读:
    Python编程基础:列表的正确使用
    RabbitMQ初步到精通-第六章-RabbitMQ之死信队列
    win系统安装sql server报错,已经安装了Visual C++ 2017 Redistributable,也是以系统管理员身份运行
    Spring IoC Container 原理解析
    探秘Nutch:揭秘开源搜索引擎的工作原理与无限应用可能(二)
    java学习day53-54(SSM)SSM权限操作
    【系统设计与实现】基于flink的分心驾驶预测与数据分析系统
    Day 21:C++STL算法篇(2/2)
    【正点原子STM32连载】 第四十三章 SPI实验 摘自【正点原子】APM32F407最小系统板使用指南
    【MySQL —— 事务】四大特性、隔离级别
  • 原文地址:https://blog.csdn.net/lib0000/article/details/128010210