Es geht derzeit bei uns um parallele Verarbeitung und jetzt sollen wir eine parallele Implementierung von 2 Algorithmen einmal praktisch umsetzen. Ich komme aber wohl anscheinend mit dem angegebenen Algorithmus klar. Der eine verwendet dann nämlich die transponierte Matrix von b und die Berechnung sieht so aus:
Das dann noch so in zwei Schleifen eingepackt, wovon die in dem Bild oben parallelisiert werden soll.
Ich habe für die Matrix extra eine eigene Klasse geschrieben und bei dem Member data handelt es sich um das Arrray das die Matrix hält. Der "threadPoolExec" ist ein ThreadPoolExecutor aus dem java.util.concurrent Package und wofür rowsMatA und wofür colsMatB steht sollte ja klar sein.
Leider kriege ich aber mit der obigen Implementierung (falls meine richtig ist, was wohl nicht der Fall ist ... ) immer das falsche Ergebnis raus. Ich habe das ganze auch einmal in "normal" implementiert, also mit 3 Schleifen und dann die innerste parallel, auch mit dem ThreadPoolExecutor als Hilfsmittel und da kriege ich das richtige Ergebnis raus. Die Ergebnisse sollten ja identisch sein?
Wenn ich die Matrizen habe (Darstellung als 2D Array in Java)
dann sollte doch
dabei rauskommen, oder nicht?
Ich kriege aber mit der obigen Implementierung
herraus.
Mit dem normalen Alg. kriege ich das, wie gesagt heraus und ebenfalls dasselbe auch per Hand und online. Was mache ich also falsch? Mich wundert das aber auch ehrlich gesagt, dass das wohl mit 2 Schleifen laufen soll? Geht das überhaupt?
Ich habe, wie schon gesagt die Matrix B vorher transponiert aber kann man das mit nur 2 Schleifen dann nachher überhaupt berechnen? Die Variante habe ich jedenfalls so vorher noch nie verwendet und auch gesehen.
Die zweite Variante soll so aussehen:
Dabei wird dann die äußere Schleife parallelisiert. Da wird dann wohl mit dem transponierten Spaltenvektor gerechnet aber da habe ich mich noch nicht rangemacht. Da frage ich mich allerdings auch wieder, ob das überhaupt mit 2 Schleifen geht? Müsste man da nicht auch nohh erst den Spaltenvektor transponieren, also noch einmal 2 Schleifen dazu? Bei dem anderen steht vorher noch explizit davor, dass r = b^T sein soll, also die transponierte Matrix von B.
Wir sollen auch noch eine Aussage zur Laufzeit der beiden Algorithmen machen und sagen, welcher von beiden dann wohl besser sein soll und auch im Vergleich zum "normalen" Algortihmus, wo man dann einfach 3 Schleifen hat, also so:
Wenn das wirklich mit 2 Schleifen bei der Berechnung funktioniert, dann müsste der erste doch der beste sein oder nicht? Da hätte man dann ja nicht mehr eine Laufzeit von n^3, wobei n die Anzahl der Zeilen und Spalten ist. Bei dem zweiten hätte man ja (meiner Meinung nach) ja noch 2 zusätzliche Schleifen, was ja auf jeden Fall schlechter ist als der erste und auch schlechter als der "normale". Liege ich damit richtig?
c ist dabei ein 2D-Array, woraus ich nachher ebenfalls dann ein Matrix Objekt erzeuge und matA und matB sind schon Matrix Objekte, weswegen ich da ja ein matA.data stehen habe, da es sich dabei um das 2D-Array des Matrix Objektes handelt. Nur noch einmal zur Klarstellung.
Das dann noch so in zwei Schleifen eingepackt, wovon die in dem Bild oben parallelisiert werden soll.
Java:
for(i = 0; i < rowsMatA; i++) {
final int iFin = i;
threadPoolExec.execute(new Runnable() {
@Override
public void run() {
for(int j = 0; j < colsMatB; j++) {
c[iFin][j] = matA.data[iFin][0] * r.data[0][j];
}
}
});
}
Ich habe für die Matrix extra eine eigene Klasse geschrieben und bei dem Member data handelt es sich um das Arrray das die Matrix hält. Der "threadPoolExec" ist ein ThreadPoolExecutor aus dem java.util.concurrent Package und wofür rowsMatA und wofür colsMatB steht sollte ja klar sein.
Leider kriege ich aber mit der obigen Implementierung (falls meine richtig ist, was wohl nicht der Fall ist ... ) immer das falsche Ergebnis raus. Ich habe das ganze auch einmal in "normal" implementiert, also mit 3 Schleifen und dann die innerste parallel, auch mit dem ThreadPoolExecutor als Hilfsmittel und da kriege ich das richtige Ergebnis raus. Die Ergebnisse sollten ja identisch sein?
Wenn ich die Matrizen habe (Darstellung als 2D Array in Java)
Code:
{{2,4},{6, 8}});
{{4,6},{8,10}});
dann sollte doch
Code:
{{40,52},{88,116}});
Ich kriege aber mit der obigen Implementierung
Code:
{{0,16},{24,48}});
Mit dem normalen Alg. kriege ich das, wie gesagt heraus und ebenfalls dasselbe auch per Hand und online. Was mache ich also falsch? Mich wundert das aber auch ehrlich gesagt, dass das wohl mit 2 Schleifen laufen soll? Geht das überhaupt?
Ich habe, wie schon gesagt die Matrix B vorher transponiert aber kann man das mit nur 2 Schleifen dann nachher überhaupt berechnen? Die Variante habe ich jedenfalls so vorher noch nie verwendet und auch gesehen.
Die zweite Variante soll so aussehen:
Dabei wird dann die äußere Schleife parallelisiert. Da wird dann wohl mit dem transponierten Spaltenvektor gerechnet aber da habe ich mich noch nicht rangemacht. Da frage ich mich allerdings auch wieder, ob das überhaupt mit 2 Schleifen geht? Müsste man da nicht auch nohh erst den Spaltenvektor transponieren, also noch einmal 2 Schleifen dazu? Bei dem anderen steht vorher noch explizit davor, dass r = b^T sein soll, also die transponierte Matrix von B.
Wir sollen auch noch eine Aussage zur Laufzeit der beiden Algorithmen machen und sagen, welcher von beiden dann wohl besser sein soll und auch im Vergleich zum "normalen" Algortihmus, wo man dann einfach 3 Schleifen hat, also so:
Java:
for(i = 0; i < rowsMatA; i++) {
for(j = 0; j < colsMatB; j++) {
for(k = 0; k < rowsMatB; k++) {
c[i][j] += matA.data[i][k] * matB.data[k][j];
}
}
}
Wenn das wirklich mit 2 Schleifen bei der Berechnung funktioniert, dann müsste der erste doch der beste sein oder nicht? Da hätte man dann ja nicht mehr eine Laufzeit von n^3, wobei n die Anzahl der Zeilen und Spalten ist. Bei dem zweiten hätte man ja (meiner Meinung nach) ja noch 2 zusätzliche Schleifen, was ja auf jeden Fall schlechter ist als der erste und auch schlechter als der "normale". Liege ich damit richtig?
c ist dabei ein 2D-Array, woraus ich nachher ebenfalls dann ein Matrix Objekt erzeuge und matA und matB sind schon Matrix Objekte, weswegen ich da ja ein matA.data stehen habe, da es sich dabei um das 2D-Array des Matrix Objektes handelt. Nur noch einmal zur Klarstellung.
Zuletzt bearbeitet: