算法学习:并行化初体验_JAVA实现并行化归并算法
这个系列包括算法导论学习过程的记录。
最初学习归并算法,对不会使其具体跑在不同的核上报有深深地怨念,刚好算倒重温了这个算法,闲来无事,利用java的thread来体验一下并行归并算法。理论上开的thread会被分配在不同的核上(核没用完的情况下)。当然利用c++来实现更好,这里主要体验一下思路。
=========================================================
- 基本Merge Sort
Merge Sort的具体思路不再详诉,将其包装为MergeSort类.
public class MergeSort {
public static void sort(int[] numbers){
sort(numbers,0,numbers.length);
}
public static void sort(int[] numbers,int pos,int end){
if ((end - pos) > 1) {
int offset = (end + pos) / 2;
sort(numbers, pos, offset);
sort(numbers, offset, end);
merge(numbers, pos, offset, end);
}
}
public static void merge(int[] numbers,int pos,int offset,int end){
int[] array1 = new int[offset - pos];
int[] array2 = new int[end - offset];
System.arraycopy(numbers, pos, array1, 0, array1.length);
System.arraycopy(numbers, offset, array2, 0, array2.length);
for (int i = pos,j=0,k=0; i < end ; i++) {
if (j == array1.length) {
System.arraycopy(array2, k, numbers, i, array2.length - k);
break;
}
if (k == array2.length) {
System.arraycopy(array1, j, numbers, i, array1.length - j);
break;
}
if (array1[j] <= array2[k]) {
numbers[i] = array1[j++];
} else {
numbers[i] = array2[k++];
}
}
}
}
- 并行Merge Sort
并行实现Merge Sort的大体思路为将原来递归拆分其中的一部分换成新开的线程来接管,也就是拆分成一些子串,给不同的核心来处理。
以我的电脑(RMBP Late2013 i5 4258u)为例,其有4个可用核。 递归拆分2次,也就是拆分成4个子串。然后分别在四个核上利用Merge sort对这些子串进行排序。完成后利用同步工具CountDownLatch来提示完成任务,父进程Merge两个已经排好的子串。
示意图如下:
将其包装为MergeParallelSort类如下:
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class MergeParallelSort {
// 最大可并行深度,为log处理器数
private static final int maxParallelDepth = (int) (Math.log(Runtime.getRuntime().availableProcessors())
/ Math.log(2));
public static void sort(int[] numbers) {
sort(numbers, 0, numbers.length, maxParallelDepth);
}
public static void sort(int[] numbers , int parallelDepth) {
sort(numbers, 0, numbers.length, parallelDepth);
}
public static void sort(int[] numbers, int start, int end) {
sort(numbers, start, end, maxParallelDepth);
}
public static void sort(int[] numbers, int start, int end, int parallelDepth) {
sortParallel(numbers, start, end, parallelDepth > maxParallelDepth ? maxParallelDepth : parallelDepth, 1);
}
/**
* Do Merge Sort in parallel way
*
* @param numbers
* @param start
* @param end
* @param parallelDepth 当前并行深度
* @param depth 当前拆分深度
*/
public static void sortParallel(final int[] numbers, final int start, final int end, final int parallelDepth,
final int depth) {
if ((end - start) > 1) {
//同步工具,等待其两个子线程完成任务后归并
final CountDownLatch mergeSignal = new CountDownLatch(2);
final int offset = (end + start) / 2;
new SortThread(depth, parallelDepth, numbers, mergeSignal, start, offset).start();
new SortThread(depth, parallelDepth, numbers, mergeSignal, offset, end).start();
//等待两个子线程完成其工作
try {
mergeSignal.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
MergeSort.merge(numbers, start, offset, end);
}
}
static class SortThread extends Thread {
private int depth;
private int parallelDepth;
private int[] numbers;
private CountDownLatch mergeSignal;
private int start;
private int end;
/**
* @param depth
* @param parallelDepth
* @param numbers
* @param mergeSignal
* @param start
* @param end
*/
public SortThread(int depth, int parallelDepth, int[] numbers, CountDownLatch mergeSignal, int start, int end) {
super();
this.depth = depth;
this.parallelDepth = parallelDepth;
this.numbers = numbers;
this.mergeSignal = mergeSignal;
this.start = start;
this.end = end;
}
@Override
public void run() {
if (depth < parallelDepth) {
sortParallel(numbers, start, end, parallelDepth, (depth + 1));
} else {
MergeSort.sort(numbers, start, end);
}
mergeSignal.countDown();
}
}
public static void main(String[] args) {
System.out.println("Parallel Merge Sort test");
System.out.println("Processor number:" + Runtime.getRuntime().availableProcessors());
System.out.println("Array Size:10000000");
long time_start, time_end;
long time_para, time_single;
int array[] = new int[10000000];
int array1[] = new int[10000000];
int array2[] = new int[10000000];
Random random = new Random();
for (int i = 0; i < 1000; i++) {
array[i] = random.nextInt(1000000);
}
System.arraycopy(array, 0, array1, 0, array1.length);
System.arraycopy(array, 0, array2, 0, array2.length);
// parallelSort
time_start = System.currentTimeMillis();
MergeParallelSort.sort(array1);
time_end = System.currentTimeMillis();
time_para = time_end - time_start;
// orginalSort
time_start = System.currentTimeMillis();
MergeSort.sort(array2);
time_end = System.currentTimeMillis();
time_single = time_end - time_start;
System.out.println("time_para:" + time_para);
System.out.println("time_single:" + time_single);
System.out.println("Speed up:"+(float)time_single/time_para);
}
}
- 输出示例&总结
尝试过数组大小的几组例子,当输入规模过小(size小于100000),并行化效率会低于直接单核处理,可能是开Thread以及等待其他Thread完成导致。当输入规模大起来,加速比也并非理想的4倍。本身基于JVM写并行化并没有明确地将线程分配到具体的核心,待以后有机会研究,此次只是当作并行化初体验罢。
算法学习:并行化初体验_JAVA实现并行化归并算法的更多相关文章
- 冒泡,快排算法之javascript初体验
引子:javascript实际使用的排序算法在标准中没有定义,可能是冒泡或快排.不用数组原生的 sort() 方法来实现冒泡和快排. Part 1:冒泡排序(Bubble Sort) 原理:临近的两数 ...
- kafka 学习之初体验
学习问题: 1.kafka是否需要zookeeper?2.kafka是什么?3.kafka包含哪些概念?4.如何模拟客户端发送.接受消息初步测试?(kafka安装步骤)5.kafka cluster怎 ...
- Docker学习<一>--初体验Windows环境下安装
背景 今天想试用spring boot与jwt协议的实现,配套就需要使用redis,但redis似乎windows环境版本部署起来不是那么舒心,果断尝试使用docker. 下载 下载地址: 稳定版:h ...
- UITextView(文本视图) 学习之初体验
UITextView文本视图相比与UITextField直观的区别就是UITextView可以输入多行文字并且可以滚动显示浏览全文.常见UITextView使用在APP的软件简介.内容详情显示.小说阅 ...
- Javascript经典算法学习1:产生随机数组的辅助类
辅助类 在几个经典排序算法学习部分,为方便统一测试不同算法,新建了一个辅助类,主要功能为:产生指定长度的随机数组,提供打印输出数组,交换两个元素等功能,代码如下: function ArraySort ...
- 有感FOC算法学习与实现总结
文章目录 基于STM32的有感FOC算法学习与实现总结 1 前言 2 FOC算法架构 3 坐标变换 3.1 Clark变换 3.2 Park变换 3.3 Park反变换 4 SVPWM 5 反馈部分 ...
- 数据结构(逻辑结构,物理结构,特点) C#多线程编程的同步也线程安全 C#多线程编程笔记 String 与 StringBuilder (StringBuffer) 数据结构与算法-初体验(极客专栏)
数据结构(逻辑结构,物理结构,特点) 一.数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关.逻辑结构包括: 集合 数 ...
- (数据科学学习手札35)tensorflow初体验
一.简介 TensorFlow时谷歌于2015年11月宣布在Github上开源的第二代分布式机器学习系统,目前仍处于快速开发迭代中,有大量的新功能新特性在陆续研发中: TensorFlow既是一个实现 ...
- 深度学习之TensorFlow安装与初体验
深度学习之TensorFlow安装与初体验 学习前 搞懂一些关系和概念 首先,搞清楚一个关系:深度学习的前身是人工神经网络,深度学习只是人工智能的一种,深层次的神经网络结构就是深度学习的模型,浅层次的 ...
随机推荐
- 【万能的搜索,用广搜来解决DP问题】ZZNU -2046 : 生化危机 / HDU 1260:Tickets
2046 : 生化危机 时间限制:1 Sec内存限制:128 MiB提交:19答案正确:8 题目描述 当致命的T病毒从Umbrella Corporation 逃出的时候,地球上大部分的人都死去了. ...
- kickstart自动化安装--tftp+nfs+dhcp
使用kickstart实现Centos 自动化安装 Kickstart自动化安装简介: 规模化:同时装配多台 服务器 自动化 :安装系统,配置各种服务 远程实现:不需要光盘,U盘等安装介质 优势: ( ...
- IE浏览器-官网下载地址
这里仅列出IE浏览器在微软官网的下载地址,便于日常使用. WindowsXP | IE6下载地址:http://www.microsoft.com/zh-CN/download/details.asp ...
- 计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和
题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将 ...
- 使用 ESXi 虚拟化 Ryzen 1700
最近开发的一个项目,需要多台机器支持,PC + 各种虚拟机,整得很乱,一怒之下,购买一台Ryzen 1700 + 32GB机器自行搭建服务器.经历两天时间,不停的踩坑,终于完成: Ryzen 1700 ...
- android学习ViewPager的简单使用
使用ViewPager需要引入android.support.v4.View.ViewPager这样的jar包,谷歌公司为解决当前版本碎片化的问题,提供的兼容的包.主要目的就是解决向下兼容问题. 1, ...
- UNIX 技巧: UNIX 高手的另外 10 个习惯
让我们面对现实吧:坏习惯很难改变.但是您已经熟悉的习惯可能更难克服.有时,重新审视某些事情可能让您遇到“啊哈,我没想到它能做到这一点!”的时刻.在 Michael Stutz 的优秀文章“UNIX 高 ...
- Oracle安装oraInventory问题
Oracle安装oraInventory问题-----------------------------2013/10/15 在使用安装Oracle软件或者使用dbca创建数据库时,所有的日志都会放在o ...
- Zim学习笔记 (Fedora)
俗话说好记性不如烂笔头, 对于一个搞IT的人来说最好的笔毫无疑问就应该是电脑了, 但最好的本呢? 之前一直在找一款适合自己的笔记软件, 找来找去只有Zim适合自己, 当然对于有编辑器之神之美誉的ema ...
- java 常用命令工具
1. jmap (1)分析堆信息 jmap -heap java_pid (2) 导出 java进程 5460 的堆内容 到文件 heap.map ,然后使用 jhat 分析 jmap -dump:l ...