Nel
precedente articolo abbiamo indicato l'utilizzo dei thread pool come una buona scelta per implementare la moltiplicazioni di matrici in parallelo. L'idea che è alla base di questo programma è quello di affidare a ogni thread del pool pezzi di matrici, esattamente di dimensioni
(n/2)x(n/2), su cui effettueremo le operazioni di
moltiplicazione e addizione, inoltre assumiamo per semplicità che
n sia una potenza di due.
Ad esempio, se dobbiamo effettuare un prodotto tra due matrici A e B e la relativa matrice prodotto P di dimensioni 16x16, avremo quattro sottomatrici 4x4 sia per A che per B; nel caso di A esse saranno
A00,
A01,
A10,
A11, e in maniera analoga indicheremo in questo modo le sottomatrici di B e P. Il prodotto
P00, che equivale alle prime quattro righe e colonne della matrice P, sarà:
Analogo ragionamento si può fare per le altre tre parti di P. Quindi abbiamo bisogno di realizzare una struttura dati
Matrix, che oltre a inglobare la matrice vera e propria, includa i vari metodi
get e
set per poter lavorare sui singoli elementi e un metodo
split, che scompone la nostra matrice
nxn in quattro sottomatrici
(n/2)x(n/2), con un'implementazione analoga al listato seguente:
public class Matrix{
private int dim;
private double[][]data;
private int rowDisplace,colDisplace;
public Matrix(int d){ dim=d;
rowDisplace=colDisplace=0;
data= newdouble[d][d];
}
private Matrix(double[][]matrix, int x, int y, int d){ data=matrix;
rowDisplace=x;
colDisplace=y;
dim=d;
}
public double get(int row, int col){ return data[row+rowDisplace][col+colDisplace];
}
public void set(int row, int col, double value){ data[row+rowDisplace][col+colDisplace]=value;
}
public int getDim(){ return dim;
}
public Matrix[][]split(){ Matrix[][]result= new Matrix[2][2];
int newDim=dim/2;
result[0][0]=
new Matrix(data,rowDisplace,colDisplace,newDim);
result[0][1]=
new Matrix(data,rowDisplace,colDisplace+newDim,newDim);
result[1][0]=
new Matrix(data, rowDisplace+newDim,colDisplace,newDim);
result[1][1]=
new Matrix(data,rowDisplace+newDim,colDisplace+newDim,newDim);
return result;
}
}
Tale struttura verrà utilizzata nei task di addizione e moltiplicazione, che interagiranno con la logica del prodotto di matrici implementato con il
thread pool.