一、简介

OpenMP介绍

在C/C++中,OpenMP可以通过使用预处理指令来让程序并行化。OpenMP指令使用的格式为:

#pragma omp 指令 [子句[子句]…]

下面是一个最简单的OpenMP程序,

#include <stdio.h>
#include <omp.h>

int main(int argc, char* argv[])
{
    int i;
	#pragma omp parallel for 
	for (i = 0; i < 10; i++) {
		printf("i = %d\n", i);
	}
	return 0;
}

  #pragma是预编译指令,这里的意思是在编译时使用openmp并行库,parallel是并行指令,for也是另外一个指令,一般来讲要使用for,通常都会跟parallel搭配使用。通常parallel只对其后面紧跟的代码块起作用,要想对多个代码块起作用,可以在代码块组合前后加上括号。

OpenMP是一套用于共享内存并行系统的多处理器程序设计的指导性的编译处理方案,我们可以发现程序还是在循环结束之后才运行return 0语句,因此可以推断OpenMP并行执行的程序要全部结束后才会运行后面非并行部分的代码,这就是fork/join并行模式。

二、parallel,for,sections指令的组合用法

parallel 是构造并行块的一个指令,同时也可以配合其他指令如for, sections等指令一起使用。在这个指令后面需要使用一对大括号来指定需要并行计算的代码。这里看一下怎么搭配for和sections的用法

#pragma omp parallel [for | sections] [子句[子句]…] 
{ 
//并行部分 
}

上面第一部分已经介绍了parallel for这种最常用的用法,下面看一下第二种用法:

#include <stdio.h>
#include <omp.h>

int main(int argc, char* argv[])
{
	#pragma omp parallel 
	{
	    int i, j;
	    #pragma omp for
	    for (i = 0; i < 5; i++)
		    printf("i = %d\n", i);
	    #pragma omp for
	    for (j = 0; j < 5; j++)
		    printf("j = %d\n", j);
	}
	return 0;
}

接下来看看sections指令的用法:

sections语句可以将下面的代码分成不同的分块,通过section指令来指定分块。每一个分块都会并行执行,具体格式:

#pragma omp [parallel] sections [子句]
{

#pragma omp section
{
//代码
}

}

int main(int argc, char* argv[])
{
	#pragma omp parallel sections
	{
		#pragma omp section 
		printf("Section 1 ThreadId = %d\n", omp_get_thread_num());
		#pragma omp section
		printf("Section 2 ThreadId = %d\n", omp_get_thread_num());
		#pragma omp section
		printf("Section 3 ThreadId = %d\n", omp_get_thread_num());
		#pragma omp section
		printf("Section 4 ThreadId = %d\n", omp_get_thread_num());
	}
	return 0;
}

sections和for的区别:

    当我们使用for时,openmp是对for语句的所有i值分配到不同线程(或计算节点)进行并行计算。

    而当我们使用sections,openmp是对sections中的子section分配到不同计算节点进行并行计算。这只适用于section和section之间没有依赖的情形。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