这篇文章只是简单使用java concurrent库写了个二维数组运算,并无什么实际意义和技术可言,请仅把我当做标题党。 更有价值的东西来自于以下留言:
Cappuccino 写道
文章的名字叫做《矩阵的并行运算》。既然叫这个名字,关键字想必应该和矩阵,或者是并行计算相关。但是通篇里面除了一个二维数组的简单加减运算,和JDK里面现成的线程池以外,没看到什么其他太多的东西。
个人认为整篇东西里面很多东西都很值得深入的,譬如线程中的互斥是怎样实现的,lock、开关量,或者是Atom变量。或者是矩阵,可以尝试有没有其他更好,更有效率的办法。如果是深入JDK的一些办法,也可以尝试看一下源码,TreeMap和HashMap到底有什么不同,为什么选这个,另外Collections.synchronizedMap是怎样实现的,让一个集合可以变为同步的。
感觉上Java最大的误导是导致使用Java的人认为他们可以用JDK实现非常非常多的东西,但实际上我们都只是在用着Sun实现的很多东西罢了,而且也并没有去弄清楚一下一个东西它内部是怎样做的,怎么样才是最好最有效的。建议你可以尝试深入很多东西,多弄点底层的东西也算是好事,毕竟软件也是相对越底层相对越吃香的o(∩_∩)o
----------------------------------------------------------------------
原文:
最近正被项目的并发问题搞得焦头烂额,在封装的语义和项目需求上似乎都出现了问题,迟迟实现不了。昨天无意中看到
这个招聘题,挺有意思的。出题人的本意可能是想考考时下流行的并行运算,受限于CPU,在PC上这种纯运算的效果并不明显,但并发倒是以后的一种趋势…
引用
- 使用Java多线程实现下述算法:
输入:整数组成的m*n的矩阵A。(m=100000, n=10000)
输出:一个数列B,数列B中的每一项为矩阵A中对应列数字之和
CPU的核心是越来越多了,以后并行运算是一种趋势,越来越多的程序需要考虑使用并行运算来加速,硬件厂商给了我们翻倍的CPU,而不是翻倍的速度,真麻烦
……
首先定义一个类,就叫做MatrixSolver吧
package fyting.iteye.com;
public class MatrixSolver
{
private final int[][] matrix;
private final int maxThreads;
private final Map<Integer, Integer> results = Collections.synchronizedMap(new TreeMap<Integer, Integer>());
public void start(){
//...
}
}
写一个main方法来测试:
public static void main(String[] args)
{
final int row = 5000, column = 2000;
final int[][] data = new int[row][column];
for(int i = 0 ; i < row; i++) {
for(int j = 0; j < column; j++) {
data[i][j] = j;
}
}
final int maxThreads = 3;
MatrixSolver solver = new MatrixSolver(maxThreads, data);
solver.start();
}
然后是实现的代码,利用JDK5的线程池,可以很轻松实现:
(事实上,JDK里CyclicBarrier的javadoc就是一个解矩阵的例子)
public void start()
{
ExecutorService executor = Executors.newFixedThreadPool(maxThreads);
final long st = System.nanoTime();
if(this.matrix.length == 0) {
System.err.println("no matrix data!");
return;
}
final int columnCount = this.matrix[0].length;
final CountDownLatch latch = new CountDownLatch(columnCount);
for(int i = 0 ; i < columnCount; i++) {
final int column = i;
executor.execute(newTask(column,latch));
}
try {
latch.await();
executor.shutdown();
long et = System.nanoTime();
long time = (et - st) / (1000*1000);
System.out.println("success, time: " + time + "ms");
executor.awaitTermination(1, TimeUnit.SECONDS);
}
catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("maxtrix: " + (matrix.length + "*" + matrix[0].length));
System.out.println("column0==>" + ArrayUtils.toString(matrix[0]));
System.out.println("results==>" + results);
}
protected Runnable newTask(int column, CountDownLatch latch)
{
return new ColumnSolver(column,latch);
}
private class ColumnSolver extends Thread
{
private final int columnIndex;
private final CountDownLatch latch;
ColumnSolver(int columnIndex, CountDownLatch latch)
{
this.columnIndex = columnIndex;
this.latch = latch;
}
@Override
public void run()
{
int count = 0;
for(int j = 0, rowCount = matrix.length; j < rowCount; j++) {
count += matrix[j][columnIndex];
}
results.put(columnIndex, count);
latch.countDown();
}
}
当然,如果是JDK1.4,可以用单独的
Doug Lea大师写的java concurrent包,否则需要自己实现线程池了,很麻烦。如下面这样的代码,很容易出错,实在是没有必要在项目中采用。
class ThreadPool
{
private final LinkedList<Runnable> tasks = new LinkedList<Runnable>();
private final Thread[] workers;
public ThreadPool(int maxThreads)
{
if(maxThreads <= 0) throw new IllegalArgumentException("maxThreads must > 0");
this.workers = new Thread[maxThreads];
for(int i = 0; i < maxThreads; i++) {
workers[i] = new WorkThread();
workers[i].start();
}
}
private class WorkThread extends Thread
{
public void run() {
Runnable r;
while(true) {
synchronized(tasks) {
while (tasks.isEmpty()) {
try
{
tasks.wait();
}
catch (InterruptedException ex)
{
// ex.printStackTrace();
return;
}
}
r = (Runnable) tasks.removeFirst();
}
try {
r.run();
}
catch (RuntimeException e) {
e.printStackTrace();
}
synchronized(ThreadPool.this) {
ThreadPool.this.notifyAll();
// System.out.println(tasks.size() + " remaining");
}
}
}
}
synchronized void waitAndShutdown() throws InterruptedException
{
while(this.tasks.size() != 0) {
wait();
}
for(Thread t: workers) {
synchronized(t) {
t.interrupt();
}
}
}
public void submit(Runnable runnable)
{
synchronized(this.tasks) {
this.tasks.addLast(runnable);
this.tasks.notify();
}
}
}
附件中有3个不同的类,分别是利用JDK1.5和JDK1.4,以及单线程的实现。
分享到:
相关推荐
矩阵乘法mpi实现 并行运算 在linux下成功运行 使用mpicc -o 编译 使用mpirun命令运行
C#网络编程作业A.3
大矩阵乘法运算的并行算法实现 ......................................... ................................................ .....................................................
编写一个WPF应用程序,利用数据...(1)在代码中用多任务通过调用某方法实现矩阵并行运算,在调用的参数中分别传递M、N、P的大小。 (2)程序中至少要测试3次有代表性的不同大小的矩阵运算,并显示其并行运行用时。
有助于学习并行程序开发 可以在本机上或者巨型机上运行
Mali-T604 GPU的二维浮点矩阵运算并行优化方法.pdf
保计算精度,根据GPU特点设计矩阵分块方式和内存分配机制来减少对数据访问频次,以发挥GPU的并行体系结构 特性来提高计算速度。实验结果表明此方法能够取得较好的效果,可大大提升大型矩阵乘法的运算速度和精度。
包含各类矩阵运算(转置、乘积、cannon乘法、LU分解、QR分解奇异值分解 cholesky分解、求逆)的串行、并行算法以及伪代码。
C语言并行计算-矩阵相乘-MPI矩阵运算,C语言代码,可运行。
矩阵相乘FOX并行算法,矩阵相乘FOX并行算法
使用Win32 API的相关知识实现矩阵的乘法运算,使用C++编写的并行实现矩阵的乘法运算
CPU-OpenMP和GPU-CUDA并行计算技术对矩阵乘法运算的加速效果分析.pdf
声明,所以同一个block中的所有threads都可见,//每个thread填充一个元素,并计算// 每个block包含16 * 16 个线程,所以每个线程负责
滑动卷积矩阵乘计算非常的费时,完成一个卷积神经网络模型的训练往往需要消耗大量的时间,针对这个问题,本次实验将构建一个基于CUDA架构的编程环境,采用CUDA/C++编程实现二维的卷积的并行计算,通过对比GPU实现与...
嵌入式计算作为新一代计算...此外,FPGA厂商也推出了一定规模的浮点矩阵运算IP核[2],虽然此IP核应用了本厂家的器件,并经过专业调试和硬件实测,性能稳定且优于手写代码,但仍可对其进行改进,以进一步提高运算速度。
分别使用串行、并行方法计算矩阵乘法,对比两者的执行时间
对集成于处理器上的MaliT604嵌入式GPU的GPGPU(GeneralPurpose computation on GPU)技术进行研究,并对不同运算规模的浮点矩阵乘法进行并行加速优化,提供实际测试结果。
代码使用C++语言,通过mic实现D=A*B+C矩阵运算,A与B分别是n*m与m*n矩阵,C为n*n矩阵,代码已经过实际调试。
VC里面实现矩阵运算的代码,VC++,希望对大家有帮助