openmp学习

来源:互联网 发布:starry nigh观星软件 编辑:程序博客网 时间:2024/05/29 04:47

一、如何配置openmp的使用环境

1.windows vs2013下如何使用可参考博客基于OpenMP的并行编程
2.ubuntu Qt下使用可参考博客 Qt编写OpenMP程序–HelloWorld
记得在头文件包含该omp.h

二、openmp学习的几点注意事项

1.缺省情况下,任何在循环前声明的变量,在线程间都是共享的。为了消除这种循环依赖关系之外,可以通过添加private子句到parallel指令中来实现这一目标。
2.关于计时函数,openmp有自己的计时函数omp_get_wtime(),标准c的计时函数为clock(),这两个函数表达的含义不同:
(1)在vs2013下测试,测试时两者用时基本一致;
(2)在ubuntu Qt5.7 下测试omp_get_wtime()为并行化的用时,clock()为各个核心计算用时之和(一般约为并行线程个数与omp_get_wtime()乘积)。

openmp语法学习

1.英文好的同学直接去openmp官网,这里信息全、新、准。
2.我在学习过程中首先参考了以下中文博客openmp学习、OpenMP共享内存并行编程详解、openmp学习笔记,在此一并谢过。
3.具体语法学习
编译器指令用以告诉编译器哪一段代码需要并行,所有的OpenMP编译器指令都以#pragma omp开始。就像其它编译器指令一样,在编译器不支持这些特征的时候OpenMP指令将被忽略。#pragma omp [clause,[[,]clause…]对directive(指令)而言clause(子句)是可选的,但子句可以影响到指令的行为。每一个指令有一系列适合它的子句,但有5个指令(master、cirticle、flush、ordered和atomic)不能使用子句。
(1) 获得处理器个数:int coreNum = omp_get_num_procs();
(2)规约:reduction的语法为recutioin(operator:list)和其他的数据属性子句不一样的是多了一个operator参数。由于最后会进行迭代运算,所以不是所有的运算符都能作为reduction的参数,而且,迭代运算需要一个初始值,不是所有的操作符需要有相同的初始值,一般而言,常见的reduction操作符的初始值为:+(0),*(1),-(0),&~(0),|(0),^(0),&&(1),||(0)另外reduction只能用于标量类型(int、float等等)

#pragma omp parallel for reduction(+:sum)      for (int i=0;i<10;i++)              sum = sum + a[i]; 

(3)critical子句: 用#pragm omp critical 将if (temp>max) max = temp括起来,它的意思是:各个线程还是并行执行for里面的语句,但当执行到critical里面时,要注意有没有其他线程正在里面执行,如果有的话,要等其他线程执行完再去执行。这样就避免了race condition问题,但显而易见,它的执行速度会变低,因为可能存在线程等待的情况

 int max = 0;      int a[10] = {11,2,33,49,113,20,321,250,689,16};  #pragma omp parallel for      for (int i=0;i<10;i++)      {          int temp = a[i];  #pragma omp critical          {              if (temp > max)                  max = temp;          }      }      std::cout<<"max: "<<max<<std::endl;

(4)

几点感想

1.数据竞态问题:当使用#pragm omp parallel for后,自动将下面的for循环分成N份(N为CPU核数),然后把每份指派给一个核去执行,而且多核之间并行执行。

原创粉丝点击