|
|
@@ -1,45 +1,57 @@
|
|
1
|
|
-# Proof of Work 2.0
|
|
|
1
|
+Proof of Work 2.0
|
|
2
|
2
|
|
|
3
|
|
-### Arten der Synchronisierung und Kommunikation
|
|
|
3
|
+### Performance-Gewinn *Single-Threaded vs Multi-Threaded*
|
|
4
|
4
|
|
|
5
|
|
-Neben den MPSC-channels für Rückgabe der Solution und der Zeitstatistik, verwenden wir für mehrere Variablen den Typ [Arc](https://doc.rust-lang.org/std/sync/struct.Arc.html). Jeder Thread bekommt über einen *clone()*-Vorgang eine Referenz auf die selbe, gemeinsame Variable im Heap. Das sync-Flag haben wir über einen [AtomicBool](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicBool.html), welcher von einem *Arc* gehalten wird gelöst. Über store(..) und load(..) lässt sich dann auf diesen 'bool' zugreifen.
|
|
|
5
|
+In der folgenden Tabelle sieht man sehr deutlich den Geschwindikeitsgewinn durch das Multithreading. Je länger die Difficulty ist, desto besser sieht man, dass durch verdopplung der Threads die reale Zeit ungefähr halbiert wird.
|
|
6
|
6
|
|
|
7
|
|
-### Performance-Gewinn *Single-Threaded vs Multi-Threaded*
|
|
|
7
|
+| Difficulty | Single Threaded* | 2 Threads* | 4 Threads* |
|
|
|
8
|
+| ---------- | -------------------------- | ------------------------- | ------------------------ |
|
|
|
9
|
+| "1234" | **0.314s** \| 0.288s | **0.284s** \| 0.280s | **0.254s** \| 0.252s |
|
|
|
10
|
+| "12345" | **0.693s** \| 0.644s | **0.462s** \| 0.660s | **0.336s** \| 0.552s |
|
|
|
11
|
+| "123456" | **12.936s** \| 12.904s | **6.899s** \| 13.464s | **5.755s** \| 15.720s |
|
|
|
12
|
+| "1234567" | **1m31.361s** \| 1m30.740s | **45.961s** \| 1m31.192s | **21.554s** \| 1m2.240s |
|
|
|
13
|
+| "12345678" | **2m2.810s** \| 2m2.684s | **1m1.332s** \| 1m46.931s | **34.746s** \| 1m38.376s |
|
|
|
14
|
+
|
|
|
15
|
+*time format: **real** | user
|
|
8
|
16
|
|
|
9
|
17
|
|
|
10
|
18
|
|
|
11
|
19
|
### Antworten
|
|
12
|
20
|
|
|
|
21
|
+#### Arten der Synchronisierung und Kommunikation
|
|
|
22
|
+
|
|
|
23
|
+Neben den MPSC-channels für Rückgabe der Solution und der Zeitstatistik, verwenden wir für mehrere Variablen den Typ [Arc](https://doc.rust-lang.org/std/sync/struct.Arc.html). Jeder Thread bekommt über einen *clone()*-Vorgang eine Referenz auf die selbe, gemeinsame Variable im Heap. Das sync-Flag haben wir über einen [AtomicBool](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicBool.html), welcher von einem *Arc* gehalten wird, gelöst. Über store(..) und load(..) lässt sich dann auf diesen 'boolean' zugreifen.
|
|
|
24
|
+
|
|
13
|
25
|
#### Was ist der Unterschied zwischen einer logischen und einer physikalischen CPU?
|
|
14
|
26
|
|
|
15
|
27
|
Logische CPU-Kerne sind nur virtuell vorhanden und werden auf die physikalische CPU 'umgeleitet'. Sie werden vom Betriebssystem, insbesondere vom Scheduler gesehen und verwendet. Deshalb spielt es beim Multithreading bzw. auch beim Scheduling ein Rolle wie das Verhältnis von logischen und phsyikalischen CPUs ist.
|
|
16
|
28
|
|
|
17
|
|
-#### 1. Wie ist die Ausgabe von time zu interpretieren, wenn mehrere Threads laufen?
|
|
|
29
|
+#### Wie ist die Ausgabe von time zu interpretieren, wenn mehrere Threads laufen?
|
|
18
|
30
|
|
|
19
|
|
-Die user-time ist immer deutlich höher als die real-time.
|
|
20
|
|
-Das heißt, dass die Threads nicht nebenläufig, sondern echt parallel laufen. Wenn man mit `-p` die Prozentangaben einschaltet, dann sieht man auch, dass die user-time deutlich über 100% ist.
|
|
|
31
|
+Im Gegensatz zu einem Thread ist bei mehreren Threads die user-time immer deutlich höher als die real-time. (siehe Tabelle)
|
|
|
32
|
+Das heißt, dass die Threads nicht nebenläufig, sondern echt parallel laufen. Wenn man mit `-p` die Prozentangaben einschaltet, dann sieht man auch, dass die user-time deutlich über 100% liegt.
|
|
21
|
33
|
|
|
22
|
|
-#### 2. Welche unterschiedlichen Ergebnisse erhalten Sie bei der Option timings? Wie stehen diese im Zusammenhang mit den Ergebnissen von time?
|
|
|
34
|
+#### Welche unterschiedlichen Ergebnisse erhalten Sie bei der Option timings? Wie stehen diese im Zusammenhang mit den Ergebnissen von time?
|
|
23
|
35
|
|
|
24
|
36
|
Die Option `timings` variiert unterschiedlich stark von den Ergebnissen von **time**. Das unix-Kommando time bezieht die Ausführungszeit des gesamten Codes mt ein. wenn man das Programm über `time cargo run --release...` aufruft, statt das erstellte binary, dann wird sogar die Compilezeit miteinberechnet.
|
|
25
|
37
|
Also auch Aufrufe von *sys-info* oder zum Beispiel das Parsen der Argumente, welches *clap* durchführt.
|
|
26
|
38
|
|
|
27
|
|
-#### 3. Welche quantitativen Auswirkungen hat die Synchronisierung (Warum)? Welche Auswirkungen haben Ihre zusätzlichen Parameter?
|
|
|
39
|
+#### Welche quantitativen Auswirkungen hat die Synchronisierung (Warum)? Welche Auswirkungen haben Ihre zusätzlichen Parameter?
|
|
28
|
40
|
|
|
29
|
41
|
Mit dem Synchronisierungsflag muss nur ein Producer eine Lösung finden, danach brechen die anderen Threads kontrolliert ihre Suche ab. Mit dem Wert hinter dem Parameter `--special` kann man die Häufigkeit dieser Abfrage (ob ein anderer Thread eine Lösung gefunden hat) steuern.
|
|
30
|
42
|
|
|
31
|
|
-#### 4. Wie variieren -s und -w die Messungen?
|
|
|
43
|
+#### Wie variieren -s und -w die Messungen?
|
|
32
|
44
|
|
|
33
|
45
|
Bei der Suche nach Hash mit base = 42 und difficulty = "123456" und 10 threads:
|
|
34
|
46
|
|
|
35
|
47
|
Mit `-s` und `-w`:
|
|
36
|
48
|
|
|
37
|
|
-Sobald eim.
|
|
|
49
|
+Der Thread, der die erste gültige *number* findet, setzt den gennanten AtomicBool auf true und beendet somit **indirekt** die anderen Threads.
|
|
38
|
50
|
```text
|
|
39
|
51
|
Sum Loops in Producers: 19019908
|
|
40
|
52
|
Sum Duration in Producers: 55s / 55585ms / 55585423us
|
|
41
|
53
|
```
|
|
42
|
|
-
|
|
|
54
|
+
|
|
43
|
55
|
|
|
44
|
56
|
Ohne `-s` und `-w`:
|
|
45
|
57
|
|
|
|
@@ -48,7 +60,7 @@ Wartet der Consumer bis jeder Thread eine *Solution* gefunden hat. Dies ist sehr
|
|
48
|
60
|
Sum Loops in Producers: 60340756
|
|
49
|
61
|
Sum Duration in Producers: 114s / 114074ms / 114074341us
|
|
50
|
62
|
```
|
|
51
|
|
-
|
|
52
|
|
-#### 5. Welche sonstigen Arten der Synchronisierung bieten sich für die Problemstellung "Lösung gefunden (-s)" an? Was sind deren Vor- und Nachteile gegenüber Ihrer gewählten Lösung?
|
|
|
63
|
+
|
|
|
64
|
+#### Welche sonstigen Arten der Synchronisierung bieten sich für die Problemstellung "Lösung gefunden (-s)" an? Was sind deren Vor- und Nachteile gegenüber Ihrer gewählten Lösung?
|
|
53
|
65
|
|
|
54
|
66
|
Man könnte anstatt dem Arc und dem AtomicBool im Consumer aktiv alle Threads töten, sobald eine Lösung gefunden wurde. Das ist zwar schneller, aber es ist nicht mehr möglich auf die Threadlaufzeiten und Threadschleifendurchläufe zuzugreifen.
|