C++ 多线程归并排序尝试

#if __cplusplus < 201103L
#error This file requires compiler and library support for the \
ISO C++ 2011 standard. This support is currently experimental, and must be \
enabled with the -std=c++11 or -std=gnu++11 compiler options. /// 这段话来自,<c++0x_warning.h>  
#endif

//#pragma GCC optimize(2) /// O2 优化 

#include <iostream>
#include <ctime>
#include <thread> /// C++ 11 标准的多线程写法 
#include <algorithm>
using namespace std;

int NOT_THREAD = (980); /// 多大长度一下不开启新线程 

const int maxn = 1000000 + 7;
int A[maxn], B[maxn];
void thread_merge_sort(int L, int R) { /// 多线程归并排序 
	if(L >= R) return;
	if(R - L == 1) {
		if(A[L] > A[R]) swap(A[L], A[R]); /// 区间中只有两个数的情况 
	}else {
		int mid = (L + R) >> 1;
		if(R - L >= NOT_THREAD) {
			thread Lth(thread_merge_sort, L,   mid);
			thread_merge_sort(mid + 1, R); /// 右半部分直接在当前线程排序 
			Lth.join();
		}else {
			thread_merge_sort(L,   mid);
			thread_merge_sort(mid+1, R); /// 直接递归计算,不建立新的线程 
		}
		int l = L, r = mid+1, m = L;
		while(l <= mid && r <= R) {
			if(A[l] <= A[r]) B[m ++] = A[l ++];
			else             B[m ++] = A[r ++];
		}
		while(l <= mid) B[m ++] = A[l ++];
		while(r <= R  ) B[m ++] = A[r ++];
		for(int i = L; i <= R; i ++) A[i] = B[i];
	}
}

int rand(int L, int R) {
	int RND = rand(); /// linux 下直接使用 rand() 生成随机数即可 
	#ifdef _WIN64
		RND = (rand() << 15) | RND;
	#endif
	#ifdef _WIN32
		RND = (rand() << 15) | RND;
	#endif
	return RND % (R - L + 1) + L;
}

class timer { /// 计时器 
	private:
		long long time_begin;
	public:
		timer(bool auto_begin = true) { /// 默认自动开始计时 
			if(auto_begin) {
				time_begin = clock();
			}
		}
		void begin() {
			time_begin = clock(); /// 开始计时 
		}
		double time_now() {
			return (clock() - time_begin)/(CLOCKS_PER_SEC * 1.0); /// 计算当前时刻 
		}
};

void Check(bool use_threads = true) {
	printf(use_threads ? "=> Threads\t[ available ]\n" : "=> Threads\t[unavailable]\n");
	printf(
		#ifdef _WIN64
			"-> _WIN64\t[ availalbe ]\n" /// 编译器 win64 环境 
		#endif
		#ifdef _WIN32
			"-> _WIN32\t[ available ]\n" /// 编译器 win32 环境 
		#endif
			"-> default\t[ available ]\n"
	);
	ios::sync_with_stdio(false); /// 关闭同步 
	int n = 1000000;
	for(int i = 1; i <= n; i ++) A[i] = rand(1, 1000000000); /// 输入被排序的序列 
	if(!use_threads) NOT_THREAD = 0x7fffffff; /// 不适用多线程 
	timer Timer; 
	thread_merge_sort(1, n); /// 多线程归并排序 
	printf("=> n = %d, Timer: %.3lf sec\n\n\n", n, Timer.time_now());
}

int main() {
	Check( true); /// 使用多线程 
	Check(false); /// 不使用多线程 
	return 0;
}

本地运行结果

可以看到,多线程归并排序比直接使用归并排序快了 31.25 % 31.25\% 31.25%(因 CPU 而异)。

O2优化后的效果对比图

开启 -O2 优化前后,多线程归并排序算法的运行效率提升并不显著,但是普通归并排序的效果有显著提升。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值