简述

通过这个标题也大概能猜测出算法的思想。

  • Merge操作是O(n)的(出自于MergeSort归并排序)
  • 根据线程数将数据划分为thread_count块(较为均匀点就好了)
  • 每段上用qsort(快排)
  • 之后再用一个merge将所有的快排结果合并起来

算法思想很简单,但是效果却不错。

  • 之前写过一篇用双进程写快排然后实现100w的排序只用0.2s

这里测试过用两个的情况,效果类似

PS D:\Code\C++\repo\openMP_test\x64\Debug> ./openMP_test.exe 2
reading finish
sort finished
Total time Serial: 0.223s

代码

  • 只有一个线程的时候不进行~
#include <iostream>
#include <omp.h>
#include <fstream>
#include <ctime>
using namespace std;
#pragma warning(disable : 4996)
int *a, n, thread_count, *output;void QSort(int begin, int end) {if (begin >= end) return;// 枢轴元素就需求最前里面的那个int i = begin, j = end, key = a[begin]; // 坑在begin点 while (i < j) {while (i < j && a[j] >= key) --j;if (i < j) a[i] = a[j];while (i < j && a[i] <= key) ++i;if (i < j) a[j] = a[i];}a[i] = key;QSort(begin, i - 1);QSort(i + 1, end);
}
void sort() {// 分成thread_count段;int *keys = new int[thread_count];bool *finished = new bool[thread_count];int localn = n / thread_count, i;for (i = 0; i < thread_count; ++i) {keys[i] = i * localn; // begin keysfinished[i] = false;}
#pragma omp parallel for num_threads (thread_count) default(none) shared(a, n,localn) private(i)for (i = 0; i < thread_count; ++i) {if (i < thread_count - 1) {QSort(i*localn, (i + 1)*localn - 1);}else {QSort(i*localn, n - 1);}}bool allfinished = false, first=true;int min=0, minkey_index, globalindex=0;while (!allfinished) {allfinished = false;first = true;// choose min indexfor (i = 0; i < thread_count; ++i) {if (finished[i]) continue;if (first) { min = a[keys[i]]; first = false; minkey_index = i;} else if (a[keys[i]] < min){min = a[keys[i]]; minkey_index = i;}}if (first) { break; }output[globalindex++] = min;keys[minkey_index]++;if (minkey_index == thread_count - 1 && keys[minkey_index] == n) finished[minkey_index] = true;else if (minkey_index < thread_count - 1 && keys[minkey_index] == (minkey_index + 1) * localn) { finished[minkey_index] = true;  }}delete[]finished;delete[]keys;
}int main(int argc, char **argv) {if (argc < 2) return 0;thread_count = strtol(argv[1], NULL, 10);int i;ifstream cin("input.txt");cin >> n;a = new int[n];output = new int[n];for (i = 0; i < n; ++i) cin >> a[i];cout << "reading finish\n";clock_t starttime, endtime;starttime = clock();sort();endtime = clock();cout << "sort finished\n";ofstream out("output.txt");for (i = 0; i < n; ++i) out << output[i] << " ";cout << "Total time sorted: " << (double)(endtime - starttime) / CLOCKS_PER_SEC << "s" << endl;delete[] a;delete[]output;
}
  • 调用之前写好的生成数据的脚本来生成数据
  • 然后用生成出来的exe来进行排序,后面的数值是线程数目
  • 运行代码其实并不消耗多少时间,主要的问题是在写入文件的时候消耗了点时间,IO操作嘛毕竟

PS D:\Code\C++\repo\openMP_test\x64\Debug> python generate.py 1000000
PS D:\Code\C++\repo\openMP_test\x64\Debug> ./openMP_test.exe 2
reading finish
sort finished
Total time Serial: 0.223s
PS D:\Code\C++\repo\openMP_test\x64\Debug> ./openMP_test.exe 10
reading finish
sort finished
Total time Serial: 0.068s
PS D:\Code\C++\repo\openMP_test\x64\Debug> ./openMP_test.exe 10
reading finish
sort finished
Total time sorted: 0.06s
PS D:\Code\C++\repo\openMP_test\x64\Debug> python check.py
right
PS D:\Code\C++\repo\openMP_test\x64\Debug>

生成数据的脚本

import sys
import numpy as npN = int(sys.argv[1])
a = np.random.randint(- int(np.sqrt(N)), int(np.sqrt(N)), N)
c = sorted(a)
with open("input.txt", 'w') as f:f.write(str(N) + '\n')f.write(' '.join(list(map(str, a)))+'\n')
with open("ans.txt", 'w') as f:for i in range(N):f.write(str(c[i]) + ' ')

检查结果的代码

with open('ans.txt', 'r')as f, open('output.txt', 'r') as r:a = f.readline()b = r.readline()print('right' if a == b else 'wrong')

