==== Aufgabe 1 (Wissensfragen) ==== a) falsch b) richtig (z. B. durch Prüfe-Handle-Situationen) c) falsch d) falsch e) richtig f) Speedup = 6, Effizienz = 3/4 g) falsch (Null ist lediglich Untertyp aller AnyRef-Typen, Nothing ist Untertyp aller Scala-Typen) ====Aufgabe 2 (Petri-Netze) ==== a) S: (1, 1, 0, 0, 0) (Transponiert) M: (-1, 0, 0, 0, 1) ( 1, 2, -1, -1, 0) ( 0, -1, 1, 0, 0) ( 0, -1, 0, 1, 0) ( 0, -1, 0, 1, -1) b) t1 -> t4 -> t3 -> t5 c) Ja d) E: (0, 7, 0, 0) ====Aufgabe 3 (Java - Präfixsumme) ==== a) Gauß-Filter / Weichzeichner (? -> eher Zeigerverdopplung) import java.util.concurrent.*; public class ParallelPrefixSums { private static CyclicBarrier barrier; public static void calculateSums(int[] values) throws InterruptedException { barrier = new CyclicBarrier(values.length); Thread[] workers = new Thread[values.length]; for (int i = 0; i < values.length; i++) { workers[i] = new Thread(new Worker(values, i)); workers[i].start(); } for (int i = 0; i < values.length; i++) { workers[i].join(); } } public static class Worker implements Runnable { private int[] values; private int index; public Worker (int[] values, int index) { this.values = values; this.index = index; } public void run() { try { int distance = 1; while (distance < values.length) { barrier.await(); int target = index + distance; int rem = values[index]; barrier.await(); if (target < values.length) { values[target] += rem; } dist *= 2; } } catch (Exception e) { e.printStackTrace(); } } } } ==== Aufgabe 4 (Schreibtischlauf - Barrieren) ==== * a) a = 1, weil sowohl a++ als auch die System.out.println-Ausgabe in einem synchronized-Block stehen und beide Threads auf dieselbe Marke synchronisieren. * b) Mögliche Ausgaben sind: a=1 a=2 a=3 Threads 1, 2, 3 started. Und a=1 a=2 Threads 1, 2, 3 started. a=3 Der Main-Thread synchronisiert nicht auf irgendeine Marke (insb. nicht auf BarrierTest.class), daher erscheinen ihm die synchronized-Blöcke der Threads nicht als unteilbare Einheit und er kann bereits nach a++, aber vor System.out.println die While-Schleife verlassen. * c) 1, 2, 3, oder 4 Mal. Jeder Thread könnte gleichzeitig b=0 am Anfang feststellen oder erst prüfen, nachdem die anderen Threads (oder ein Teil davon) das IF verlassen. * d) Vorletzte oder letzte Zeile. Der CountDownLatch ist nur mit 3 initialisiert worden. Daher kann sich der letzte Thread irgendwo zwischen barrier.await() und latch.countDown() befinden. ==== Aufgabe 5 (Scala - Snake-Sort) ==== sortAsc, sortDes waren nicht Teil der Aufgabe, sind aber zum Testen implementiert. import System.{ currentTimeMillis => ct } type Row = List[Int] type Matrix = List[Row] def sortAsc: Row => Row = rs => if(rs == Nil) Nil else rs.min :: sortAsc(rs.filter(_ > rs.min)) def sortDes: Row => Row = rs => if(rs == Nil) Nil else rs.max :: sortDes(rs.filter(_ < rs.max)) def sortCols: Matrix => Matrix = m => (for(col <- m.transpose) yield sortAsc(col)).toList.transpose def sortColsPar: Matrix => Matrix = m => (for(col<- m.transpose.par) yield sortAsc(col)).toList.transpose // Alternativ (laut #Scala ist die Paralleliät bei beiden äquivalent gegeben): def sortColsPar2: Matrix => Matrix = m => m.transpose.par.map(sortAsc(_)).toList.transpose def sortRows: Matrix => Matrix = m =>{ def helper: (Matrix, Int) => Matrix = { case (Nil, n) => Nil case (m::ms, n) if(n % 2 == 0) => sortAsc(m)::helper(ms,n+1) case (m::ms, n) if(n % 2 != 0) => sortDes(m)::helper(ms,n+1) } helper(m,0) } //Alternative ohne Helfer-Funktion: def sortRows2: Matrix => Matrix = m => m match { case Nil => Nil case (row::m) => if (m.length % 2 == 0) sortAsc(row)::sortRows2(m) else sortDes(row)::sortRows2(m) } def sortHelper: (Int, Matrix) => Stream[(Matrix,Matrix)] = { case (n,m) => if (n%2==0) (m, sortRows(m)) #::sortHelper(n+1,sortRows(m)) else (m,sortCols(m)) #::sortHelper(n+1,sortCols(m)) } def snakeSort: Matrix => Matrix = m => { def helper: (Matrix, Int) => Matrix = (m,n) => { val a = sortHelper(0,m)(n) if(a._1 == a._2) a._2 else helper(m,n+1) } helper(m,0) } ==== Aufgabe 6 ==== Nicht mehr Teil des Vorlesungsstoffes.