OpenMP支持的编程语言包括C、C++和Fortran,简单的说,就是一种API,来编写多线程应用程序。通过使用简单的指令#pragma omp …就可以对程序进行多线程并行。OpenMP使得程序员可以把更多的精力投入到并行算法本身,而非其具体实现细节。对基于数据分集的多线程程序设计,它是一个很好的选择。但是,作为高层抽象,OpenMP并不适合需要复杂的线程间同步和互斥的场合。OpenMP的另一个缺点是不能在非共享内存系统(如计算机集群)上使用。在这样的系统上,MPI使用较多。
用 OpenMP 编写的程序在运行时采用 fork-join 并行执行模式。程序开始是以一个单进程运行,称为执行的主线程。主线程顺序运行到第 1 个并行块结构时就生成一个线程队,原来的主线程成为线程队的主线程。程序中被并行块包围起来的所有语句(包括块内被调用的子程序)在线程队中并行执行,一直到并行块执行完后,线程队中的线程中止,而主线程继续执行。一个程序中可以定义任意数目的并块,因此,在一个程序的执行中可以分叉、合并若干次。

使用

做是使用一些指令:

parallel :用在一个结构块之前,表示这段代码将被多个线程并行执行;
for:用于for循环语句之前,表示将循环计算任务分配到多个线程中并行执行,以实现任务分担,必须由编程人员自己保证每次循环之间无数据相关性;
parallel for :parallel和for指令的结合,也是用在for循环语句之前,表示for循环体的代码将被多个线程并行执行,它同时具有并行域的产生和任务分担两个功能;
sections :用在可被并行执行的代码段之前,用于实现多个结构块语句的任务分担,可并行执行的代码段各自用section指令标出(注意区分sections和section);
parallel sections:parallel和sections两个语句的结合,类似于parallel for;
single:用在并行域内,表示一段只被单个线程执行的代码;
critical:用在一段代码临界区之前,保证每次只有一个OpenMP线程进入;
flush:保证各个OpenMP线程的数据影像的一致性;
barrier:用于并行域内代码的线程同步,线程执行到barrier时要停下等待,直到所有线程都执行到barrier时才继续往下执行;
atomic:用于指定一个数据操作需要原子性地完成;
master:用于指定一段代码由主线程执行;
threadprivate:用于指定一个或多个变量是线程专用,后面会解释线程专有和私有的区别。

例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <iostream>
#include <omp.h>
using namespace std;
void test1(){int nthreads, tid;omp_set_num_threads(2);/* Fork a team of threads giving them their own copies of variables */#pragma omp parallel{/* Obtain thread number */tid = omp_get_thread_num();/* Only master thread does this */if (omp_get_thread_num() == 1){for (int i = 0; i < 100000; i++) {int x = 1000, y = 100;double  num = x / y;}printf("Hello World from thread = 1\n" );}else if (omp_get_thread_num() == 0){for (int i = 0; i < 100000; i++) {int x = 1000, y = 100;double  num = x / y;}printf("Hello World from thread = 0\n" );}}  /* All threads join master thread and disband */return;
}void test2()
{
#pragma omp parallel for for(int k = 0; k < 2; k++)  {  if (omp_get_thread_num() == 1){for (int i = 0; i < 100000; i++) {int x = 1000, y = 100;double  num = x / y;}printf("Hello World from thread = 1\n" );}else if (omp_get_thread_num() == 0){for (int i = 0; i < 100000; i++) {int x = 1000, y = 100;double  num = x / y;}printf("Hello World from thread = 0\n" );}  } return;
}void test() {for (int i = 0; i < 100000; i++) {int x = 1000, y = 100;double  num = x / y;}
}
int main() {cout << "CPU number:" << omp_get_num_procs() << endl;double start = omp_get_wtime();test1();double end = omp_get_wtime();cout << "Multi-thread Time is: " << (end - start)*1000 << endl;double t1 = omp_get_wtime();for (int i = 0; i < 100000; i++) {int x = 1000, y = 100;double  num = x / y;}for (int i = 0; i < 100000; i++) {int x = 1000, y = 100;double  num = x / y;}double t2 = omp_get_wtime();cout << "Single Time is: " << (t2 - t1)*1000 << endl;t1 = omp_get_wtime();test2();t2 = omp_get_wtime();cout << "thread is: " << (t2 - t1)*1000 << endl;return 0;
}

