如何在java中转换矩阵(并行/多线程)

如何在java中转换矩阵(并行/多线程),java,multithreading,matrix,parallel-processing,transpose,Java,Multithreading,Matrix,Parallel Processing,Transpose,我们都知道矩阵转置是多么有用,编写一个用于顺序使用的通用算法是没有问题的。然而,为了多线程的目的,我在做同样的事情时遇到了一些问题,并且只有4 x 4的小案例才能正常工作 我的方法是将双[][]结构的相等部分(在本例中为2x2)分配给四个线程中的每一个。在这种情况下,这意味着起始位置为0,0&0,2&2,0&2,2。这是通过“kol”和“rad”传入的 然而,我不能让这个在更大的矩阵上工作,所以任何帮助都将不胜感激。我找到的这个问题最接近的答案是: 这也是我将双[][]结构分为四个部分的灵感。我

我们都知道矩阵转置是多么有用,编写一个用于顺序使用的通用算法是没有问题的。然而,为了多线程的目的,我在做同样的事情时遇到了一些问题,并且只有4 x 4的小案例才能正常工作

我的方法是将双[][]结构的相等部分(在本例中为2x2)分配给四个线程中的每一个。在这种情况下,这意味着起始位置为0,0&0,2&2,0&2,2。这是通过“kol”和“rad”传入的

然而,我不能让这个在更大的矩阵上工作,所以任何帮助都将不胜感激。我找到的这个问题最接近的答案是:

这也是我将双[][]结构分为四个部分的灵感。我的(正在工作的)4x4代码可以在下面找到,那么我如何修改它以使其适用于四个线程呢

干杯

