C++之OpenMP并行编程——枚举排序

环境设置

(这是自己高新能与云计算课程的一个作业)可以看之前那篇Visual Studio 2017之OpenMP运行环境配置

算法设计

枚举排序算法:
是一种最简单的排序算法,通常也称为秩排序(Rank Sort)。 该算法的具体思想是(假设按关键字递增排序),对每一个待排序的元素统计小于它的所有 元素的个数,从而得到该元素最终处于序列中的位置。
1、串行算法:
假定待排序的 n 个数存在 a[1]…a[n] 中。首先将 a[1]与 a[2]…a[n]比较,记录比其小的数的个数,令其为k,a[1]就被存入有序的 数组 b[1]…b[n]的 b[k+1]位置上;然后将 a[2]与 a[1],a[3]…a[n]比较,记录比其小的数的个数,依此类推。这样的比较操作共n(n-1)次,所以串行秩排序的时间复杂度为O(n平方)。
在这里插入图片描述
2、并行算法
在这里插入图片描述
在该并行算法中,使用了n个处理器,由于每个处理器定位一个元素,所以步骤⑵的时 间复杂度为 O(n);步骤⑶中主进程完成的数组元素重定位操作的时间复杂度为 O(n),通 信复杂度分别为 O(n);同时⑴中的通信复杂度为 O(n平方);所以总的计算复杂度为 O(n), 总的通信复杂度为 O(n平方)。

源代码

#include<omp.h>
#include<iostream>
#include<math.h>
#include<time.h>
using namespace std;
//串行排序
void enumSort(int *a, int *b, int n)
{
	for (int i = 0; i < n; i++)
	{
		int k = 0;
		for (int j = 0; j < n; j++)
		{
			if (a[i] > a[j])
				k++;
		}
		while (b[k] != 0)
			k++;
		b[k] = a[i];
	}
}
//并行排序
void paEnumSort(int *a, int *b, int n)
{
	omp_set_num_threads(n);
#pragma omp parallel for
	for (int i = 0; i < n; i++)
	{
		int k = 0;
		for (int j = 0; j < n; j++)
		{
			if (a[i] > a[j])
				k++;
		}
		while (b[k] != 0)
			k++;
		b[k] = a[i];
	}
}
int main()
{
	for (int n = 2000; n < 30000; n += 2000)
	{
		int *a = new int[n];
		int *b = new int[n];
		int *b2 = new int[n];
		double s1, s2, e1, e2;
		//随机数
		srand((unsigned)(time(NULL)));
		for (int i = 0; i < n; i++)
		{
			a[i] = rand();
			b[i] = 0;
			b2[i] = 0;
		}
		s1 = omp_get_wtime();
		enumSort(a, b, n);
		e1 = omp_get_wtime();
		cout << "串行运算使用时间:" << e1 - s1 << endl;
		s2 = omp_get_wtime();
		paEnumSort(a, b2, n);
		e2 = omp_get_wtime();
		cout << "并行运算使用时间:" << e2 - s2 << endl;
		cout << endl;
		delete a, b, b2;
	}
	system("pause");
}

运行结果:

(只不过代码其实有些问题,好像分配不了那么多线程。。。先放着后面解决了再看吧)
在这里插入图片描述
在这里插入图片描述
蓝色为并行计算,橙色为串行计算。
分析:刚开始并行算法运行时间是多于串行算法的,随后从4000开始,并行算法的时间比串行时间少;可见随着数组长度的变大,并行算法的优势就体现出来了。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