为了更好地理解我们的并行计算,我们首先来说明几个概念:
1.什么是多核
2.什么是多处理器
3.什么是多线程技术
多核: 多核是指一个计算机处理器芯片上有多个处理器核心,它们之间通过cpu内部总线进行通讯
多处理器:多处理器是指在一台计算机中有多个处理器,也就是将多个计算机内核集成在一个芯片上,总而提高计算能力
多线程技术:在计算机的cpu在处理作业时,如果单一的进程可能会导致阻塞,所以多个线程并发执行,提高了效率,
下面我们来介绍OPenMp算法(OpenMp多线程编程)
先介绍几个常用的函数:1.omp_set_num_threads();设置一个并行区域使用的线程数
2.omp_get_num_threads();获取当前并行区域内同一个线程组内的线程数
3.omp_get_thread_num();获取线程在线程组内的线程号
注:除了利用函数以外,我们还可以手动设置线程数
在计算机中的环境变量里,我们加入OMP_NUM_THREADS,并且为其赋值
下面我们直接上干货:
编译指导语句:
1.parallel for指令:
//下面是OpenMp的程序
#include"stdafx.h"
#include"omp.h"
int main(int argc,_TCHAR *argv[]){
omp_set_num_threads(4);
#pragma omp parallel for
for(int j=0;j<4;j++){
printf("j=%d,Thread=%d\n",j,omp_get_thread_num());
}
return 0;
}此时的输出是将这个for循环平均分配到4个线程中去,这4个线程并行计算,即同时执行
2.parallel 指令
#include"stdafx.h"
#include"omp.h"
int main(int argc,_TCHAR *argv[]){
omp_set_num_threads(4);
#pragma omp parallel
for(int j=0;j<4;j++){
printf("j=%d,Thread=%d\n",j,omp_get_thread_num());
}
return 0;
}此时,分为四个线程,每个线程都要将这个·for循环执行一遍,即并行区域,一般来说,parallel与for连用,但是在这里要注意,for指令后面一定要与for循环相连,
3.临界区(critical),这是为了便数据竞争
//下面我们来看一下临界区的概念
#include"stdafx.h"
#include"omp.h"
int main(int argc,_TCHAR *argv[]){
omp_set_num_threads(4);
int arx[10];
arx[0]=1;
arx[1]=2;
arx[2]=3;
arx[3]=4;
arx[4]=5;
int max_num=-1;
#pragma omp parallel for
for(int i=0;i<5;i++){
//下面的代码,我们用到了临界区的相关信息
//这样的话可以避免结果的错误
#pragma omp critical(max_arx)
if(arx[i]>max_num)
max_num=arx[i];
}
printf("max=%d\n",max_num);
return 0;下面分享一个自己写的临界区的代码:
//自己单独写一个临界区的代码
#include"stdafx.h"
#include"omp.h"
int main(int argc,_TCHAR *argv[]){
omp_set_num_threads(4);
int a[10]={12,23,45,65,78,87,98,89,0,70};
int max_num=0;
int i;
#pragma omp parallel for
for(int j=0;j<4;j++){
#pragma omp critical(max_a)
if(a[j]>max_num)
max_num=a[j];
}
printf("max=%d\n",max_num);
return 0;
}
4.private字句private字句也是为了避免数据竞争
例子:
//下面我们学习一下private子句
#include"stdafx.h"
#include"omp.h"
int main(int argc,_TCHAR *argv[]){
omp_set_num_threads(2);
int k=0;
printf("k=%d\n",k);
//其实这是把一个循环分到两个线程去做(手动去分)
#pragma omp parallel private(k)
{
//这里我们用到了private字句,这样的话,对于每一个线程来说,都有一个独自的k,是私有变量
int id=omp_get_thread_num();
k=0;//在这里,因为k是这个并行区域的私有变量,所以一定要初始化
if(id==0)
//在这里for循环的执行次数还是一定的
for(int i=0;i<10;i++)
{
k+=1;
printf("k=%d\n",k);
}
else
{
for(int i=0;i<10;i++)
{
k+=2;
printf("k=%d\n",k);
}
}
}
#pragma parallel for private(k)
for(int i=0;i<10;i++)
{
k++;
printf("k=%d\n",k);
}
printf("k=%d\n",k);
system("pause");
return 0;
}
通过运行结果我们可以发现,每一个k都对应自己的线程,只会随着自己的线程的变化而变化
关于运行结果,我不在粘出来了,希望大家可以去自己操作一下,工具是vc2015,一定要打开openmp的开关