cmake:

cmake_minimum_required(VERSION 3.5)project(exe)SET(CMAKE_BUILD_TYPE "Release")
#SET(CMAKE_BUILD_TYPE "Debug")SET(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb ${CMAKE_CXX_FLAGS} ")
SET(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall ${CMAKE_CXX_FLAGS} ")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/out")FIND_PACKAGE( OpenMP REQUIRED)
if(OPENMP_FOUND)
message("OPENMP FOUND !!!!")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS} -lstdc++ -pthread -fopenmp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} -lstdc++ -pthread -fopenmp")
set(CMAKE_EXE_LINKER_FLAGS"${CMAKE_EXE_LINKER_FLAGS}${OpenMP_EXE_LINKER_FLAGS} -lstdc++ -pthread -fopenmp")
endif()add_definitions(-D__ARM_NEON)if(USE_CVITEK1838)
add_definitions("-O3 -fpermissive -fPIC  -mcpu=cortex-a53 -fno-aggressive-loop-optimizations  -Wno-narrowing -ffunction-sections -fdata-sections -fstack-protector -DUSER_BIT_64 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DENABLE_NEON" )  #-DUSE_HI3559include_directories(#${SDK_DIR}/include${THIRD_PARTY_LIB_DIR}/opencv-3.2_cvitek/include../src/cvitek ../src  ../inc                   ${SYS_SDK_DIR}/middleware/include    ${SYS_SDK_DIR}/middleware/include/ive   ${SYS_SDK_DIR}/middleware/include/isp/cv182x            #${IVE_DIR}/include/ive${TPU_DIR}/include/cvimath) link_directories(${SYS_SDK_DIR}/middleware/lib64${SYS_SDK_DIR}/middleware/lib64/3rd${THIRD_PARTY_LIB_DIR}/opencv-3.2_cvitek/lib   ) set(IVE_LIBS2${SYS_SDK_DIR}/middleware/lib64/libcvi_ive_tpu.so#${SYS_SDK_DIR}/middleware/lib64/libcvi_ive_tpu.so)endif()add_executable(test_openmp test_openmp.cpp)
target_link_libraries(test_openmp cvimath cviruntime cvikernel cvitracer)#vpu sys

一些问题

1.运行时候报错找不到库

加这个

FIND_PACKAGE( OpenMP REQUIRED)
if(OPENMP_FOUND)
message("OPENMP FOUND !!!!")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS} -lstdc++ -pthread -fopenmp")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} -lstdc++ -pthread -fopenmp")
set(CMAKE_EXE_LINKER_FLAGS"${CMAKE_EXE_LINKER_FLAGS}${OpenMP_EXE_LINKER_FLAGS} -lstdc++ -pthread -fopenmp")
endif()

或者编译时候直接

g++ test_openmp.cpp -o test -fopenmp
或
gcc test_openmp.cpp -o test -fopenmp -lstdc++

添加so库到运行目录,这里找的是晶视的docker里找出来的库

2.运行效果,在pc上和在晶视芯片上,运行效率都低于单线程,目前网上发现同样问题的情况不少

