多线程矩阵乘法

时间:2014-05-11 15:06:25

标签: java multithreading concurrency runnable

我正在尝试比较sequantial和concurent矩阵乘法。每次顺序都更快。例如60 x 60矩阵sequantial找到4 ms而concurent 277 ms。在我的代码中出错了?

concurent:

private static void multiplyMatrixConcurent() {
     result_concurent =new Matrix(rows, columns);

     for (int i = 0; i < cell; i++) {
         Runnable task = new MatrixMultiplicationThread(i);
         Thread worker = new Thread(task);
         worker.start();


    }


}

private static class MatrixMultiplicationThread implements Runnable{
         private int cell;

         MatrixMultiplicationThread(int cell) {
             this.cell=cell;
            }
         @Override
            public void run() {
             int row = cell / columns ;
             int column = cell % columns;
                for (int i = 0; i < rows; i++) {
                        double t1 = matrix.getCell(row, i);
                        double t2=  matrix.getCell(i, column);
                        double temp= t1*t2;
                        double res = result_concurent.getCell(row, column) +temp;
                        result_concurent.setCell(res, row, column);


                }

            }

     }

顺序:

private static void multiplyMatrixSequence() {
     result_sequantial =new Matrix(rows, columns);
     for (int i = 0; i < rows; i++) {
        for (int j = 0; j <rows; j++) {
            for (int k = 0; k < columns; k++) { 
                double t1=matrix.getCell(i,k);
                double t2=matrix.getCell(k, j);

                double temp= t1*t2;
                double res = result_sequantial.getCell(i, j) + temp;
                result_sequantial.setCell(res,i,j);
            }
        }
    }

}

2 个答案:

答案 0 :(得分:3)

我没有看到任何明显错误的东西。您没有在发布的并发启动代码中将单元格设置为行*列,但我认为这是发布中的问题,而不是您运行的代码。

线程有开销。它们具有分配内存并需要额外管理CPU资源。如果线程数量适中且硬件可以并行处理多个线程,那么您就赢了。但是,对于纯cpu绑定任务,拥有比处理元素更多的线程只是开销而没有任何收益。在这种情况下,您有3600个线程。我猜你有一个可以同时处理2到8个线程的处理器。你的线程数使得处理器的能力相形见绌,因此你的速度会慢下来。

请注意,当线程执行阻塞操作(如磁盘或网络I / O)时,更多线程可以允许交错。这些陈述也不适用于GPU计算案例,即使是内存访问也允许有效的线程交错。

顺便说一句,如果您的目标实际上是生成快速矩阵乘法 - 使用现有的库。这些库是由那些利用处理器缓存结构,专用硬件指令集和浮点细微细节的人开发的,可以生成比休闲编码器生成的文件更快,更准确的库。

答案 1 :(得分:3)

创建线程需要一些时间(与其他操作相比,它很昂贵)。您可以使用ThreadPool并重用现有(已完成)线程,而不是为每个单元格创建新线程。这减少了创建新线程的时间。但是,每个线程场景的执行时间仍然非常短,设置线程比顺序运行需要更多的时间。

private static void multiplyMatrixConcurent() {
   result_concurent =new Matrix(rows, columns);
   ExecutorService executor = Executors.newFixedThreadPool(4);
   for (int i = 0; i < cell; i++) {
     Runnable worker = new MatrixMultiplicationThread(i);
     executor.execute(worker);
   }
   executor.shutdown();
}