openmp多线程简单编程
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多线程简单编程相关推荐
- C++ 高性能计算之多线程简单基础入门教程
C/C++ 高性能计算之多线程简单基础入门教程 比起别人的盲目罗列函数接口,鹦鹉学舌式的解释每一个输入参数和输出参数,一味求全而无重点,我的文章更侧重于入门知识的讲解,宁缺毋滥,只有一些最简单的入门用 ...
- CSerialPort多线程串口编程工具详解
1.前言 既然有了MSComm这种简单粗暴的控件,为什么还需要CSerialPort类?这是因为与前者相比,这个类在程序的发布上不需要加入其他的文件,而且CSerialPort提供给我们的函数都是开放 ...
- python 多线程并发编程(生产者、消费者模式),边读图像,边处理图像,处理完后保存图像实现提高处理效率
文章目录 需求 实现 先导入本次需要用到的包 一些辅助函数 如下函数是得到指定后缀的文件 如下的函数一个是读图像,一个是把RGB转成BGR 下面是主要的几个处理函数 在上面几个函数构建对应的处理函数 ...
- Java 多线程 并发编程
转载自 Java 多线程 并发编程 一.多线程 1.操作系统有两个容易混淆的概念,进程和线程. 进程:一个计算机程序的运行实例,包含了需要执行的指令:有自己的独立地址空间,包含程序内容和数据:不同进 ...
- C#——await与async实现多线程异步编程
以前,我们或许用过Thread,在主线程执行的时候,新开另一个新线程,来执行新方法. 今天看别人发给我的一段代码的时候发现了一个不认识的await,但是又感觉很熟悉的样子,感觉是线程那块儿的东西,查了 ...
- day16多线程网络编程日志枚举
多线程&网络编程 一.实现多线程 1.1 相关概念 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的一条执行路径.实际运作单位.简单理解:应用软件中互相独立,可以同时运 ...
- Java多线程并发编程--Java并发包(JUC)
Java多线程并发–Java并发包(JUC) 前言 前一篇文章中,笔者已经介绍了Java多线程的一些基础知识,但是想要成为一名中高级Java程序员还必须懂得Java并发包(JUC)的知识点,而且JUC ...
- 推荐《Linux 多线程服务器端编程》
赖勇浩(http://laiyonghao.com) 最近,有一位朋友因为工作需要,需要从网游的客户端编程转向服务器端编程,找我推荐一本书.我推荐了<Linux 多线程服务器端编程--使用 mu ...
- Java学习笔记2 多线程简单总结
多线程简单总结 1. 相关概念 1.1 线程与进程 进程 线程 1.2 线程调度 分时调度 抢占式调度 1.3 同步与异步 同步 异步 1.4 并发与并行 并发 并行 2. 创建线程 2.1 继承Th ...
最新文章
- win10系统由于服务器出错翻译失败,win10系统下谷歌浏览器翻译失败如何解决
- bios文件查看工具_何必花钱升级显卡!AMD鸡血BIOS杀到
- 联机分析的列式数据库 clickHouse
- java hibernate 表关联_Hibernate多表关联
- lubridate | 日期类型数据的转换
- Linux下通过jstat命令查看jvm的GC情况
- 消息循环,注册窗口,创建窗口【图解】
- 精益数据分析 - 第15章 阶段1:移情
- 2018年,数万款小程序暴毙在路上
- 深度解读“人类首次实现室温超导”:思路并无突破,中国并不落后-1
- Sloth组件之NetRisc.Configuration源代码发布
- 全通系统定义、零极点关系、应用
- C# 城市路网地图生成与运动模拟(一)-数据的获取
- mysql自定义函数的分号_MySQL 第八篇:自定义函数、存储过程、游标-阿里云开发者社区...
- android广告赚钱[转]
- c语言报告西电,c语言课程设计报告西安电子科技大学.docx
- 易优cms uiarclist 文档列表可视化标签
- Python怎么计算时间差(含代码实例)
- 常用的git操作指令
- Spring cloud 通过父工程打包多个子工程