并行计算 Clion配置使用OpenMP

文章目录

  • 配置CMakeList.txt文件
  • OpenMP之HelloWorld
  • 数据共享属性
    • shared子句
    • private子句
    • default子句
      • default(shared)
      • default(none)

配置CMakeList.txt文件

文件底部加入以下内容,即可支持OpenMP

FIND_PACKAGE(OpenMP REQUIRED)
if (OPENMP_FOUND)
    message("OPENMP FOUND")
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif ()

参考链接:openmp基本使用

OpenMP之HelloWorld

#include 
#include "omp.h"
using namespace std;
int main() {
    //设置线程数,一般设置的线程数不超过CPU核心数,这里开3个线程执行并行代码段
    omp_set_num_threads(3);
#pragma omp parallel
    {
        printf("hello, I am Thread %d\n", omp_get_thread_num());
    }
}

注意:

  • #pragma后 “{” 一定要换行。
  • 使用printf来避免输出混乱(cout流输出会造成输出混乱)

在这里插入图片描述在这里插入图片描述
可以看到,多线程执行,导致输出不确定。

数据共享属性

openmp并行区域中的变量可以是共享的,也可以是私有的

  • 如果一个变量是共享的,那么这个变量存在一个实例,在所有线程之间共享。请始终记住共享变量会产生额外的开销。 因此当需要良好的性能时,通常最好尽量减少共享变量的数量。
  • 如果一个变量是私有的,那么线程组中的每个线程都有自己的私有变量的本地副本。

另外,openmp有一套规则,当变量的属性没有被声明的时候,可以推断变量的数据共享属性。

  • 在并行区域之外声明的变量的数据共享属性通常是共享的,因此n和a是共享变量。
  • 循环迭代变量默认情况下是私有的,因此i是私有的。
  • 在平行区域内局部声明的变量是私有的,因此b是私有变量。
    并行计算 Clion配置使用OpenMP_第1张图片

shared子句

  • i,a都是parallel区域之外声明的变量,所以他们的数据共享属性是共享的。
  • 我们也可以使用shared子句,显式的声明变量的共享属性。
  • parallel区域内改变变量会对区域外的变量有影响。
#include 
#include "omp.h"
using namespace std;
int main() {
    int i = 0;
    float a = 512.3;
#pragma omp parallel //shared(a,n)
    {
        i = i + 1;
        printf("thread %d ,i = %d ,a= %lf\n", omp_get_thread_num(), i, a);
    }
    printf("out of parallel i = %d", i);
}

并行计算 Clion配置使用OpenMP_第2张图片
可以看到,parallel区域内改变i的值,区域外的i也被改变。证明他们是同一个i。

private子句

我们可以通过在并行区域内声明私有变量来避免在 openMP 结构中列出私有变量。最好尽可能在并行区域内声明私有变量,这条准则简化了代码并提高了可读性。

#include 
#include "omp.h"
using namespace std;
int main() {
    int i = 0;
    float a = 512.3;
#pragma omp parallel private(i,a)
    {
        i = i + 1;
        printf("thread %d ,i = %d ,a= %lf\n", omp_get_thread_num(), i, a);
    }
    printf("out of parallel i = %d", i);
}

并行计算 Clion配置使用OpenMP_第3张图片
区域内的变量被声明为private时,各线程内各自的变量都被随机初始化,而且和并行区域外部同名变量无关。

default子句

default(shared)

  • 默认并行区域内的变量都属于共享变量
  • 严重不建议使用default(shared),它只会令代码的阅读性非常差。

default(none)

default (none) 子句强制程序员明确指定所有变量的数据共享属性

你可能感兴趣的:(c++,c++,开发语言)