openmp多线程简单编程相关推荐

  1. C++ 高性能计算之多线程简单基础入门教程

    C/C++ 高性能计算之多线程简单基础入门教程 比起别人的盲目罗列函数接口,鹦鹉学舌式的解释每一个输入参数和输出参数,一味求全而无重点,我的文章更侧重于入门知识的讲解,宁缺毋滥,只有一些最简单的入门用 ...

  2. CSerialPort多线程串口编程工具详解

    1.前言 既然有了MSComm这种简单粗暴的控件,为什么还需要CSerialPort类?这是因为与前者相比,这个类在程序的发布上不需要加入其他的文件,而且CSerialPort提供给我们的函数都是开放 ...

  3. python 多线程并发编程(生产者、消费者模式),边读图像,边处理图像,处理完后保存图像实现提高处理效率

    文章目录 需求 实现 先导入本次需要用到的包 一些辅助函数 如下函数是得到指定后缀的文件 如下的函数一个是读图像,一个是把RGB转成BGR 下面是主要的几个处理函数 在上面几个函数构建对应的处理函数 ...

  4. Java 多线程 并发编程

    转载自  Java 多线程 并发编程 一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进 ...

  5. C#——await与async实现多线程异步编程

    以前,我们或许用过Thread,在主线程执行的时候,新开另一个新线程,来执行新方法. 今天看别人发给我的一段代码的时候发现了一个不认识的await,但是又感觉很熟悉的样子,感觉是线程那块儿的东西,查了 ...

  6. day16多线程网络编程日志枚举

    多线程&网络编程 一.实现多线程 1.1 相关概念 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的一条执行路径.实际运作单位.简单理解:应用软件中互相独立,可以同时运 ...

  7. Java多线程并发编程--Java并发包(JUC)

    Java多线程并发–Java并发包(JUC) 前言 前一篇文章中,笔者已经介绍了Java多线程的一些基础知识,但是想要成为一名中高级Java程序员还必须懂得Java并发包(JUC)的知识点,而且JUC ...

  8. 推荐《Linux 多线程服务器端编程》

    赖勇浩(http://laiyonghao.com) 最近,有一位朋友因为工作需要,需要从网游的客户端编程转向服务器端编程,找我推荐一本书.我推荐了<Linux 多线程服务器端编程--使用 mu ...

  9. Java学习笔记2 多线程简单总结

    多线程简单总结 1. 相关概念 1.1 线程与进程 进程 线程 1.2 线程调度 分时调度 抢占式调度 1.3 同步与异步 同步 异步 1.4 并发与并行 并发 并行 2. 创建线程 2.1 继承Th ...

最新文章

  1. win10系统由于服务器出错翻译失败,win10系统下谷歌浏览器翻译失败如何解决
  2. bios文件查看工具_何必花钱升级显卡!AMD鸡血BIOS杀到
  3. 联机分析的列式数据库 clickHouse
  4. java hibernate 表关联_Hibernate多表关联
  5. lubridate | 日期类型数据的转换
  6. Linux下通过jstat命令查看jvm的GC情况
  7. 消息循环,注册窗口,创建窗口【图解】
  8. 精益数据分析 - 第15章 阶段1:移情
  9. 2018年,数万款小程序暴毙在路上
  10. 深度解读“人类首次实现室温超导”:思路并无突破,中国并不落后-1
  11. Sloth组件之NetRisc.Configuration源代码发布
  12. 全通系统定义、零极点关系、应用
  13. C# 城市路网地图生成与运动模拟(一)-数据的获取
  14. mysql自定义函数的分号_MySQL 第八篇:自定义函数、存储过程、游标-阿里云开发者社区...
  15. android广告赚钱[转]
  16. c语言报告西电,c语言课程设计报告西安电子科技大学.docx
  17. 易优cms uiarclist 文档列表可视化标签
  18. Python怎么计算时间差(含代码实例)
  19. 常用的git操作指令
  20. Spring cloud 通过父工程打包多个子工程

热门文章

  1. Java故障记录——OutOfMemoryError
  2. 关于ZETag云标签你了解多少?
  3. 算法笔记 胡凡 codeup 数列
  4. python计算机视觉-1.2.2 图像轮廓与直方图
  5. 21岁女总裁董思阳,她做对了那些事情
  6. 初学者都能学会的ElasticSearch入门实战《玩转ElasticSearch 2》
  7. html仿网易云网站,GitHub - Hdoove/music-webapp: 仿网易云webapp
  8. java透视图_Eclipse透视图
  9. 内容为王,如何打造爆款小红书笔记?
  10. 原型设计都有哪些好用的软件?