OpenMP

OpenMP支持的编程语言包括C、C++和Fortran,简单的说,就是一种API,来编写多线程应用程序。通过使用简单的指令#pragma omp …就可以对程序进行多线程并行。OpenMP使得程序员可以把更多的精力投入到并行算法本身,而非其具体实现细节。对基于数据分集的多线程程序设计,它是一个很好的选择。但是,作为高层抽象,OpenMP并不适合需要复杂的线程间同步和互斥的场合。OpenMP的另一个缺点是不能在非共享内存系统(如计算机集群)上使用。在这样的系统上,MPI使用较多。
用 OpenMP 编写的程序在运行时采用 fork-join 并行执行模式。程序开始是以一个单进程运行,称为执行的主线程。主线程顺序运行到第 1 个并行块结构时就生成一个线程队,原来的主线程成为线程队的主线程。程序中被并行块包围起来的所有语句(包括块内被调用的子程序)在线程队中并行执行,一直到并行块执行完后,线程队中的线程中止,而主线程继续执行。一个程序中可以定义任意数目的并块,因此,在一个程序的执行中可以分叉、合并若干次。
1. 如何使用openMP
在VS里想使用OpenMP编程非常简单,在普通的控制台程序中就可以包含头文件使用指令来并行程序了。
注意:包含头文件后需要项目属性页上左侧选择“配置属性”——“C/C++”——“语言”,然后在右侧“OpenMP支持”后选择“是(/openmp)”。
OpenMP_第1张图片

  1. 例子
#include 
#include   // openMP必带头文件
using namespace std;
void test() {
	for (int i = 0; i < 10000; i++) {
		int x = 1000, y = 100;
		double  num = x / y;
	}
}
int main() {
	const int count = 50000;
	int a[count];
	int b[count];
	int c[count] = { 0 };
	for (int i = 0; i < count; i++) {
		a[i] = i + 1;
		b[i] = 10;
	}

	cout << "CPU number:" << omp_get_num_procs() << endl;

#pragma omp parallel 
	{
		printf("Hello!   threadID=%d  thraed number:%d\n", omp_get_thread_num(), omp_get_num_threads());
	}

	//use openMP instruct to parallel to loop;
	//set the  threads num 
	omp_set_num_threads(4);

	double start = omp_get_wtime();
	//Also can use:#pragma omp parallel for  num_threads(4)
#pragma omp parallel for  
	for (int i = 0; i < count; i++) {
		c[i] = a[i] / b[i];
		test();
	}
	double end = omp_get_wtime();
	cout << "Multi-thread Time is: " << end - start << endl;


	double t1 = omp_get_wtime();
	for (int i = 0; i < count; i++) {
		c[i] = a[i] / b[i];
		test();
	}
	double t2 = omp_get_wtime();
	cout << "Single Time is: " << t2 - t1 << endl;

	return 0;
}
  1. openMP使用
#pragma omp 指令
子句1
子句2
...
指令:
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:用于指定一个或多个变量是线程专用,后面会解释线程专有和私有的区别。

你可能感兴趣的:(C++)