为了更好地理解我们的并行计算,我们首先来说明几个概念:

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的开关