基于OpenMP的并行计算

基于OpenMP的并行计算

本人所有博客仅用于个人的知识积累,禁止商业与非商业用途的剽窃和抄袭,如有错误,欢迎各位大佬批评指正,我们一起交流讨论、共同成长。

序言:本学期选修了《GPU并行计算》这门课程,借此来学习一下并行计算的硬件基础、并行程序设计思想与方法、并行算法设计与分析等内容,提高个人的编码能力和底层硬件与上层软件的联系能力。闲话不多说,我们开始吧!

基于OpenMP(Open Multi-Processing)的并行程序主要是在原来的串行程序基础上,添加编译指导指令(类似于C/C++中带“#”的语句)。因此,编程任务量小,上手比较容易。而实现并行行为主要是依靠底层运行支持库,程序员不需要关注这些,只需要考虑并行区域的划分与并行算法的设计。

首先,使用OpenMP(以下简称“omp”)时,需要包含的头文件如下代码块所示,第一个头文件包含了omp的编译指导语句,第二个头文件主要是为了测试并行计算的时间,使用其中的数据类型clock_t

#include<omp.h>
#include<time.h>

基于omp的并行语句都是以如下关键词组开始的:

#pragma omp 

若出现如下语句,则表明代码段进入了并行模式:

#pragma omp parallel

利用下方的主函数可以测试在未指定线程个数的时候,CPU一共创建了多少线程来执行并行代码段。parallel块中的每行代码都被多个线程重复执行了。

int main()
{
#pragma omp parallel
	cout << "hello world" << endl;
	return 0;
}

下面给出几组简单且常见的并行测试程序来体会基于omp的并行编程方法。

循环语句中开启多个线程需要用到下述语句,且两组语句等价

#pragma omp parallel for
#pragma omp parallel 
	{
#pragma omp for
	for(...)
		{
			...
		}
	...
	}

值得注意的是,
1、第二组代码段中,若没有#pragma omp parallel,则无法实现并行,只有二者结合起来使用才会有效;
2、#pragma omp for语句的作用域仅在当前循环,对于并行区域的其他循环不起作用,若并行块中的所有for循环都需要并行计算的话,则每组循环开始前都应添加#pragma omp for语句;
3、参与并行计算的线程必须保证具有独立性,即各个循环之间互不相关,后一个循环不依赖于前面若干个循环的结果;
4、此类并行模式属于数据级并行

若指定线程数为n,则

#pragma omp parallel num_threads(n) 
	{
#pragma omp for
	for(...)
		{
			...
		}
	...
	}

测试程序1:并行输出测试

#include<iostream>
#include<Windows.h>
#include<omp.h>
using namespace std;
int main()
{
#pragma omp parallel
	{
#pragma omp for
		for (int j = 0; j < 1000; j++)
		{
			Sleep(5000);
			cout << "j=" << j << ", Thread_id = " << omp_get_thread_num() << endl;
		}	
	}
	return 0;
}

测试程序2:串行累加与并行累加的用时比较

#include<iostream>
#include<time.h>
#include<omp.h>
using namespace std;
void SumNumber()
{
	int sum = 0;
	for(int i = 0; i < 10000000; i++)
		sum ++;
}
void SerialTest()
{
	clock_t t1 = clock();
	for (int i = 0; i < 100; i++)
		SumNumber();
	clock_t t2 = clock();
	cout << "Serial Time: " << t2 - t1 << endl;
}
void ParallelTest()
{
	clock_t t1 = clock();
#pragma omp parallel for
	for (int i = 0; i < 100; i++)
		SumNumber();
	clock_t t2 = clock();
	cout << "Parallel Time: " << t2 - t1 << endl;
}
int main()
{
	SerialTest();
	ParallelTest();
	return 0;
}

在这里插入图片描述

void ParallelTest()
{
	clock_t t1 = clock();
#pragma omp parallel num_threads(5)
	{
#pragma omp for
		for (int i = 0; i < 100; i++)
			SumNumber();
	}
	clock_t t2 = clock();
	cout << "Parallel Time: " << t2 - t1 << endl;
}

在这里插入图片描述

sections结构是omp中常用的任务划分语句,将并行区域的代码结构划分为离散的代码块(section),每个代码块(section)都由一个线程执行,属于任务级并行

#pragma omp parallel sections
{
	#pragma omp section
	{
		...
	}
	#pragma omp section
	{
		...
	}
	...
}

测试程序3:向量的加法


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值