public double[][] transponerMatrise(double[][] matrise, int rad, int 
kol, int id)
{
  if((id != 2))
   {
      for (int i = rad; i < n/2 + rad; i++)
      {
        for (int j = kol+1; j < n/2 + kol; j++)
        {
          System.out.println("Traad " + id + " bytter " + i + "," + j + " med " + j + "," + i);
          System.out.println("Value is " + matrise[i][j] + ", " + matrise[j][i]);
            element = matrise[i][j];
            matrise[i][j] = matrise[j][i];
            matrise[j][i] = element;
        }
      }
    }
    else
    {
      for (int i = rad; i < n/2 + rad-1; i++)
      {
        for (int j = kol; j < n/2 + kol; j++)
        {
          System.out.println("Traad " + id + " bytter " + i + "," + j + " med " + j + "," + i);
          System.out.println("Value is " + matrise[i][j] + ", " + matrise[j][i]);
            element = matrise[i][j];
            matrise[i][j] = matrise[j][i];
            matrise[j][i] = element;
        }
      }
    }
    return matrise;
}
public double[][]转置矩阵(double[][]矩阵,int-rad,int)
kol,int id)
{
如果((id!=2))
{
对于(int i=rad;i
PS:我知道代码可以正常工作,因为我有一种针对工作顺序变量的检查方法。

这是一场先验的与O(N^2)
成本函数的失败之战 如果我可以把你的注意力转到一个更聪明的方法上,成本几乎是
O(1)
(恒定的),这个技巧将帮助你开始朝着一个更有希望的方向工作

可以尝试在矩阵元素的高性能调优(缓存线友好)的“原始”存储之上添加一个精简的抽象层。此抽象层将有助于访问“原始”存储(使用索引轴、索引跨距和切片技巧-与HPC FORTRAN库启发了著名的
及其跨距技巧的方法非常相似),这样
.T
方法就不会产生任何昂贵的效果(类似于推土
N^2
内存位置,在那里和后面交换)但只需交换抽象层中的轴参数,负责间接映射器,对于任何大的
矩阵[N,N]都需要几十纳秒;其中N=10100100010000 100000 10000000+
仍然一些
[ns]


做这个或其他更复杂的矩阵运算没有什么比这更快的了,FORTRAN和
numpy
,性能优化,方法本身就是这种观察的证明。

使用线程将行交换为列可能是一个简单的想法,但因此你需要两倍的内存来存储矩阵,这可能是一个专业的巨大矩阵上的问题。另外,如果您有一个6核CPU,我认为使用100线程没有多大好处,因此我的线程池非常小。正如@user3666197所提到的,这仍然是一个昂贵的解决方案-但并行;-)

import java.util.concurrent.CountDownLatch;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公共类矩阵传输{
公共静态void main(最终字符串[]args)引发InterruptedException{
最终MatrixTransposition transposition=新MatrixTransposition();
final int[][]source=transposition.create(32);
final int[][]transposed=transposition.solve(源代码);
System.out.println(“比较源和转置=“+transposition.Compare(源,转置));
最终int[][]结果=转置.solve(转置);
System.out.println(“比较源和双转置=“+transposition.Compare(源,结果));
转置打印(来源);
转置打印(转置);
}
公共布尔比较(最终整数[][]a,最终整数[][]b){
for(int r=0;rimport java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MatrixTransposition {

    public static void main(final String[] args) throws InterruptedException {
        final MatrixTransposition transposition = new MatrixTransposition();
        final int[][] source = transposition.create(32);
        final int[][] transposed = transposition.solve(source);
        System.out.println("Compare source and transpositon = " + transposition.compare(source, transposed));
        final int[][] result = transposition.solve(transposed);
        System.out.println("Compare source and double transpositon = " + transposition.compare(source, result));

        transposition.print(source);
        transposition.print(transposed);
    }

    public boolean compare(final int[][] a, final int[][] b) {
        for (int r = 0; r < a.length; r++) {
            for (int c = 0; c < a[0].length; c++) {
                if (a[r][c] != b[r][c]) return false;
            }
        }
        return true;
    }

    public int[][] create(final int size) {
        final int[][] result = new int[size][size];
        for (int r = 0; r < size; r++) {
            for (int c = 0; c < size; c++) {
                result[r][c] = r * size + c;
            }
        }
        return result;
    }

    public void print(final int[][] input) {
        final int size = input.length;
        final int maxNr = size * size;
        final int digits = new String(maxNr + "").length();
        final String cellFormat = "%0" + digits + "d ";

        for (int r = 0; r < input.length; r++) {
            final int[] row = input[r];
            for (final int c : row) {
                System.out.print(String.format(cellFormat, c));
            }
            System.out.println("");
        }

        System.out.println("");
    }

    public int[][] solve(final int[][] input) throws InterruptedException {
        final int width = input.length;
        final int height = input[0].length;

        final int[][] result = new int[width][height];
        final CountDownLatch latch = new CountDownLatch(width);
        for (int r = 0; r < width; r++) {
            final int row = r;
            threadPool.execute(() -> {
                solvePart(result, input, row);
                latch.countDown();
            });
        }

        latch.await();
        return result;
    }

    private void solvePart(final int[][] result, final int[][] input, final int r) {
        System.out.println("Solve row " + String.format("%02d", r) + " in thread " + Thread.currentThread().getName());
        final int[] row = input[r];
        for (int c = 0; c < row.length; c++) {
            result[c][r] = row[c];
        }
    }
    private final ExecutorService threadPool = Executors.newFixedThreadPool(6);
}
public class Matrix {

        private class Index {
            Index(final int row, final int col) {
                super();
                this.row = row;
                this.col = col;
            }

            int col;
            int row;
        }

        public Matrix(final int rows, final int cols) {
            this.rows = rows;
            this.cols = cols;
            data = new int[rows][cols];
        }

        public int get(final int row, final int col) {
            return get(getIndex(row, col));
        }

        public void set(final int row, final int col, final int value) {
            set(getIndex(row, col), value);
        }

        public void transpose() {
            transpositioned = !transpositioned;
        }

        private int get(final Index index) {
            return data[index.row][index.col];
        }

        private Index getIndex(final int row, final int col) {
            return transpositioned ? new Index(col, row) : new Index(row, col);
        }

        private void set(final Index index, final int value) {
            data[index.row][index.col] = value;
        }

        private final int cols;
        private final int[][] data;
        private final int rows;
        private boolean transpositioned;

    }