Not logged in. · Lost password · Register

Page:  previous  1  2 
Sheppard
Professional Retard
Avatar
Member since Oct 2013
13 posts
In reply to post ID 133363
kann mal jemand die 1e begründen?
Xenomes
Avatar
Member since Oct 2009
96 posts
Quote by Sheppard:
kann mal jemand die 1e begründen?

Fließband [2, 4, 5, 6, 1],
3 Pakete

(2+4+5+6+1) + 2*6 = 18 + 12 = 30
Knowledge is power. Guard it well.
*Ralf
Avatar
Member since Oct 2011
774 posts
In reply to post ID 133344
Subject: zur 4)
+1 jeanorwin
Quote by jeanorwin on 2014-07-18, 18:02:
a) def construct: (Int => List[Int]) => (List[Int] => Int) => Int => Int = facs => sum => n => sum(facs(n))
b) def fss: Int => Stream[(Int, Int)] = n => (n, fss(n)) #::fss(n+1)
c) def count: (Int, Int) => Int = (start, nElem) => fss(start).take(nElem).foldLeft(0)(soFar, cur => if(cur._1 > cur._2) soFar+1 else soFar)
Die a) sollte stimmen. Bei der b) musst du im String-Head fs(n) statt fss(n) setzen und bei der c) fehlen die Klammern ums Tupel (soFar, cur).

Also sollte das (mit anderen Variablennamen) so aussehen:

  1. object DivisorFunction {
  2.  
  3.     def facs: Int => List[Int] =
  4.             n => List.range(1, n/2 + 1).toSet.filter(t => (n.toDouble/t).isValidInt).toList
  5.  
  6.     def sum: List[Int] => Int =
  7.             ls => ls.sum
  8.    
  9.     def fs: Int => Int = construct(facs)(sum)
  10.    
  11.     def construct: (Int => List[Int]) => (List[Int] => Int) => Int => Int =
  12.         f => s => n => s(f(n))
  13.    
  14.     def fss: Int => Stream[(Int, Int)] =    
  15.         n => (n, fs(n)) #:: fss(n+1)
  16.    
  17.     def count: (Int, Int) => Int =
  18.         (n0, m) => fss(n0).take(m).foldLeft(0)((n, c) => if(c._1 > c._2) n+1 else n)
  19. }
varj
Member since Apr 2012
78 posts
In reply to post ID 132888
Subject: Aufgabe 5 (Schreibtischlauf)
Quote by Hoschi on 2014-06-27, 13:32:
Aufgabe 5: Schreibtischlauf
a)   
Ausgabe                            Alternative Ausgaben
Question to Deep Thought:    Keine Alternative
Leerzeile                    Keine Alternative
Answer to the:            Keine Alternative
Ultimate Question        Douglas
of Life                Keine Alternative
Adams                The Universe
and Everything            Keine Alternative


