算法学习:并行化初体验_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安装与初体验 学习前 搞懂一些关系和概念 首先,搞清楚一个关系:深度学习的前身是人工神经网络,深度学习只是人工智能的一种,深层次的神经网络结构就是深度学习的模型,浅层次的 ...
随机推荐
- 响应式布局 —— Demo
响应式布局实例演示What is 响应式布局? 响应式布局是Ethan Marcotte在2010年5月份提出的一个概念,简而言之,就是一个网站能够兼容多个终端--而不是为每个终端做一个特定的版本.这 ...
- XAMPP启动MySQL时报端口被占用错误
1 问题描述 启动XAMPP中的mysql时宝凑,错误信息是:3306端口被占用 2 问题诊断 2.1 可能是在安装XAMPP之前安装了MySQL,这样电脑中就有两个MySQL啦,如果我们在安装时都采 ...
- 【HOSTS相关】什么时候使用127.0.0.1
什么时候使用127.0.0.1 在测试环境,如果想知道上线后服务发生异常中断的情况下界面会如何展示,这个时候有2种方式: 第1种是:由开发人员协助,比如后台开发人员在服务器上使这个服务停止,或者由前端 ...
- CentOS7开机提示welcome to emergency mode!after logging in...
CentOS7.3昨天用的还好好的的,但是今天开机提示如下(如图提示): welcome to emergency mode!after logging in ,type "journalc ...
- 删除oracle数据库[转]
--===================== -- 手动删除oracle数据库 --===================== 在很多情况下,或无法使用dbca工具的时候,我们需要手动来删除数据库. ...
- Java字符串操作
最近翻看之前的东西,发现有些看似简单的东西竟然忘的差不多了,记录一下对字符串大小写转换的操作. 打印结果
- Myeclipse和windows调节成护眼色
作为程序员,对着电脑屏幕久了,眼睛难免疲劳,下面相信对我们每个 人都很有帮助. windows xp:桌面空白处右键,属性,外观-高级,然后在项目那栏选窗口,再点颜色-其它,然后把色调设为85(默认是 ...
- 修改(同步)linux时间
新申请下来的机器的时间现在我们所在的时区不一致,需要同步成东八区 查看当前的时间: date -R; date +%z 修改时区: cp /usr/share/zoneinfo/Asia/Shangh ...
- 【Ubuntu 16】启动Eclipse Indigo报错 error code1 jdk没有配置好
在/etc/profile下配置好JAVA_HOME CLASSPATH PATH 这些变量后 eclipse启动jvm并不能直接按照这些变量来启动 需要使用命令 update-alternative ...
- ASP.NET Core 运行原理解剖[2]:Hosting补充之配置介绍
在上一章中,我们介绍了 ASP.NET Core 的启动过程,主要是对 WebHost 源码的探索.而本文则是对上文的一个补充,更加偏向于实战,详细的介绍一下我们在实际开发中需要对 Hosting 做 ...