【OpenMP实现】任意线程数并行化快排结合Merge排序100w--10线程下只用0.06s相关推荐

  1. 服务器线程数一直增加,.NET Core中遇到奇怪的线程死锁问题:内存与线程数不停地增长...

    一个 asp.net core 站点,之前运行在Linux 服务器上,运行一段时间后有时站点会挂掉,在日志中记录很多"EMFILE too many open files"的错误: ...

  2. Python实现常用排序(选择、冒泡、插入、快排、合并排序、堆排序)

    排序 基本思想:各类排序的共同点,个人认为可以把原始的数据序列,划分为有序序列与无序序列.有序序列开始可能为0,在每一次操作(循环或者递归)后,有序序列数目会加1,无序序列数目会减一,代码走完后,原本 ...

  3. 寻找第K大的数(快排思想)

    使用快排思想找第K大的数,算法复杂度O(n). 1.以数组a的第0位a[0]为参考基准base,将数组划分为两个部分: 如果找第K大的数,则将大于base的数往前挪,将小于base的数往后挪.如果找第 ...

  4. 算法_第k大的数_快排(leetcode215,java)

    文章目录 前言 一.题目描述 二.思路 三.代码实现 前言 1.(Math.random()(x-y))+y // Math.random()(x-y+1)+y; 随机数x~y 2.递归 3.三目运算 ...

  5. java 快排_八大排序-快速排序(搞定面试之手写快排)

    概要 快速排序由C. A. R. Hoare在1960年提出,是八大排序算法中最常用的经典排序算法之一.其广泛应用的主要原因是高效,核心算法思想是分而治之.快速排序经常会被作为面试题进行考察,通常的考 ...

  6. java 线程数_在虚拟机中是什么限制java线程数量?这方面涉及哪些调优?

    首先要说明一点,Java线程的实现是基于底层系统的线程机制来实现的,程序中开的线程并不全部取决于JVM虚拟机栈,而是取决于CPU,操作系统,其他进程,Java的版本.JVM的线程与计算机本身性能相关. ...

  7. LeetCode--75.颜色分类(三路快排,计数排序)

    颜色分类(C) 1. 题目描述 2. 题目解析 3. C语言实现 3.1 三路快排法 3.2 计数排序法 1. 题目描述 难度:中等 2. 题目解析 这道题需要注意一下几点: 原地进行排序,不可以另外 ...

  8. 【软件】[Qt\C++] 冒泡、希尔、堆排、基数、快排 5种排序Gui界面带对比——使用Qt实现

    完整代码 https://github.com/gongfpp/sortsWithQt 成品(随机生成数字后全过了一遍) 一. 实验任务(实验题目.目的) 实现5种排序(冒泡.希尔.堆排.基数.快排) ...

  9. 主要的七种排序(快排、希尔排序、堆排序、归并排序、选择排序、插入排序、冒泡排序)

    一.冒泡排序 冒泡排序是最简单的排序,不需要额外空间,时间复杂度为O(N^2):代码如下 import java.util.Arrays;public class BubbleSort {public ...

最新文章

  1. java中的类加载器有,Java自定义的类加载器,java自定义加载,在java中类加载器有以...
  2. 课堂练习课下作业----用户场景分析
  3. 没有bug队——加贝——Python 练习实例 3,4
  4. 服务端和客户端测试连通ip设置记录
  5. STM32F407之资源
  6. 为什么setTimeout(fn,0)有时有用?
  7. jquery分页插件精选
  8. mysql根据id主键查询是找到了就不再遍历后面的数据了吗_MySQL索引相关
  9. DIY多快充协议太阳能充电器!----锂电池充电电路
  10. 小作业-drawline换成drawrectangle和fillRectangle
  11. 解决关灯游戏(Lights Off)
  12. C# 字符串转JSON格式
  13. Vue+ bootStrap 实现员的增删改查 离职操作 全选单选
  14. MATLAB的人工神经网络应用
  15. m3u8 文件代码片段.
  16. 最好用的mac免费PDF阅读器是什么?
  17. 微程序控制器之微程序控制器构成
  18. 竞价推广效果不好,是哪些方面影响的呢?
  19. 风雨二十载:OpenGL 4.3规范发布
  20. 最新前端体系学习路径推荐(内附免费资料)

热门文章

  1. WinCE中断结构分析
  2. 机器学习经典算法之线性回归sklearn实现
  3. OpenGL帧缓存对象(FBO:Frame Buffer Object)(转载)
  4. Hyperledger Fabric 1.2 --- Chaincode Operator 解读和测试(一)
  5. 《算法图解》第四章笔记与课后练习_快速排序算法
  6. Python2.7基础知识点思维导图
  7. ntp时间服务器配置
  8. (How to)Windows Live Writer插入Latex公式
  9. 运行python-thrift的DEMO
  10. ORA-27301 解决一例