如何在java中转换矩阵(并行/多线程)
我们都知道矩阵转置是多么有用,编写一个用于顺序使用的通用算法是没有问题的。然而,为了多线程的目的,我在做同样的事情时遇到了一些问题,并且只有4 x 4的小案例才能正常工作 我的方法是将双[][]结构的相等部分(在本例中为2x2)分配给四个线程中的每一个。在这种情况下,这意味着起始位置为0,0&0,2&2,0&2,2。这是通过“kol”和“rad”传入的 然而,我不能让这个在更大的矩阵上工作,所以任何帮助都将不胜感激。我找到的这个问题最接近的答案是: 这也是我将双[][]结构分为四个部分的灵感。我的(正在工作的)4x4代码可以在下面找到,那么我如何修改它以使其适用于四个线程呢 干杯如何在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”传入的 然而,我不能让这个在更大的矩阵上工作,所以任何帮助都将不胜感激。我找到的这个问题最接近的答案是: 这也是我将双[][]结构分为四个部分的灵感。我
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;
}