ich hätte eine Frage bezüglich "Ultimate Question/Douglas"-Ausgabe, und zwar: Warum ist es eine Alternative hier möglich? Ich dachte, dass CyclicBarrier Sichtbarkeitssynchronisation garantiert --> counter wird dann garantiert zwei mal erhöht... und die Abfrage if(counter == 2) steht doch nach dem barrier und dazwischen passiert auch keine Änderungen der counter...Und wie genau bewirken die drei nacheinander stehende barrier.await() (Z. 52-54) auf die Ausführung des Codes? Ich glaube, ich verstehe das Konzept des CyclicBarriers nicht sehr gut...
mkmdl
Member since Nov 2009
272 posts
Ja, die CyclicBarrier garantiert Sichtbarkeitssynchronisation. Das Problem liegt aber woanders. Schau dir nochmal ganz genau den Code an. ;)
varj
Member since Apr 2012
78 posts
Quote by mkmdl:
Ja, die CyclicBarrier garantiert Sichtbarkeitssynchronisation. Das Problem liegt aber woanders. Schau dir nochmal ganz genau den Code an. ;)
Danke für die Antwort)
counter ist ein "normales" int. Aber ich dachte, z.B. ein Thread erhöht counter um eins, wartet, und danach ein zweites Thread erhöht counter um eins. Dann hat der counter wert 2 und wir haben "Ultimate Question" als Ausgabe... counter wird noch niergendwo mehr geändert... Geht es hier genau um diese Abfrage (Z.71-72), dass sie nicht "atomar" erfolgt? [bin total verzweifelt...]
Ich kann naturlich "sicherheitshalber" sagen, dass statt int counter mache ich AtomicInteger, das löst aber mein Verständnisproblem nicht :(
CodeMonkey
Member since May 2011
655 posts
Das Erhöhen von counter mittels counter++ ist keine atomare Aktion, sondern setzt sich zusammen aus dem Laden des alten Werts, dem Addieren von 1 auf diesen alten Wert und dem Speichern des neuen Werts in der Variable counter. Zwischen all diesen Operationen kann es nun zu Wettlaufsituationen kommen und es kann passieren, dass beide Threads zuerst den alten Wert lesen (0) beide diesen alten Wert erhöhen (1) und diesen dann zurückschreiben (wobei ein Thread den anderen überschreibt). Das Ergebnis ist dann 1 statt 2. Daran ändert dann auch die Sichtbarkeitssynchronisation durch die Barrier nichts mehr, da die Wettlaufsituation vorher auftritt. Durch nutzen eines AtomicInteger oder Verwendung von synchronized kann das Problem entsprechend lösen.
varj
Member since Apr 2012
78 posts
Danke für sehr ausführliche und verständliche Antwort! Diese Erklärung hat mir geholfen, mein tatsächliches Verständnisproblem "sicher" feststellen :)
Quote by CodeMonkey:
Das Erhöhen von counter mittels counter++ ist keine atomare Aktion, sondern setzt sich zusammen aus dem Laden des alten Werts, dem Addieren von 1 auf diesen alten Wert und dem Speichern des neuen Werts in der Variable counter.
Das ist mir bekannt. Wie ich vermutet habe, verstehe ich das Konzept des CyclicBarriers einfach nicht komplett. Der CyclicBarrier garantiert [nur(?)] das es auf alle Threads gewartet wird, dass sie alle ihre Arbeit erledigen, bevor es weitergeht. Und das ist einzigste, was er kann? (oder kann er mehr? ich habe mir immer gedacht, dass er noch "mächtiger" ist :) alle Beispiele, die ich im Internet gefunden habe, haben mein Problem leider nicht geklärt...)
Es gibt aber solche Fälle, wo das hier
int counter = 0;

barrier.await();
counter++;
barrier.await();
doch richtig funktionieren wird, obwohl counter "nur" ein int ist, oder? Und wenn ja, es wäre super ein Beispiel dafür zu finden :)
This post was edited on 2016-02-14, 15:19 by varj.
mkmdl
Member since Nov 2009
272 posts
Die CyclicBarrier garantiert Sichtbarkeitssynchronisation, das bedeutet, dass die Schreibzugriffe, die vor dem await()-Aufruf in den beteiligten Threads geschehen, danach für die beteiligten Threads sichtbar sind. Das Problem mit counter++, welches CodeMonkey geschildert hat, ist aber kein (oder genauer: nicht nur ein) Sichtbarkeitsproblem, sondern (auch) eine Wettlaufsituation.

Quote by varj:
int counter = 0;

barrier.await();
counter++;
barrier.await();
Das funktioniert, wenn zum Beispiel nur ein Thread counter++ durchführt und ein anderer nach dem zweiten barrier.await() lesend auf counter zugreift. Ohne die CyclicBarrier würde es dann zu nichtdeterministischem Verhalten kommen.
varj
Member since Apr 2012
78 posts
Am Anfang dachte ich, dass CyclicBarrier auch fuer mehrere Threads Sichtbarkeitssynchronisation garantiert.
vielen Dank! Die Erklaerungen haben mir sehr geholfen :)
CodeMonkey
Member since May 2011
655 posts
Quote by varj:
Am Anfang dachte ich, dass CyclicBarrier auch fuer mehrere Threads Sichtbarkeitssynchronisation garantiert.
vielen Dank! Die Erklaerungen haben mir sehr geholfen :)
Ich glaube du verstehst Sichtbarkeitssynchronisation in diesem Fall einfach falsch. Denn eine CyclicBarrier kümmert sich durchaus um Sichtbarkeitssynchronisation unter mehreren Threads. Allerdings tritt hier kein Sichtbarkeitsproblem nach der Barrier auf.

