标签:min idt noi har 兴趣 openmp 部分 lan actual
https://zhuanlan.zhihu.com/p/51173703
最近,有个课设关于提取SIFT特征,老师要求不能使用OpenCV,从底层实现SIFT特征,在实现的过程中,参考了很多人的思路,其中有一个是对代码进行并行优化,引起了我的兴趣,所以找了一些资料来详细认识下OpenMP的使用~~
参考文章:
OpenMP并行程序设计(二) - 周伟明的多核、测试专栏 - CSDN博客
标准并行模式执行代码的基本思想是,程序开始时只有一个主线程,程序中的串行部分都由主线程执行,并行的部分是通过派生其他线程来执行,但是如果并行部分没有结束时是不会执行串行部分的~
开发环境:VS2015,注意使用时要将OpenMP打开,并且#include "omp"
在C++中,OpenMP的指令格式为:#pragma omp指令[子句[子句]…]
例如: #pragma omp parallel private(i, j)
parallel 就是指令, private是子句
OpenMP的指令有以下一些:(常用的已标黑)
例子1:
#include <iostream>
#include "omp.h"
using namespace std;
int main(int argc, char **argv) {
//设置线程数,一般设置的线程数不超过CPU核心数,这里开4个线程执行并行代码段
omp_set_num_threads(4);
#pragma omp parallel
{
cout << "Hello" << ", I am Thread " << omp_get_thread_num() << endl;
}
}
结果1:
Hello, I am Thread 1
Hello, I am Thread 0
Hello, I am Thread 2
Hello, I am Thread 3
例子2:(带for的指令)
#include <iostream>
#include "omp.h"
using namespace std;
int main() {
omp_set_num_threads(4);
#pragma omp parallel
for (int i = 0; i < 3; i++)
printf("i = %d, I am Thread %d\n", i, omp_get_thread_num());
getchar();
}
结果2:
i = 0, I am Thread 0
i = 1, I am Thread 0
i = 2, I am Thread 0
i = 0, I am Thread 0
i = 0, I am Thread 0
i = 0, I am Thread 0
i = 1, I am Thread 0
i = 2, I am Thread 0
i = 1, I am Thread 0
i = 2, I am Thread 0
i = 1, I am Thread 0
i = 2, I am Thread 0
例子3:
#include <iostream>
#include "omp.h"
using namespace std;
int main() {
omp_set_num_threads(4);
#pragma omp parallel for
for (int i = 0; i < 3; i++)
printf("i = %d, I am Thread %d\n", i, omp_get_thread_num());
getchar();
}
结果3:
i = 0, I am Thread 0
i = 1, I am Thread 1
i = 2, I am Thread 2
注意注意:例子三和例子二的区别和不同
omp_get_num_procs, 返回运行本线程的多处理机的处理器个数。
omp_get_num_threads, 返回当前并行区域中的活动线程个数。
omp_get_thread_num, 返回线程号
omp_set_num_threads, 设置并行执行代码时的线程个数
omp_init_lock, 初始化一个简单锁
omp_set_lock, 上锁操作
omp_unset_lock, 解锁操作,要和omp_set_lock函数配对使用。
omp_destroy_lock, omp_init_lock函数的配对操作函数,关闭一个锁
如果在VS2015中运行时,首先要先做一个判断,编译器是否支持OpenMP,在下图中把其打开,然后在程序中做一个判断语句:
#ifdef _OPENMP //判断是否定义
omp_lock_t lock;
omp_init_lock(&lock);
#endif
设置打开OpenMP:
private, 指定每个线程都有它自己的变量私有副本。
firstprivate,指定每个线程都有它自己的变量私有副本,并且变量要被继承主线程中的初值。
lastprivate,主要是用来指定将线程中的私有变量的值在并行处理结束后复制回主线程中的对应变量。
reduce,用来指定一个或多个变量是私有的,并且在并行处理结束后这些变量要执行指定的运算。
nowait,忽略指定中暗含的等待
num_threads,指定线程的个数
schedule,指定如何调度for循环迭代
shared,指定一个或多个变量为多个线程间的共享变量
ordered,用来指定for循环的执行要按顺序执行
copyprivate,用于single指令中的指定变量为多个线程的共享变量
copyin,用来指定一个threadprivate的变量的值要用主线程的值进行初始化。
default,用来指定并行处理区域内的变量的使用方式,缺省是shared
其实,实际中做优化时会考虑的更多更复杂,不过自己的代码优化的话,一般也就是优化for循环多一些,比较简单。具体使用时再进行查找深入了解~
标签:min idt noi har 兴趣 openmp 部分 lan actual
原文地址:https://www.cnblogs.com/dhcn/p/12272898.html