博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
1、OpenMP常用函数、parallel、for
阅读量:4171 次
发布时间:2019-05-26

本文共 5174 字,大约阅读时间需要 17 分钟。

基本思想:因为看NCNN源码,发现up主代码中,使用了OpenMP预编译指令,所以详细查阅了资料,先简单学习一下,等有时间在补充NCNN代码的中的实例,这里原理不详细叙述,只记录使用,以备后续用到好查阅;

个人感觉OpenMP 最难的问题在于如何把存在数据依赖的运算关系拆成相互独立的运算,进行并行加速,先把简单的记录一下,后期看大神代码 逐渐完善example吧~

编译工具使用Clion2021.1.1,因为使用OpenMP的主要目的在于加速处理指令,因此会着重比较一下串行程序和OpenMP并行程序的执行效率对比,有时间在补充OpenMP和多线程的执行效率对比

(1)OpenMP的常用的函数和使用:

测试代码:(cmakelists.txt不在重复黏贴)

cmake_minimum_required(VERSION 3.16)project(OpenMP)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp ")set(CMAKE_CXX_STANDARD 11)add_executable(OpenMP main.cpp)

测试代码

#include 
#include
using namespace std;int main() { std::cout<<"the current thread id: "<
<

结果:

F:\OpenMP\cmake-build-debug\OpenMP.exethe current thread id: 0the machine thread num: 1the current processer num: 12Process finished with exit code 0

测试显示:当前的代码运行的线程id=0,当前的代码仅用一个线程执行,本机总共有12个逻辑CPU

6核CPU,12个逻辑处理器 一颗内核在一个时间片内只能执行一个内核线程;当物理CPU使用了超线程技术后,在CPU的一颗内核中,利用就是利用其中空闲的执行单元,模拟出另外一个核心(并不是真正的物理运算核心),使得CPU的这颗内核有两个逻辑核心,也就是所谓的逻辑CPU,此时物理CPU的一颗内核在一个时间片内理论上可同时执行两个内核线程,从而提高了整个CPU的工作效率,此时逻辑CPU的数量=物理CPU的数量x单个CPU的内核数x2。值得注意的是,一颗内核并不代表只能有一个或者两个逻辑CPU,也可以有4个逻辑CPU或者更多。

(2)OpenMP的基本语法

基本语法为

#pragra omp parallel [for|sections]{.....//并行次数由PC的内核数决定}

大括号里面的语句按照本机所含有的线程数执行

#include 
#include
#include
using namespace std;using namespace chrono;void sequentialProgram(int num){ for(int i=0;i
(end_time-start_time).count()<<" seconds"<
(end_time-start_time).count()<<" seconds"<

结果可视,串行程序都在主线程id=0上执行,而OpenMP分别在0~11线程号上执行

F:\OpenMP\cmake-build-debug\OpenMP.exehello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0sequentialProgram elapse time: 0.024749 secondshello world the current thread id: 1hello world the current thread id: 0hello world the current thread id: 4hello world the current thread id: 11hello world the current thread id: 7hello world the current thread id: 3hello world the current thread id: 8hello world the current thread id: 6hello world the current thread id: 9hello world the current thread id: 10hello world the current thread id: 2hello world the current thread id: 5parallelProgram elapse time: 0.0278966 secondsProcess finished with exit code 0

(2)还可以指定线程数量,来运行代码

#pragma omp parallel num_threads(n){....}或者omp_set_num_threads(n);//设置环境变量#pragma omp parallel {....}

测试代码

#include 
#include
#include
using namespace std;using namespace chrono;void sequentialProgram(int num){ for(int i=0;i
(end_time-start_time).count()<<" seconds"<
(end_time-start_time).count()<<" seconds"<

运行结果,可以分析其线程号

F:\OpenMP\cmake-build-debug\OpenMP.exehello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0hello world the current thread id: 0threadProgram elapse time: 0.0622209 secondsA hello world the current thread id: 1A hello world the current thread id: 5A hello world the current thread id: 0A hello world the current thread id: 2A hello world the current thread id: 4A hello world the current thread id: 3B hello world the current thread id: 1B hello world the current thread id: 2B hello world the current thread id: 0C hello world the current thread id: 1C hello world the current thread id: 0parallelProgram elapse time: 0.0310061 secondsProcess finished with exit code 0

(3)随着次数num的测试增多,耗时会更明显 ,OpenMP效率明显更快

#pragma omp parallel forfor(int i=0;i

测试代码

#include 
#include
#include
using namespace std;using namespace chrono;void sequentialProgram(int num){ for(int i=0;i
(end_time-start_time).count()<<" seconds"<
(end_time-start_time).count()<<" seconds"<

测试结果,时间对比消耗

F:\OpenMP\cmake-build-debug\OpenMP.exesequentialProgram elapse time: 0.268991 secondsparallelProgram elapse time: 0.0172777 secondsProcess finished with exit code 0

(4)多个并行for指令处理

#pragma omp parallel{#pragma omp forfor(int i=0;i

测试代码

#include 
#include
#include
using namespace std;using namespace chrono;void sequentialProgram(int num){ for(int i=0;i
(end_time-start_time).count()<<" seconds"<
(end_time-start_time).count()<<" seconds"<

测试结果

F:\OpenMP\cmake-build-debug\OpenMP.exesequentialProgram elapse time: 0.263229 secondsparallelProgram elapse time: 0.0286121 secondsProcess finished with exit code 0

参考:《OpenmP编译原理及实现技术》 清华大学出版社

《OpenMP 简易教程》作者:周伟明 整理:Vae Anchoret

转载地址:http://ftyai.baihongyu.com/

你可能感兴趣的文章
利用位运算统计文本文档中的汉字字数
查看>>
基础编程题目集 - 7-1 厘米换算英尺英寸(15 分)
查看>>
关于转义序列
查看>>
C++ Template 基础篇(一):函数模板
查看>>
C++ Template 基础篇(二):类模板
查看>>
内存泄漏和内存溢出的区别和联系
查看>>
C/C++读写文本文件、二进制文件
查看>>
Dangling pointer(悬垂指针、迷途指针)和 Wild pointer(野指针)
查看>>
#pragma once用法总结
查看>>
斐波那契数列的三种解法及时间复杂度
查看>>
避免if语句的深层次嵌套
查看>>
C++中类的声明和类的实现分开
查看>>
VS中常用的快捷键
查看>>
UML学习入门就这一篇文章
查看>>
【20181209】C++求最大公约数
查看>>
为何程序员喜欢将INF设置为0x3f3f3f3f?
查看>>
ios::sync_with_stdio(false);
查看>>
20190120 OJ 回文序列的判断
查看>>
20190120 OJ递归
查看>>
leetcode notes:longest substring without repeating charactors
查看>>