Ausführlicher geschrieben steht da in etwa (der restliche Code ist für das eigentliche Problem irrelevant) :
  1. barrier.await();
  2. int tmp = counter;
  3. int tmp2 = tmp + 1;
  4. counter = tmp2;
  5. barrier.await();
Die Barrier sorgt am barrier.await() dafür, dass Sichtbarkeitssynchronisation durchgeführt wird. D.h. nach dem barrier.await() ist der neue Wert von counter für alle Threads sichtbar. Die Barrier kann aber folgendes nicht verhindern:

1. Eine Wettlaufsituation, die auftritt, wenn T1 Zeile 2 oder 3 bereits ausgeführt hat, dann aber verdrängt wird und T2 somit tmp = counter ausführt bevor T1 counter überhaupt verändert hat. T2 lädt also den alten Wert, weil der neue vom anderen Thread noch nicht einmal berechnet wurde (oder zumindest nicht gespeichert wurde).

2. Ein Sichtbarkeitsproblem, nachdem T1 Zeile 4 ausgeführt hat. Es kann jetzt passieren, dass T2 Zeile 2 ausführt und obwohl T1 counter bereits geschrieben hat, wird von T2 noch der alte Wert gelesen (z. B. weil der neue Wert nur bei T1 im Cache liegt oder weil T2 noch einen veralteten Wert im Cache hat, den er nicht aktualisiert). Die Barrier kann hier nicht helfen, weil das Sichtbarkeitsproblem zwischen zwei await-Aufrufen auftritt.

Die Barrier garantiert Sichtbarkeitssynchronisation über await-Grenzen hinweg. Man kann es sich also so vorstellen, dass an einem await die geänderten Speicheradressen synchronisiert werden. Es wird keine Magie betrieben, um zwischen zwei await-Aufrufen Sichtbarkeitsprobleme zu beheben.

Würde man ein an dieser Stelle ein volatile int verwenden würde (2.) nicht auftreten können, sondern nur noch (1.). Um (1.) und (2.) auszuschließen und damit Threadsicherheit  zu garantieren brauchst du ein synchronized oder ein AtomicInteger.

Ein Beispiel für mehrere Threads, bei denen Sichtbarkeitssynchronisation funktioniert (wie mkmdl es schon angedeutet hat):
T1:
  1. barrier.await();
  2. counter++;
  3. barrier.await();
  4. // don't write to counter

T2:
  1. barrier.await();
  2. // don't use counter
  3. barrier.await();
  4. System.out.println(counter);
In diesem Fall gibt es zum write im ersten Barrieren-Abschnitt keine Entsprechung im anderen Thread und durch die Sichtbarkeitssynchronisation am await wird garantiert, dass counter++ auf jeden Fall vorher durchgeführt wurde und das Ergebnis für T2 sichtbar ist. Würde man die Barriere allerdings weglassen, könnten wieder Wettlaufsituationen und Sichtbarkeitsprobleme auftreten.
varj
Member since Apr 2012
78 posts
+1 simlrein
Quote by CodeMonkey:
Ich glaube du verstehst Sichtbarkeitssynchronisation in diesem Fall einfach falsch.
Ja, genau diese Vermutung habe ich ganz am Anfang geäußert :)
Quote by varj:
Ich glaube, ich verstehe das Konzept des CyclicBarriers nicht sehr gut...
Diese letzte ausführliche Erklärung hat mir bestätigt, dass ich es tatsächlich verstanden habe (und nicht nur im Bezug auf diese Aufgabe  :) )
Danke CodeMonkey und mkmdl nochmals für gute und ausführliche Erklärungen!
Close Smaller – Larger + Reply to this post:
Verification code: VeriCode Please enter the word from the image into the text field below. (Type the letters only, lower case is okay.)
Smileys: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Special characters:
Page:  previous  1  2 
Go to forum
Datenschutz | Impressum
Powered by the Unclassified NewsBoard software, 20150713-dev, © 2003-2011 by Yves Goergen