Anki Deck Changes

Commit: 9664d041 - digging the hole even deeper

Author: lhorva <lhorva@student.ethz.ch>

Date: 2026-05-04T23:07:29+02:00

Changes: 73 note(s) changed (66 added, 7 modified, 0 deleted)

ℹ️ Cosmetic Changes Hidden: 1 note(s) had formatting-only changes and are not shown below • 1 HTML formatting changes

Note 1: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Cloze
GUID: &{f,XLC*~+
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Hashfunktion (Annahmen)
Falls die Elemente in \(D\) gross sind und Speicherzugriffe sowie Vergleiche teuer sind, verwendet man eine Hashfunktion \(h : U \to [m]\) mit zwei Eigenschaften:
  • \(h\) ist effizient berechenbar
  • {{c2::\(h\) verhält sich wie eine Zufallsfunktion: \(\forall u \in U\;\forall i \in [m]:\; \Pr[h(u) = i] = \tfrac{1}{m}\), unabhängig für verschiedene \(u\)}}

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Hashfunktion (Annahmen)
Falls die Elemente in \(D\) gross sind und Speicherzugriffe sowie Vergleiche teuer sind, verwendet man eine Hashfunktion \(h : U \to [m]\) mit zwei Eigenschaften:
  • \(h\) ist effizient berechenbar
  • {{c2::\(h\) verhält sich wie eine Zufallsfunktion: \(\forall u \in U\;\forall i \in [m]:\; \Pr[h(u) = i] = \tfrac{1}{m}\), unabhängig für verschiedene \(u\)}}

\(U\) ist das Universum der möglichen Element-Werte; \([m] = \{1, \ldots, m\}\) sind die Hash-Werte.
Field-by-field Comparison
Field Before After
Text <b>Hashfunktion (Annahmen)</b><br>Falls die Elemente in \(D\) gross sind und Speicherzugriffe sowie Vergleiche teuer sind, verwendet man eine <b>Hashfunktion</b> \(h : U \to [m]\) mit zwei Eigenschaften:<br><ul><li>{{c1::\(h\) ist effizient berechenbar}}</li><li>{{c2::\(h\) verhält sich wie eine Zufallsfunktion: \(\forall u \in U\;\forall i \in [m]:\; \Pr[h(u) = i] = \tfrac{1}{m}\), unabhängig für verschiedene \(u\)}}</li></ul>
Extra \(U\) ist das Universum der möglichen Element-Werte; \([m] = \{1, \ldots, m\}\) sind die Hash-Werte.
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden

Note 2: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Cloze
GUID: ){U0btIv-;
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Schlüsseleigenschaft)
Definiere die Folge \(x_0 := n,\; x_i := a[x_{i-1}]\) für \(i \geq 1\). Sei der Pfad \(k \geq 1\) Kanten lang und der Kreis \(\ell \geq 3\) Kanten lang.
Wähle \(0 \leq r < \ell\) und \(s \geq 1\) mit \(k + r = s\ell\). Dann gilt:\[x_{k+r} = {{c2::x_{2(k+r)} }}.\]Insbesondere existiert ein {{c3::\(i \leq n\) mit \(x_i = x_{2i}\)}}.

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Schlüsseleigenschaft)
Definiere die Folge \(x_0 := n,\; x_i := a[x_{i-1}]\) für \(i \geq 1\). Sei der Pfad \(k \geq 1\) Kanten lang und der Kreis \(\ell \geq 3\) Kanten lang.
Wähle \(0 \leq r < \ell\) und \(s \geq 1\) mit \(k + r = s\ell\). Dann gilt:\[x_{k+r} = {{c2::x_{2(k+r)} }}.\]Insbesondere existiert ein {{c3::\(i \leq n\) mit \(x_i = x_{2i}\)}}.

Anschauung: Sobald die Folge \(x_0, x_1, \ldots\) den Kreis erreicht hat (nach \(k\) Schritten), läuft sie unendlich im Kreis. Wir suchen einen Schritt-Index \(i\), bei dem ein einfach-laufender und ein doppelt-laufender Pointer den gleichen Knoten betreten. Dafür muss \(2i - i = i\) ein Vielfaches der Kreislänge \(\ell\) sein und \(i \geq k\) gelten: also \(i = k + r\) mit \(k + r \equiv 0 \pmod{\ell}\).

Wahl: \(s = 1\) für \(k \leq \ell\), und \(s = \lceil k/\ell \rceil\) für \(k > \ell\).
Field-by-field Comparison
Field Before After
Text <b>Floyd's Cycle Finding (Schlüsseleigenschaft)</b><br>Definiere die Folge \(x_0 := n,\; x_i := a[x_{i-1}]\) für \(i \geq 1\). Sei der Pfad \(k \geq 1\) Kanten lang und der Kreis \(\ell \geq 3\) Kanten lang.<br>Wähle \(0 \leq r &lt; \ell\) und \(s \geq 1\) mit {{c1::\(k + r = s\ell\)}}. Dann gilt:\[x_{k+r} = {{c2::x_{2(k+r)} }}.\]Insbesondere existiert ein {{c3::\(i \leq n\) mit \(x_i = x_{2i}\)}}.
Extra Anschauung: Sobald die Folge \(x_0, x_1, \ldots\) den Kreis erreicht hat (nach \(k\) Schritten), läuft sie unendlich im Kreis. Wir suchen einen Schritt-Index \(i\), bei dem ein einfach-laufender und ein doppelt-laufender Pointer den gleichen Knoten betreten. Dafür muss \(2i - i = i\) ein Vielfaches der Kreislänge \(\ell\) sein und \(i \geq k\) gelten: also \(i = k + r\) mit \(k + r \equiv 0 \pmod{\ell}\).<br><br>Wahl: \(s = 1\) für \(k \leq \ell\), und \(s = \lceil k/\ell \rceil\) für \(k &gt; \ell\).
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding

Note 3: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Cloze
GUID: +N@/D$lVm_
modified

Before

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::2._Sortieren_und_Selektieren
Selektionsproblem: Bestimme in einer Folge \((A[1], \ldots, A[n])\) paarweise verschiedener Zahlen den \(k\)-kleinsten Wert.

Naiver Ansatz: Sortieren + Index, Laufzeit \(O(n \log n)\).

Schneller geht es mit QuickSelect (erwartet \(O(n)\)):
QuickSelect(A, ℓ, r, k):
  p ← Uniform({ℓ, ℓ+1, ..., r})
  t ← Partition(A, ℓ, r, p)
  if t = ℓ + k - 1: return A[t]    # gefunden
  else if t > ℓ + k - 1:
    return QuickSelect(A, ℓ, t-1, k)     # links
  else:
    return QuickSelect(A, t+1, r, k - t) # rechts

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::2._Sortieren_und_Selektieren
Selektionsproblem: Bestimme in einer Folge \((A[1], \ldots, A[n])\) paarweise verschiedener Zahlen den \(k\)-kleinsten Wert.

Naiver Ansatz: Sortieren + Index, Laufzeit \(O(n \log n)\).

Schneller geht es mit QuickSelect (erwartet \(O(n)\)):
QuickSelect(A, ℓ, r, k):
  p ← Uniform({ℓ, ℓ+1, ..., r})
  t ← Partition(A, ℓ, r, p)
  if t = ℓ + k - 1: return A[t]    # gefunden
  else if t > ℓ + k - 1:
    return QuickSelect(A, ℓ, t-1, k)     # links
  else:
    return QuickSelect(A, t+1, r, k - t) # rechts

Im Gegensatz zu QuickSort rekursiert QuickSelect nur in eine der beiden Hälften (oder gibt direkt zurück, falls Pivot bereits an der gesuchten Position liegt). Das macht den Unterschied zwischen \(O(n \log n)\) und \(O(n)\) erwartet.

Bei einem Aufruf von QuickSelect ist die Anzahl Vergleiche \(T = \sum_{i=1}^{N} (r_i - \ell_i)\), wobei \(N\) die Anzahl Partition-Aufrufe ist.

After

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::2._Sortieren_und_Selektieren
Selektionsproblem: Bestimme in einer Folge \((A[1], \ldots, A[n])\) paarweise verschiedener Zahlen den \(k\)-kleinsten Wert.

Naiver Ansatz: Sortieren + Index, Laufzeit \(O(n \log n)\).

Schneller geht es mit QuickSelect (erwartet \(O(n)\)):
QuickSelect(A, ℓ, r, k):
  p ← Uniform({ℓ, ℓ+1, ..., r})
  t ← Partition(A, ℓ, r, p)
  if t = ℓ + k - 1: return A[t]    # gefunden
  else if t > ℓ + k - 1:
    return QuickSelect(A, ℓ, t-1, k)     # links
  else:
    return QuickSelect(A, t+1, r, k - t) # rechts

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::2._Sortieren_und_Selektieren
Selektionsproblem: Bestimme in einer Folge \((A[1], \ldots, A[n])\) paarweise verschiedener Zahlen den \(k\)-kleinsten Wert.

Naiver Ansatz: Sortieren + Index, Laufzeit \(O(n \log n)\).

Schneller geht es mit QuickSelect (erwartet \(O(n)\)):
QuickSelect(A, ℓ, r, k):
  p ← Uniform({ℓ, ℓ+1, ..., r})
  t ← Partition(A, ℓ, r, p)
  if t = ℓ + k - 1: return A[t]    # gefunden
  else if t > ℓ + k - 1:
    return QuickSelect(A, ℓ, t-1, k)     # links
  else:
    return QuickSelect(A, t+1, r, k - t) # rechts

Im Gegensatz zu QuickSort rekursiert QuickSelect nur in eine der beiden Hälften (oder gibt direkt zurück, falls Pivot bereits an der gesuchten Position liegt). Das macht den Unterschied zwischen \(O(n \log n)\) und \(O(n)\) erwartet.

Bei einem Aufruf von QuickSelect ist die Anzahl Vergleiche \(T = \sum_{i=1}^{N} (r_i - \ell_i)\), wobei \(N\) die Anzahl Partition-Aufrufe ist.
Field-by-field Comparison
Field Before After
Text <b>Selektionsproblem:</b> Bestimme in einer Folge \((A[1], \ldots, A[n])\) paarweise verschiedener Zahlen den {{c1::\(k\)-kleinsten Wert}}.<br><br>Naiver Ansatz: Sortieren + Index, Laufzeit {{c2::\(O(n \log n)\)}}.<br><br>Schneller geht es mit <b>QuickSelect</b> (erwartet {{c3::\(O(n)\)}}):<pre>QuickSelect(A, ℓ, r, k): p ← Uniform({ℓ, ℓ+1, ..., r}) t ← Partition(A, ℓ, r, p) if t = ℓ + k - 1: return A[t] # gefunden else if t &gt; ℓ + k - 1: return QuickSelect(A, ℓ, t-1, k) # links else: return QuickSelect(A, t+1, r, k - t) # rechts</pre> <b>Selektionsproblem:</b> Bestimme in einer Folge \((A[1], \ldots, A[n])\) paarweise verschiedener Zahlen den {{c1::\(k\)-kleinsten Wert}}.<br><br>Naiver Ansatz: Sortieren + Index, Laufzeit {{c2::\(O(n \log n)\)}}.<br><br>Schneller geht es mit <b>QuickSelect</b> (erwartet \(O({{c3::n}})\)):<pre>QuickSelect(A, ℓ, r, k): p ← Uniform({ℓ, ℓ+1, ..., r}) t ← Partition(A, ℓ, r, p) if t = ℓ + k - 1: return A[t] # gefunden else if t &gt; ℓ + k - 1: return QuickSelect(A, ℓ, t-1, k) # links else: return QuickSelect(A, t+1, r, k - t) # rechts</pre>
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::2._Sortieren_und_Selektieren

Note 4: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Classic
GUID: ,*ESus}q*l
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Phase 1)
Wie wird mit nur drei Variablen ein \(i \geq 1\) mit \(x_i = x_{2i}\) berechnet, und welche Bedeutung hat das gefundene \(i\)?

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Phase 1)
Wie wird mit nur drei Variablen ein \(i \geq 1\) mit \(x_i = x_{2i}\) berechnet, und welche Bedeutung hat das gefundene \(i\)?

igel := a[n]
hase := a[a[n]]
i := 1
while (igel != hase):
    igel := a[igel]
    hase := a[a[hase]]
    i := i + 1
Der Igel macht pro Iteration einen Schritt, der Hase zwei. Treffen sie sich, gilt \(x_i = x_{2i}\) mit \(i = k + r\) (Pfadlänge \(k\) plus Rest \(r\) wie in der Schlüsseleigenschaft).

Laufzeit: \(O(n)\), denn \(i \leq k + \ell \leq n\).
Field-by-field Comparison
Field Before After
Front <b>Floyd's Cycle Finding (Phase 1)</b><br>Wie wird mit nur drei Variablen ein \(i \geq 1\) mit \(x_i = x_{2i}\) berechnet, und welche Bedeutung hat das gefundene \(i\)?
Back <pre>igel := a[n] hase := a[a[n]] i := 1 while (igel != hase): igel := a[igel] hase := a[a[hase]] i := i + 1</pre>Der Igel macht pro Iteration einen Schritt, der Hase zwei. Treffen sie sich, gilt \(x_i = x_{2i}\) mit \(i = k + r\) (Pfadlänge \(k\) plus Rest \(r\) wie in der Schlüsseleigenschaft).<br><br>Laufzeit: \(O(n)\), denn \(i \leq k + \ell \leq n\).
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding

Note 5: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Cloze
GUID: -+PkHTr|N.
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Datensatz und Duplikate
Ein Datensatz \(D = (s_1, s_2, \ldots, s_n)\) ist eine Folge von \(n\) Elementen.
Ein Paar \((i, j)\) mit \(1 \leq i < j \leq n\) heisst Duplikat in \(D\), falls \(s_i = s_j\).

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Datensatz und Duplikate
Ein Datensatz \(D = (s_1, s_2, \ldots, s_n)\) ist eine Folge von \(n\) Elementen.
Ein Paar \((i, j)\) mit \(1 \leq i < j \leq n\) heisst Duplikat in \(D\), falls \(s_i = s_j\).

Beispiel: \(D = (A, C, B, Z, C, B, C)\) mit Indizes \(1, \ldots, 7\). Dann ist \(\mathrm{Dupl}(D) = \{(2,5), (2,7), (5,7), (3,6)\}\), denn Position \(2, 5, 7\) tragen alle \(C\), und Position \(3, 6\) tragen \(B\).
Field-by-field Comparison
Field Before After
Text <b>Datensatz und Duplikate</b><br>Ein <b>Datensatz</b> \(D = (s_1, s_2, \ldots, s_n)\) ist {{c1::eine Folge von \(n\) Elementen}}.<br>Ein Paar \((i, j)\) mit \(1 \leq i &lt; j \leq n\) heisst <b>Duplikat</b> in \(D\), falls {{c2::\(s_i = s_j\)}}.
Extra Beispiel: \(D = (A, C, B, Z, C, B, C)\) mit Indizes \(1, \ldots, 7\). Dann ist \(\mathrm{Dupl}(D) = \{(2,5), (2,7), (5,7), (3,6)\}\), denn Position \(2, 5, 7\) tragen alle \(C\), und Position \(3, 6\) tragen \(B\).
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden

Note 6: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Classic
GUID: 5pn1{Da=cd
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Phase 2)
Nach Phase 1 ist ein Treffpunkt mit \(i = k + r\) bekannt. Wie bestimmt man daraus die gesuchten Indizes \(i \neq j\) mit \(a[i] = a[j]\)?

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Phase 2)
Nach Phase 1 ist ein Treffpunkt mit \(i = k + r\) bekannt. Wie bestimmt man daraus die gesuchten Indizes \(i \neq j\) mit \(a[i] = a[j]\)?

Beobachtung: Aus \(i = k + r\) folgt \(x_k = x_{i+k}\) (beide sind der Eintrittsknoten des Kreises). Setze den Hasen auf \(n\) zurück und lasse beide mit gleicher Geschwindigkeit laufen, dabei jeweils den Vorgänger merken:
hase := n
while (igel != hase):
    i := igel
    j := hase
    igel := a[igel]
    hase := a[hase]
return i, j
Wenn Hase und Igel sich wieder treffen, sind sie am Eintrittsknoten des Kreises. Die zwei Vorgänger \(i\) und \(j\) sind verschieden, zeigen aber per Konstruktion beide auf den Eintrittsknoten, das heisst \(a[i] = a[j]\).
Field-by-field Comparison
Field Before After
Front <b>Floyd's Cycle Finding (Phase 2)</b><br>Nach Phase 1 ist ein Treffpunkt mit \(i = k + r\) bekannt. Wie bestimmt man daraus die gesuchten Indizes \(i \neq j\) mit \(a[i] = a[j]\)?
Back Beobachtung: Aus \(i = k + r\) folgt \(x_k = x_{i+k}\) (beide sind der <b>Eintrittsknoten</b> des Kreises). Setze den Hasen auf \(n\) zurück und lasse beide mit <b>gleicher</b> Geschwindigkeit laufen, dabei jeweils den Vorgänger merken:<br><pre>hase := n while (igel != hase): i := igel j := hase igel := a[igel] hase := a[hase] return i, j</pre>Wenn Hase und Igel sich wieder treffen, sind sie am Eintrittsknoten des Kreises. Die zwei Vorgänger \(i\) und \(j\) sind verschieden, zeigen aber per Konstruktion beide auf den Eintrittsknoten, das heisst \(a[i] = a[j]\).
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding

Note 7: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Classic
GUID: CMDdQgC0[y
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Lösung mit Hashmap
Beschreibe den Algorithmus und nenne den entscheidenden Unterschied zur Sortier-Lösung.

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Lösung mit Hashmap
Beschreibe den Algorithmus und nenne den entscheidenden Unterschied zur Sortier-Lösung.

Algorithmus:
  1. Hashen und indexieren: \(((h(s_1), 1), (h(s_2), 2), \ldots, (h(s_n), n))\)
  2. Sortiere nach erster Koordinate (jetzt Hash-Werte aus \([m]\), nicht mehr die teuren Original-Elemente)
  3. Durchlaufe die sortierte Folge, um Duplikat-Kandidaten zu finden
  4. Wichtig: Kandidaten müssen noch auf mögliche Kollisionen geprüft werden, denn \(h(s_i) = h(s_j)\) impliziert nicht \(s_i = s_j\)
Vorteil: Sortieren erfolgt auf kleinen Hash-Werten, nicht auf den (teuren) Originalelementen.
Field-by-field Comparison
Field Before After
Front <b>Lösung mit Hashmap</b><br>Beschreibe den Algorithmus und nenne den entscheidenden Unterschied zur Sortier-Lösung.
Back <b>Algorithmus:</b><ol><li>Hashen und indexieren: \(((h(s_1), 1), (h(s_2), 2), \ldots, (h(s_n), n))\)</li><li>Sortiere nach erster Koordinate (jetzt Hash-Werte aus \([m]\), nicht mehr die teuren Original-Elemente)</li><li>Durchlaufe die sortierte Folge, um Duplikat-Kandidaten zu finden</li><li><b>Wichtig:</b> Kandidaten müssen noch auf mögliche Kollisionen geprüft werden, denn \(h(s_i) = h(s_j)\) impliziert nicht \(s_i = s_j\)</li></ol><b>Vorteil:</b> Sortieren erfolgt auf kleinen Hash-Werten, nicht auf den (teuren) Originalelementen.
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden

Note 8: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Cloze
GUID: [u#wQ+Y.*n
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Aufgabenstellung)
Gegeben ein Array \(a[1, \ldots, n]\) mit \(a[i] \in \{1, \ldots, n-1\}\). Finde zwei Indizes \(i \neq j\) mit \(a[i] = a[j]\), unter folgenden Einschränkungen:
  • Laufzeit \(O(n)\)
  • Das Array \(a\) darf nicht verändert werden (Zugriffe \(a[i]\) sind beliebig oft erlaubt)
  • Nur \(O(1)\) zusätzliche Speicherzellen

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Aufgabenstellung)
Gegeben ein Array \(a[1, \ldots, n]\) mit \(a[i] \in \{1, \ldots, n-1\}\). Finde zwei Indizes \(i \neq j\) mit \(a[i] = a[j]\), unter folgenden Einschränkungen:
  • Laufzeit \(O(n)\)
  • Das Array \(a\) darf nicht verändert werden (Zugriffe \(a[i]\) sind beliebig oft erlaubt)
  • Nur \(O(1)\) zusätzliche Speicherzellen

Ein Duplikat existiert sicher, denn \(a\) hat \(n\) Einträge mit Werten aus einer Menge der Grösse \(n-1\) (Schubfachprinzip).

Diese Variante hat keine direkte praktische Bedeutung, zeigt aber, was mit guter algorithmischer Herangehensweise möglich ist.
Field-by-field Comparison
Field Before After
Text <b>Floyd's Cycle Finding (Aufgabenstellung)</b><br>Gegeben ein Array \(a[1, \ldots, n]\) mit \(a[i] \in \{1, \ldots, n-1\}\). Finde zwei Indizes \(i \neq j\) mit \(a[i] = a[j]\), unter folgenden Einschränkungen:<ul><li>Laufzeit {{c1::\(O(n)\)}}</li><li>{{c2::Das Array \(a\) darf nicht verändert werden}} (Zugriffe \(a[i]\) sind beliebig oft erlaubt)</li><li>Nur {{c3::\(O(1)\)}} zusätzliche Speicherzellen</li></ul>
Extra Ein Duplikat existiert sicher, denn \(a\) hat \(n\) Einträge mit Werten aus einer Menge der Grösse \(n-1\) (Schubfachprinzip).<br><br>Diese Variante hat keine direkte praktische Bedeutung, zeigt aber, was mit guter algorithmischer Herangehensweise möglich ist.
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding

Note 9: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Cloze
GUID: g0V)&ygKw?
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Kollision
Eine Kollision ist ein Paar \((i, j)\) mit \(1 \leq i < j \leq n\), \(s_i \neq s_j\) und \(h(s_i) = h(s_j)\).
Anschaulich: Kollisionen sind die neuen (unerwünschten) Duplikate in der Hashmap, also Hashmap-Duplikate, die im Original keine sind.

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Kollision
Eine Kollision ist ein Paar \((i, j)\) mit \(1 \leq i < j \leq n\), \(s_i \neq s_j\) und \(h(s_i) = h(s_j)\).
Anschaulich: Kollisionen sind die neuen (unerwünschten) Duplikate in der Hashmap, also Hashmap-Duplikate, die im Original keine sind.

Echte Duplikate (\(s_i = s_j\)) erzeugen automatisch übereinstimmende Hashes; das ist erwünscht. Kollisionen sind die zusätzlichen, unerwünschten Übereinstimmungen, die durch die Komprimierung \(|U| \to [m]\) entstehen.
Field-by-field Comparison
Field Before After
Text <b>Kollision</b><br>Eine <b>Kollision</b> ist {{c1::ein Paar \((i, j)\) mit \(1 \leq i &lt; j \leq n\), \(s_i \neq s_j\) und \(h(s_i) = h(s_j)\)}}.<br>Anschaulich: Kollisionen sind {{c2::die neuen (unerwünschten) Duplikate in der Hashmap}}, also Hashmap-Duplikate, die im Original keine sind.
Extra Echte Duplikate (\(s_i = s_j\)) erzeugen automatisch übereinstimmende Hashes; das ist erwünscht. Kollisionen sind die zusätzlichen, unerwünschten Übereinstimmungen, die durch die Komprimierung \(|U| \to [m]\) entstehen.
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden

Note 10: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Cloze
GUID: hN,uV~s)@n
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Erwartete Anzahl Kollisionen
Für eine Hashfunktion \(h : U \to [m]\) mit \(\Pr[h(u) = i] = \tfrac{1}{m}\) gilt:\[\mathbb{E}[\#\text{Kollisionen}] \leq {{c1::\binom{n}{2} \cdot \tfrac{1}{m}}}.\]Insbesondere folgt mit der Wahl \(m = n^2\): \(\mathbb{E}[\#\text{Kollisionen}] < 1\).

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Erwartete Anzahl Kollisionen
Für eine Hashfunktion \(h : U \to [m]\) mit \(\Pr[h(u) = i] = \tfrac{1}{m}\) gilt:\[\mathbb{E}[\#\text{Kollisionen}] \leq {{c1::\binom{n}{2} \cdot \tfrac{1}{m}}}.\]Insbesondere folgt mit der Wahl \(m = n^2\): \(\mathbb{E}[\#\text{Kollisionen}] < 1\).

Beweisidee: Für jedes feste Paar \((i, j)\) mit \(s_i \neq s_j\) gilt \(\Pr[h(s_i) = h(s_j)] = \tfrac{1}{m}\) (wegen Unabhängigkeit / Zufallsfunktion). Es gibt höchstens \(\binom{n}{2}\) solche Paare, und Linearität des Erwartungswerts liefert die Schranke.
Field-by-field Comparison
Field Before After
Text <b>Erwartete Anzahl Kollisionen</b><br>Für eine Hashfunktion \(h : U \to [m]\) mit \(\Pr[h(u) = i] = \tfrac{1}{m}\) gilt:\[\mathbb{E}[\#\text{Kollisionen}] \leq {{c1::\binom{n}{2} \cdot \tfrac{1}{m}}}.\]Insbesondere folgt mit der Wahl \(m = n^2\): \(\mathbb{E}[\#\text{Kollisionen}] {{c2::&lt; 1}}\).
Extra Beweisidee: Für jedes feste Paar \((i, j)\) mit \(s_i \neq s_j\) gilt \(\Pr[h(s_i) = h(s_j)] = \tfrac{1}{m}\) (wegen Unabhängigkeit / Zufallsfunktion). Es gibt höchstens \(\binom{n}{2}\) solche Paare, und Linearität des Erwartungswerts liefert die Schranke.
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden

Note 11: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Cloze
GUID: unEExu6hiJ
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Resultat)
Auf einem Array \(a[1, \ldots, n]\) mit \(a[i] \in \{1, \ldots, n-1\}\) findet der Hase-und-Igel-Algorithmus zwei Indizes \(i \neq j\) mit \(a[i] = a[j]\) in:
  • Laufzeit \(O(n)\)
  • Zusätzlicher Speicher: nur vier Variablen (igel, hase, i, j)
Das Array \(a\) wird dabei nicht verändert.

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Resultat)
Auf einem Array \(a[1, \ldots, n]\) mit \(a[i] \in \{1, \ldots, n-1\}\) findet der Hase-und-Igel-Algorithmus zwei Indizes \(i \neq j\) mit \(a[i] = a[j]\) in:
  • Laufzeit \(O(n)\)
  • Zusätzlicher Speicher: nur vier Variablen (igel, hase, i, j)
Das Array \(a\) wird dabei nicht verändert.

Bemerkenswert: Die offensichtliche Hashmap-Lösung benötigt \(\Theta(n \log n)\) Zusatzspeicher; Floyd's Algorithmus kommt mit \(O(1)\) Zusatzspeicher aus, ohne die Laufzeitschranke zu opfern.

Der Algorithmus ist deterministisch und (anders als Hashmap/Bloomfilter) nicht randomisiert: er steht hier als Kontrast und Highlight, nicht als randomisierter Algorithmus.
Field-by-field Comparison
Field Before After
Text <b>Floyd's Cycle Finding (Resultat)</b><br>Auf einem Array \(a[1, \ldots, n]\) mit \(a[i] \in \{1, \ldots, n-1\}\) findet der Hase-und-Igel-Algorithmus zwei Indizes \(i \neq j\) mit \(a[i] = a[j]\) in:<ul><li>Laufzeit {{c1::\(O(n)\)}}</li><li>Zusätzlicher Speicher: {{c2::nur vier Variablen}} (igel, hase, i, j)</li></ul>Das Array \(a\) wird dabei {{c3::nicht verändert}}.
Extra Bemerkenswert: Die offensichtliche Hashmap-Lösung benötigt \(\Theta(n \log n)\) Zusatzspeicher; Floyd's Algorithmus kommt mit \(O(1)\) Zusatzspeicher aus, ohne die Laufzeitschranke zu opfern.<br><br>Der Algorithmus ist deterministisch und (anders als Hashmap/Bloomfilter) <b>nicht</b> randomisiert: er steht hier als Kontrast und Highlight, nicht als randomisierter Algorithmus.
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding

Note 12: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Classic
GUID: vJ-_bexxr5
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Erste Lösung für das Duplikate-finden-Problem
Beschreibe den Algorithmus und gib seine Laufzeit an.

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Erste Lösung für das Duplikate-finden-Problem
Beschreibe den Algorithmus und gib seine Laufzeit an.

Algorithmus:
  1. Indexiere: \(((s_1, 1), (s_2, 2), \ldots, (s_n, n))\).
  2. Sortiere die Folge nach der ersten Koordinate.
  3. Durchlaufe die sortierte Folge, um Duplikate zu finden (gleiche Werte stehen jetzt benachbart).
Analyse:
  • Sortieren: \(O(n \log n)\) Vergleiche und Speicherzugriffe
  • Durchlaufen: \(O(n + |\mathrm{Dupl}(D)|)\)
Field-by-field Comparison
Field Before After
Front <b>Erste Lösung für das Duplikate-finden-Problem</b><br>Beschreibe den Algorithmus und gib seine Laufzeit an.
Back <b>Algorithmus:</b><ol><li>Indexiere: \(((s_1, 1), (s_2, 2), \ldots, (s_n, n))\).</li><li>Sortiere die Folge nach der ersten Koordinate.</li><li>Durchlaufe die sortierte Folge, um Duplikate zu finden (gleiche Werte stehen jetzt benachbart).</li></ol><b>Analyse:</b><ul><li>Sortieren: \(O(n \log n)\) Vergleiche und Speicherzugriffe</li><li>Durchlaufen: \(O(n + |\mathrm{Dupl}(D)|)\)</li></ul>
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden

Note 13: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Cloze
GUID: {(x$*~gqX=
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Wichtige Eigenschaften der Hashwerte
Jedes \(h(s_i)\) ist zufällig gleichverteilt in \([m]\), aber es gilt deterministisch \(s_i = s_j \Rightarrow h(s_i) = h(s_j)\).
Wir wählen \(m\) viel kleiner als \(|U|\), also Komprimierung.

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden
Wichtige Eigenschaften der Hashwerte
Jedes \(h(s_i)\) ist zufällig gleichverteilt in \([m]\), aber es gilt deterministisch \(s_i = s_j \Rightarrow h(s_i) = h(s_j)\).
Wir wählen \(m\) viel kleiner als \(|U|\), also Komprimierung.

Die Implikation \(s_i = s_j \Rightarrow h(s_i) = h(s_j)\) ist nötig, damit echte Duplikate auch im Hash-Raum als Duplikate erscheinen. Die Umkehrung gilt im Allgemeinen nicht: zwei verschiedene Elemente können denselben Hash-Wert haben (Kollision).
Field-by-field Comparison
Field Before After
Text <b>Wichtige Eigenschaften der Hashwerte</b><br>Jedes \(h(s_i)\) ist {{c1::zufällig gleichverteilt in \([m]\)}}, aber es gilt deterministisch {{c2::\(s_i = s_j \Rightarrow h(s_i) = h(s_j)\)}}.<br>Wir wählen \(m\) viel kleiner als \(|U|\), also {{c3::Komprimierung}}.
Extra Die Implikation \(s_i = s_j \Rightarrow h(s_i) = h(s_j)\) ist nötig, damit echte Duplikate auch im Hash-Raum als Duplikate erscheinen. Die Umkehrung gilt im Allgemeinen <b>nicht</b>: zwei verschiedene Elemente können denselben Hash-Wert haben (Kollision).
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::6._Duplikate_finden

Note 14: ETH::2. Semester::A&W

Deck: ETH::2. Semester::A&W
Note Type: Horvath Cloze
GUID: |(%V*=bZ6e
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Graph-Reformulierung)
Definiere den gerichteten Graphen \(D = (V, A)\) mit \(V = [n]\) und {{c2::\(A = \{(i, a[i]) \mid 1 \leq i \leq n\}\)}}.
Eigenschaften:
  • Jeder Knoten hat genau eine ausgehende Kante
  • Knoten \(n\) hat keine eingehende Kante (weil \(a[i] \neq n\) für alle \(i\))
  • Der von Knoten \(n\) ausgehende Subgraph (immer der ausgehenden Kante folgen) besteht aus einem Pfad gefolgt von einem Kreis (\(\rho\)-Form)

Back

ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding
Floyd's Cycle Finding (Graph-Reformulierung)
Definiere den gerichteten Graphen \(D = (V, A)\) mit \(V = [n]\) und {{c2::\(A = \{(i, a[i]) \mid 1 \leq i \leq n\}\)}}.
Eigenschaften:
  • Jeder Knoten hat genau eine ausgehende Kante
  • Knoten \(n\) hat keine eingehende Kante (weil \(a[i] \neq n\) für alle \(i\))
  • Der von Knoten \(n\) ausgehende Subgraph (immer der ausgehenden Kante folgen) besteht aus einem Pfad gefolgt von einem Kreis (\(\rho\)-Form)

Notation: Pfad hat \(k \geq 1\) Kanten, Kreis hat \(\ell \geq 3\) Kanten, mit \(k + \ell \leq n\).
Field-by-field Comparison
Field Before After
Text <b>Floyd's Cycle Finding (Graph-Reformulierung)</b><br>Definiere den gerichteten Graphen \(D = (V, A)\) mit {{c1::\(V = [n]\)}} und {{c2::\(A = \{(i, a[i]) \mid 1 \leq i \leq n\}\)}}.<br>Eigenschaften:<ul><li>Jeder Knoten hat genau {{c3::eine ausgehende Kante}}</li><li>Knoten \(n\) hat {{c4::keine eingehende Kante}} (weil \(a[i] \neq n\) für alle \(i\))</li><li>Der von Knoten \(n\) ausgehende Subgraph (immer der ausgehenden Kante folgen) besteht aus {{c5::einem Pfad gefolgt von einem Kreis}} (\(\rho\)-Form)</li></ul>
Extra Notation: Pfad hat \(k \geq 1\) Kanten, Kreis hat \(\ell \geq 3\) Kanten, mit \(k + \ell \leq n\).
Tags: ETH::2._Semester::A&W::2._Wahrscheinlichkeitstheorie_und_randomisierte_Algorithmen::8._Randomisierte_Algorithmen::7._Floyds_Cycle_Finding

Note 15: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: $}DD/7f+@3
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle
Bei der bimolekularen Reaktion \(A + B \to C\) ist die DGl \(u'(t) = k(a - u)(b - u)\) und nicht \(u'(t) = k(a + u)(b + u)\), weil:

Die Ausgangsstoffe \(A\) und \(B\) liegen in endlicher Menge vor und werden mit der Reaktion verbraucht. Die verbleibenden Mengen sind \(a - u\) bzw. \(b - u\), nicht \(a + u\) bzw. \(b + u\).

Konsequenz: Die Reaktion stoppt, sobald \(u = \min(a, b)\), weil dann ein Edukt aufgebraucht ist und \(u' = 0\) wird.

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle
Bei der bimolekularen Reaktion \(A + B \to C\) ist die DGl \(u'(t) = k(a - u)(b - u)\) und nicht \(u'(t) = k(a + u)(b + u)\), weil:

Die Ausgangsstoffe \(A\) und \(B\) liegen in endlicher Menge vor und werden mit der Reaktion verbraucht. Die verbleibenden Mengen sind \(a - u\) bzw. \(b - u\), nicht \(a + u\) bzw. \(b + u\).

Konsequenz: Die Reaktion stoppt, sobald \(u = \min(a, b)\), weil dann ein Edukt aufgebraucht ist und \(u' = 0\) wird.
Field-by-field Comparison
Field Before After
Text Bei der bimolekularen Reaktion \(A + B \to C\) ist die DGl \(u'(t) = k(a - u)(b - u)\) und <b>nicht</b> \(u'(t) = k(a + u)(b + u)\), weil:<br><br>{{c1::Die Ausgangsstoffe \(A\) und \(B\) liegen in <b>endlicher Menge</b> vor und werden mit der Reaktion <b>verbraucht</b>. Die verbleibenden Mengen sind \(a - u\) bzw. \(b - u\), nicht \(a + u\) bzw. \(b + u\).}}<br><br>Konsequenz: {{c2::Die Reaktion <b>stoppt</b>, sobald \(u = \min(a, b)\), weil dann ein Edukt aufgebraucht ist und \(u' = 0\) wird.}}
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle

Note 16: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: &w#tm2.1,Y
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung
Eine lineare Differentialgleichung \(a_n(x) y^{(n)} + \dots + a_0(x) y = s(x)\) heisst DGl mit konstanten Koeffizienten, falls alle Funktionen \(a_i(x)\) konstante Funktionen sind (d.h. \(a_i(x) = a_i \in \mathbb{R}\)).

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung
Eine lineare Differentialgleichung \(a_n(x) y^{(n)} + \dots + a_0(x) y = s(x)\) heisst DGl mit konstanten Koeffizienten, falls alle Funktionen \(a_i(x)\) konstante Funktionen sind (d.h. \(a_i(x) = a_i \in \mathbb{R}\)).
Field-by-field Comparison
Field Before After
Text Eine lineare Differentialgleichung \(a_n(x) y^{(n)} + \dots + a_0(x) y = s(x)\) heisst <b>DGl mit konstanten Koeffizienten</b>, falls {{c1::alle Funktionen \(a_i(x)\) konstante Funktionen sind}} (d.h. \(a_i(x) = a_i \in \mathbb{R}\)).
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung

Note 17: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: )hn#lezg{!
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::2._Lösungsstruktur
Satz (Fundamentallösungen): Eine lineare, homogene Differentialgleichung der Ordnung \(n\) besitzt \(n\) Lösungen \(y_1(x), \dots, y_n(x)\), sodass die allgemeine Lösung gegeben ist durch
\[ y(x) = C_1 y_1(x) + \dots + C_n y_n(x), \quad C_1, \dots, C_n \in \mathbb{R} \]Diese Lösungen werden Fundamentallösungen genannt.

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::2._Lösungsstruktur
Satz (Fundamentallösungen): Eine lineare, homogene Differentialgleichung der Ordnung \(n\) besitzt \(n\) Lösungen \(y_1(x), \dots, y_n(x)\), sodass die allgemeine Lösung gegeben ist durch
\[ y(x) = C_1 y_1(x) + \dots + C_n y_n(x), \quad C_1, \dots, C_n \in \mathbb{R} \]Diese Lösungen werden Fundamentallösungen genannt.
Field-by-field Comparison
Field Before After
Text <b>Satz (Fundamentallösungen):</b> Eine lineare, homogene Differentialgleichung der Ordnung \(n\) besitzt {{c1::\(n\) Lösungen \(y_1(x), \dots, y_n(x)\)}}, sodass die <b>allgemeine Lösung</b> gegeben ist durch<br>\[ {{c2::y(x) = C_1 y_1(x) + \dots + C_n y_n(x), \quad C_1, \dots, C_n \in \mathbb{R}}} \]Diese Lösungen werden {{c3::<b>Fundamentallösungen</b>}} genannt.
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::2._Lösungsstruktur

Note 18: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: 64..u6&9G{
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle
Beschränktes (logistisches) Wachstum mit Wachstumskonstante \(k > 0\) und Kapazitätsgrenze \(L > 0\):

\[ {{c1::u'(t) = k\,u(t)\left(1 - \dfrac{u(t)}{L}\right)}} \]
Charakteristisches Verhalten:
  • Für \(u(t) \ll L\): nahezu exponentielles Wachstum \(u' \approx k\,u\)
  • Für \(u(t) \to L\): Wachstumsrate \(u' \to 0\), die Grösse stagniert bei der Kapazität \(L\)

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle
Beschränktes (logistisches) Wachstum mit Wachstumskonstante \(k > 0\) und Kapazitätsgrenze \(L > 0\):

\[ {{c1::u'(t) = k\,u(t)\left(1 - \dfrac{u(t)}{L}\right)}} \]
Charakteristisches Verhalten:
  • Für \(u(t) \ll L\): nahezu exponentielles Wachstum \(u' \approx k\,u\)
  • Für \(u(t) \to L\): Wachstumsrate \(u' \to 0\), die Grösse stagniert bei der Kapazität \(L\)
Field-by-field Comparison
Field Before After
Text <b>Beschränktes (logistisches) Wachstum</b> mit Wachstumskonstante \(k &gt; 0\) und Kapazitätsgrenze \(L &gt; 0\):<br><br>\[ {{c1::u'(t) = k\,u(t)\left(1 - \dfrac{u(t)}{L}\right)}} \]<br>Charakteristisches Verhalten:<ul><li>Für \(u(t) \ll L\): {{c2::nahezu exponentielles Wachstum \(u' \approx k\,u\)}}</li><li>Für \(u(t) \to L\): {{c3::Wachstumsrate \(u' \to 0\), die Grösse stagniert bei der Kapazität \(L\)}}</li></ul>
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle

Note 19: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: =x+CE-oxI#
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::3._Eulerscher_Ansatz
Zum Lösen einer linearen, homogenen DGl mit konstanten Koeffizienten
\[ a_n u^{(n)}(x) + a_{n-1} u^{(n-1)}(x) + \dots + a_1 u'(x) + a_0 u(x) = 0 \]verwendet man den Eulerschen Ansatz:
\[ u(x) = e^{\lambda x} \]Einsetzen liefert die charakteristische Gleichung
\[ {{c2::a_n \lambda^n + a_{n-1} \lambda^{n-1} + \dots + a_1 \lambda + a_0 = 0}} \]bzw. das charakteristische Polynom {{c3::\(p(\lambda) = a_n \lambda^n + a_{n-1} \lambda^{n-1} + \dots + a_1 \lambda + a_0\)}}.

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::3._Eulerscher_Ansatz
Zum Lösen einer linearen, homogenen DGl mit konstanten Koeffizienten
\[ a_n u^{(n)}(x) + a_{n-1} u^{(n-1)}(x) + \dots + a_1 u'(x) + a_0 u(x) = 0 \]verwendet man den Eulerschen Ansatz:
\[ u(x) = e^{\lambda x} \]Einsetzen liefert die charakteristische Gleichung
\[ {{c2::a_n \lambda^n + a_{n-1} \lambda^{n-1} + \dots + a_1 \lambda + a_0 = 0}} \]bzw. das charakteristische Polynom {{c3::\(p(\lambda) = a_n \lambda^n + a_{n-1} \lambda^{n-1} + \dots + a_1 \lambda + a_0\)}}.
Field-by-field Comparison
Field Before After
Text Zum Lösen einer linearen, homogenen DGl mit konstanten Koeffizienten<br>\[ a_n u^{(n)}(x) + a_{n-1} u^{(n-1)}(x) + \dots + a_1 u'(x) + a_0 u(x) = 0 \]verwendet man den <b>Eulerschen Ansatz</b>:<br>\[ {{c1::u(x) = e^{\lambda x}}} \]Einsetzen liefert die <b>charakteristische Gleichung</b><br>\[ {{c2::a_n \lambda^n + a_{n-1} \lambda^{n-1} + \dots + a_1 \lambda + a_0 = 0}} \]bzw. das <b>charakteristische Polynom</b> {{c3::\(p(\lambda) = a_n \lambda^n + a_{n-1} \lambda^{n-1} + \dots + a_1 \lambda + a_0\)}}.
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::3._Eulerscher_Ansatz

Note 20: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: Ij@&w9=oPW
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::3._Eulerscher_Ansatz
Allgemeine Lösung (nur reelle Nullstellen): Hat das charakteristische Polynom einer linearen, homogenen DGl mit konstanten Koeffizienten ausschliesslich reelle Nullstellen \(\lambda_i\) mit Multiplizität \(m_i\) (\(i = 1, \dots, r\)), so ist die allgemeine Lösung
\[ {{c1::u(x) = \sum_{i=1}^{r} \left( \sum_{p=0}^{m_i - 1} C_{ip}\, x^p \right) e^{\lambda_i x}}} \]Pro Nullstelle \(\lambda_i\) liefert das also {{c2::\(m_i\) Fundamentallösungen \(e^{\lambda_i x}, x e^{\lambda_i x}, \dots, x^{m_i - 1} e^{\lambda_i x}\)}}.

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::3._Eulerscher_Ansatz
Allgemeine Lösung (nur reelle Nullstellen): Hat das charakteristische Polynom einer linearen, homogenen DGl mit konstanten Koeffizienten ausschliesslich reelle Nullstellen \(\lambda_i\) mit Multiplizität \(m_i\) (\(i = 1, \dots, r\)), so ist die allgemeine Lösung
\[ {{c1::u(x) = \sum_{i=1}^{r} \left( \sum_{p=0}^{m_i - 1} C_{ip}\, x^p \right) e^{\lambda_i x}}} \]Pro Nullstelle \(\lambda_i\) liefert das also {{c2::\(m_i\) Fundamentallösungen \(e^{\lambda_i x}, x e^{\lambda_i x}, \dots, x^{m_i - 1} e^{\lambda_i x}\)}}.
Field-by-field Comparison
Field Before After
Text <b>Allgemeine Lösung (nur reelle Nullstellen):</b> Hat das charakteristische Polynom einer linearen, homogenen DGl mit konstanten Koeffizienten ausschliesslich reelle Nullstellen \(\lambda_i\) mit Multiplizität \(m_i\) (\(i = 1, \dots, r\)), so ist die allgemeine Lösung<br>\[ {{c1::u(x) = \sum_{i=1}^{r} \left( \sum_{p=0}^{m_i - 1} C_{ip}\, x^p \right) e^{\lambda_i x}}} \]Pro Nullstelle \(\lambda_i\) liefert das also {{c2::\(m_i\) Fundamentallösungen \(e^{\lambda_i x}, x e^{\lambda_i x}, \dots, x^{m_i - 1} e^{\lambda_i x}\)}}.
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::3._Eulerscher_Ansatz

Note 21: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: PYb5.02vXc
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung
Eine Differentialgleichung der Form
\[ a_n(x) y^{(n)}(x) + a_{n-1}(x) y^{(n-1)}(x) + \dots + a_1(x) y'(x) + a_0(x) y(x) = s(x) \]heisst lineare Differentialgleichung mit Koeffizienten \(a_i(x)\).

  • Die Ordnung der DGl ist die maximale Ordnung der vorkommenden Ableitungen.
  • Die Funktion \(s(x)\) nennt man Störfunktion.

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung
Eine Differentialgleichung der Form
\[ a_n(x) y^{(n)}(x) + a_{n-1}(x) y^{(n-1)}(x) + \dots + a_1(x) y'(x) + a_0(x) y(x) = s(x) \]heisst lineare Differentialgleichung mit Koeffizienten \(a_i(x)\).

  • Die Ordnung der DGl ist die maximale Ordnung der vorkommenden Ableitungen.
  • Die Funktion \(s(x)\) nennt man Störfunktion.
Field-by-field Comparison
Field Before After
Text Eine Differentialgleichung der Form<br>\[ a_n(x) y^{(n)}(x) + a_{n-1}(x) y^{(n-1)}(x) + \dots + a_1(x) y'(x) + a_0(x) y(x) = s(x) \]heisst {{c1::<b>lineare Differentialgleichung</b>}} mit Koeffizienten \(a_i(x)\).<br><br><ul><li>Die <b>Ordnung</b> der DGl ist {{c2::die maximale Ordnung der vorkommenden Ableitungen}}.</li><li>Die Funktion \(s(x)\) nennt man {{c3::<b>Störfunktion</b>}}.</li></ul>
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung

Note 22: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: Qp3^E,]TbW
modified

Before

Front

ETH::2._Semester::Analysis::4._Funktionen::4._Elementare_Funktionen::6._Transformationen
Alle drei Transformationen (Streckung/Verschiebung in x- und y-Richtung) sind darstellbar als zusammengesetzte Funktion: \[ g(x) = s(u(x)) = s \circ u(x) \]Dabei nennt man \(s\) die äussere und \(u\) die innere Funktion.

Back

ETH::2._Semester::Analysis::4._Funktionen::4._Elementare_Funktionen::6._Transformationen
Alle drei Transformationen (Streckung/Verschiebung in x- und y-Richtung) sind darstellbar als zusammengesetzte Funktion: \[ g(x) = s(u(x)) = s \circ u(x) \]Dabei nennt man \(s\) die äussere und \(u\) die innere Funktion.

Beispiel: Die horizontale Verschiebung \(g(x) = f(x + k)\) lässt sich schreiben als \(g(x) = f(h(x))\) mit innerer Funktion \(h(x) = x + k\).

After

Front

ETH::2._Semester::Analysis::4._Funktionen::4._Elementare_Funktionen::6._Transformationen
Alle drei Transformationen (Streckung/Verschiebung in x- und y-Richtung) sind darstellbar als zusammengesetzte Funktion: \[ g(x) = s(u(x)) = s \circ u(x) \]Dabei nennt man \(s\) die äussere und \(u\) die innere Funktion.

Back

ETH::2._Semester::Analysis::4._Funktionen::4._Elementare_Funktionen::6._Transformationen
Alle drei Transformationen (Streckung/Verschiebung in x- und y-Richtung) sind darstellbar als zusammengesetzte Funktion: \[ g(x) = s(u(x)) = s \circ u(x) \]Dabei nennt man \(s\) die äussere und \(u\) die innere Funktion.

Beispiel: Die horizontale Verschiebung \(g(x) = f(x + k)\) lässt sich schreiben als \(g(x) = f(h(x))\) mit innerer Funktion \(h(x) = x + k\).
Field-by-field Comparison
Field Before After
Text Alle drei Transformationen (Streckung/Verschiebung in x- und y-Richtung) sind darstellbar als <i>zusammengesetzte Funktion</i>: \[ g(x) = s(u(x)) = s \circ u(x) \]Dabei nennt man \(s\) die {{c1::äussere}} und \(u\) die {{c2::innere}} Funktion. Alle drei Transformationen (Streckung/Verschiebung in x- und y-Richtung) sind darstellbar als <i>zusammengesetzte Funktion</i>: \[ g(x) = s(u(x)) = s \circ u(x) \]Dabei nennt man \(s\) die {{c1::äussere}} und \(u\) die {{c1::innere}} Funktion.
Tags: ETH::2._Semester::Analysis::4._Funktionen::4._Elementare_Funktionen::6._Transformationen

Note 23: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: W!ocL61JGV
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung
Eine lineare Differentialgleichung
\[ a_n(x) y^{(n)}(x) + \dots + a_0(x) y(x) = s(x) \]heisst:
  • homogen, falls \(s(x) = 0\)
  • inhomogen, falls \(s(x) \neq 0\)

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung
Eine lineare Differentialgleichung
\[ a_n(x) y^{(n)}(x) + \dots + a_0(x) y(x) = s(x) \]heisst:
  • homogen, falls \(s(x) = 0\)
  • inhomogen, falls \(s(x) \neq 0\)
Field-by-field Comparison
Field Before After
Text Eine lineare Differentialgleichung<br>\[ a_n(x) y^{(n)}(x) + \dots + a_0(x) y(x) = s(x) \]heisst:<ul><li>{{c1::<b>homogen</b>}}, falls {{c2::\(s(x) = 0\)}}</li><li>{{c1::<b>inhomogen</b>}}, falls {{c2::\(s(x) \neq 0\)}}</li></ul>
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung

Note 24: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: X.y:I?=bL;
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::3._Eulerscher_Ansatz
Allgemeine Lösung (mit komplexen Nullstellen): Hat das charakteristische Polynom \(r\) reelle Nullstellen \(\lambda_i\) (Multiplizität \(m_i\)) und \(s\) Paare komplexer Nullstellen \(a_j \pm i b_j\) (Multiplizität \(m_j\)), so ist die allgemeine Lösung
\[ \begin{gathered} u(x) = \sum_{i=1}^{r} \left( \sum_{p=0}^{m_i - 1} C_{ip}\, x^p \right) e^{\lambda_i x} \\ {{c1::+ \sum_{j=1}^{s} \sum_{q=0}^{m_j - 1} \left( A_{jq}\, x^q\, e^{a_j x} \sin(b_j x) + B_{jq}\, x^q\, e^{a_j x} \cos(b_j x) \right)}} \end{gathered} \]
Pro komplexem Paar \(a_j \pm i b_j\) treten also Fundamentallösungen der Form {{c2::\(x^q e^{a_j x} \sin(b_j x)\) und \(x^q e^{a_j x} \cos(b_j x)\) für \(q = 0, \dots, m_j - 1\)}} auf.

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::3._Eulerscher_Ansatz
Allgemeine Lösung (mit komplexen Nullstellen): Hat das charakteristische Polynom \(r\) reelle Nullstellen \(\lambda_i\) (Multiplizität \(m_i\)) und \(s\) Paare komplexer Nullstellen \(a_j \pm i b_j\) (Multiplizität \(m_j\)), so ist die allgemeine Lösung
\[ \begin{gathered} u(x) = \sum_{i=1}^{r} \left( \sum_{p=0}^{m_i - 1} C_{ip}\, x^p \right) e^{\lambda_i x} \\ {{c1::+ \sum_{j=1}^{s} \sum_{q=0}^{m_j - 1} \left( A_{jq}\, x^q\, e^{a_j x} \sin(b_j x) + B_{jq}\, x^q\, e^{a_j x} \cos(b_j x) \right)}} \end{gathered} \]
Pro komplexem Paar \(a_j \pm i b_j\) treten also Fundamentallösungen der Form {{c2::\(x^q e^{a_j x} \sin(b_j x)\) und \(x^q e^{a_j x} \cos(b_j x)\) für \(q = 0, \dots, m_j - 1\)}} auf.
Field-by-field Comparison
Field Before After
Text <b>Allgemeine Lösung (mit komplexen Nullstellen):</b> Hat das charakteristische Polynom \(r\) reelle Nullstellen \(\lambda_i\) (Multiplizität \(m_i\)) und \(s\) Paare komplexer Nullstellen \(a_j \pm i b_j\) (Multiplizität \(m_j\)), so ist die allgemeine Lösung<br>\[ \begin{gathered} u(x) = \sum_{i=1}^{r} \left( \sum_{p=0}^{m_i - 1} C_{ip}\, x^p \right) e^{\lambda_i x} \\ {{c1::+ \sum_{j=1}^{s} \sum_{q=0}^{m_j - 1} \left( A_{jq}\, x^q\, e^{a_j x} \sin(b_j x) + B_{jq}\, x^q\, e^{a_j x} \cos(b_j x) \right)}} \end{gathered} \]<br>Pro komplexem Paar \(a_j \pm i b_j\) treten also Fundamentallösungen der Form {{c2::\(x^q e^{a_j x} \sin(b_j x)\) und \(x^q e^{a_j x} \cos(b_j x)\) für \(q = 0, \dots, m_j - 1\)}} auf.
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::3._Eulerscher_Ansatz

Note 25: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: XD?:-{*nv*
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::4._Bedingungen
Die allgemeine Lösung einer DGl der Ordnung \(n\) enthält \(n\) freie Konstanten. Um eine konkrete Lösung auszuwählen, muss man also \(n\) Bedingungen vorgeben. Zwei Strategien:

Anfangswertproblem (AWP): Alle Bedingungen werden an derselben Stelle \(t_0\) vorgegeben, z.B. für \(n = 2\): \(u(t_0) = u_0,\ u'(t_0) = v_0\).

Randwertproblem (RWP): Die Bedingungen werden an verschiedenen Stellen vorgegeben, z.B. für \(n = 2\): \(u(t_0) = u_0,\ u(t_1) = u_1\) mit \(t_0 \neq t_1\).

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::4._Bedingungen
Die allgemeine Lösung einer DGl der Ordnung \(n\) enthält \(n\) freie Konstanten. Um eine konkrete Lösung auszuwählen, muss man also \(n\) Bedingungen vorgeben. Zwei Strategien:

Anfangswertproblem (AWP): Alle Bedingungen werden an derselben Stelle \(t_0\) vorgegeben, z.B. für \(n = 2\): \(u(t_0) = u_0,\ u'(t_0) = v_0\).

Randwertproblem (RWP): Die Bedingungen werden an verschiedenen Stellen vorgegeben, z.B. für \(n = 2\): \(u(t_0) = u_0,\ u(t_1) = u_1\) mit \(t_0 \neq t_1\).
Field-by-field Comparison
Field Before After
Text Die allgemeine Lösung einer DGl der Ordnung \(n\) enthält {{c1::\(n\) freie Konstanten}}. Um eine konkrete Lösung auszuwählen, muss man also \(n\) Bedingungen vorgeben. Zwei Strategien:<br><br><b>Anfangswertproblem (AWP):</b> {{c2::Alle Bedingungen werden an <b>derselben Stelle</b> \(t_0\) vorgegeben}}, z.B. für \(n = 2\): {{c3::\(u(t_0) = u_0,\ u'(t_0) = v_0\)}}.<br><br><b>Randwertproblem (RWP):</b> {{c4::Die Bedingungen werden an <b>verschiedenen Stellen</b> vorgegeben}}, z.B. für \(n = 2\): {{c5::\(u(t_0) = u_0,\ u(t_1) = u_1\) mit \(t_0 \neq t_1\)}}.
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::4._Bedingungen

Note 26: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: [qecP[HHF2
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle
Welche der folgenden DGl beschreibt beschränktes Wachstum (eine Grösse, die nicht beliebig gross werden kann)?
  • \(u' = k\,u \cdot \dfrac{u}{L}\): nicht beschränkt: für \(u \to \infty\) wächst \(u'\) sogar quadratisch
  • \(u' = k\,u\,\bigl(1 + \dfrac{u}{L}\bigr)\): nicht beschränkt: \(u'\) wächst mit \(u\) immer schneller
  • \(u' = k\,u\,\dfrac{L}{u} = k\,L\): nicht beschränkt: konstantes Wachstum, also lineares unbegrenztes Wachstum
  • \(u' = k\,u\,\bigl(1 - \dfrac{u}{L}\bigr)\): beschränkt, da \(u' \to 0\) für \(u \to L\)

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle
Welche der folgenden DGl beschreibt beschränktes Wachstum (eine Grösse, die nicht beliebig gross werden kann)?
  • \(u' = k\,u \cdot \dfrac{u}{L}\): nicht beschränkt: für \(u \to \infty\) wächst \(u'\) sogar quadratisch
  • \(u' = k\,u\,\bigl(1 + \dfrac{u}{L}\bigr)\): nicht beschränkt: \(u'\) wächst mit \(u\) immer schneller
  • \(u' = k\,u\,\dfrac{L}{u} = k\,L\): nicht beschränkt: konstantes Wachstum, also lineares unbegrenztes Wachstum
  • \(u' = k\,u\,\bigl(1 - \dfrac{u}{L}\bigr)\): beschränkt, da \(u' \to 0\) für \(u \to L\)
Field-by-field Comparison
Field Before After
Text Welche der folgenden DGl beschreibt <b>beschränktes Wachstum</b> (eine Grösse, die nicht beliebig gross werden kann)?<ul><li>\(u' = k\,u \cdot \dfrac{u}{L}\): {{c1::nicht beschränkt: für \(u \to \infty\) wächst \(u'\) sogar quadratisch}}</li><li>\(u' = k\,u\,\bigl(1 + \dfrac{u}{L}\bigr)\): {{c1::nicht beschränkt: \(u'\) wächst mit \(u\) immer schneller}}</li><li>\(u' = k\,u\,\dfrac{L}{u} = k\,L\): {{c1::nicht beschränkt: konstantes Wachstum, also lineares unbegrenztes Wachstum}}</li><li>\(u' = k\,u\,\bigl(1 - \dfrac{u}{L}\bigr)\): {{c2::beschränkt, da \(u' \to 0\) für \(u \to L\)}}</li></ul>
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle

Note 27: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: ]e,H2sK$mq
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::3._Mechanik
Mechanische Probleme: Bewegung wird über die wirkenden Kräfte modelliert. Nach Newton gilt für jede Kraft \(F\):

\[ {{c1::F = m\,\ddot{y} = m\,a}} \]
wobei \(y\) die Position des Körpers und {{c3::\(a = \ddot{y}\) seine Beschleunigung}} ist. Die DGl entsteht, indem alle Kräfte aufsummiert und gleich \(m\,\ddot{y}\) gesetzt werden.

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::3._Mechanik
Mechanische Probleme: Bewegung wird über die wirkenden Kräfte modelliert. Nach Newton gilt für jede Kraft \(F\):

\[ {{c1::F = m\,\ddot{y} = m\,a}} \]
wobei \(y\) die Position des Körpers und {{c3::\(a = \ddot{y}\) seine Beschleunigung}} ist. Die DGl entsteht, indem alle Kräfte aufsummiert und gleich \(m\,\ddot{y}\) gesetzt werden.
Field-by-field Comparison
Field Before After
Text <b>Mechanische Probleme:</b> Bewegung wird über die wirkenden Kräfte modelliert. Nach Newton gilt für jede Kraft \(F\):<br><br>\[ {{c1::F = m\,\ddot{y} = m\,a}} \]<br>wobei {{c2::\(y\) die Position des Körpers}} und {{c3::\(a = \ddot{y}\) seine Beschleunigung}} ist. Die DGl entsteht, indem alle Kräfte aufsummiert und gleich \(m\,\ddot{y}\) gesetzt werden.
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::3._Mechanik

Note 28: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: fiDV6AZfLm
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::1._Methodik
Grundprinzip beim Aufstellen von DGln aus einer Bilanz: Die Änderungsrate einer Grösse \(y(t)\) ist die Differenz aus Zuwachsrate und Abnahmerate:

\[ {{c2::y'(t) = \text{Zuwachs}(t) - \text{Abnahme}(t)}} \]
Beide Raten sind in Einheiten pro Zeit angegeben und dürfen von \(t\) und/oder von \(y(t)\) selbst abhängen.

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::1._Methodik
Grundprinzip beim Aufstellen von DGln aus einer Bilanz: Die Änderungsrate einer Grösse \(y(t)\) ist die Differenz aus Zuwachsrate und Abnahmerate:

\[ {{c2::y'(t) = \text{Zuwachs}(t) - \text{Abnahme}(t)}} \]
Beide Raten sind in Einheiten pro Zeit angegeben und dürfen von \(t\) und/oder von \(y(t)\) selbst abhängen.
Field-by-field Comparison
Field Before After
Text <b>Grundprinzip</b> beim Aufstellen von DGln aus einer Bilanz: Die Änderungsrate einer Grösse \(y(t)\) ist die {{c1::Differenz aus Zuwachsrate und Abnahmerate}}:<br><br>\[ {{c2::y'(t) = \text{Zuwachs}(t) - \text{Abnahme}(t)}} \]<br>Beide Raten sind in {{c3::Einheiten pro Zeit}} angegeben und dürfen von \(t\) <b>und/oder</b> von \(y(t)\) selbst abhängen.
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::1._Methodik

Note 29: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: fsYIR[D{A1
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle
Bimolekulare Reaktion \(A + B \to C\) mit endlichen Anfangsmengen \(a, b\) und Reaktionskonstante \(k > 0\). Sei \(u(t)\) die Menge des Produkts \(C\) zur Zeit \(t\). Dann lautet die DGl:

\[ u'(t) = k\,(a - u(t))\,(b - u(t)) \]
Idee: Die Reaktionsrate ist proportional zum Produkt der verbleibenden Mengen \((a - u)\) von \(A\) und \((b - u)\) von \(B\), weil pro entstandenem \(C\) je ein \(A\) und ein \(B\) verbraucht werden.

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle
Bimolekulare Reaktion \(A + B \to C\) mit endlichen Anfangsmengen \(a, b\) und Reaktionskonstante \(k > 0\). Sei \(u(t)\) die Menge des Produkts \(C\) zur Zeit \(t\). Dann lautet die DGl:

\[ u'(t) = k\,(a - u(t))\,(b - u(t)) \]
Idee: Die Reaktionsrate ist proportional zum Produkt der verbleibenden Mengen \((a - u)\) von \(A\) und \((b - u)\) von \(B\), weil pro entstandenem \(C\) je ein \(A\) und ein \(B\) verbraucht werden.
Field-by-field Comparison
Field Before After
Text <b>Bimolekulare Reaktion</b> \(A + B \to C\) mit endlichen Anfangsmengen \(a, b\) und Reaktionskonstante \(k &gt; 0\). Sei \(u(t)\) die Menge des Produkts \(C\) zur Zeit \(t\). Dann lautet die DGl:<br><br>\[ {{c1::u'(t) = k\,(a - u(t))\,(b - u(t))}} \]<br>Idee: Die Reaktionsrate ist proportional zum Produkt der {{c2::verbleibenden Mengen \((a - u)\) von \(A\) und \((b - u)\) von \(B\)}}, weil pro entstandenem \(C\) je ein \(A\) und ein \(B\) verbraucht werden.
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle

Note 30: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: gxV}gd66Rd
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::2._Lösungsstruktur
Satz (Superpositionsprinzip): Sind \(y_1(x)\) und \(y_2(x)\) Lösungen einer linearen, homogenen Differentialgleichung, so ist auch
\[ y(x) = C_1 y_1(x) + C_2 y_2(x), \quad C_1, C_2 \in \mathbb{R} \]eine Lösung der gleichen Differentialgleichung.

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::2._Lösungsstruktur
Satz (Superpositionsprinzip): Sind \(y_1(x)\) und \(y_2(x)\) Lösungen einer linearen, homogenen Differentialgleichung, so ist auch
\[ y(x) = C_1 y_1(x) + C_2 y_2(x), \quad C_1, C_2 \in \mathbb{R} \]eine Lösung der gleichen Differentialgleichung.
Field-by-field Comparison
Field Before After
Text <b>Satz (Superpositionsprinzip):</b> Sind \(y_1(x)\) und \(y_2(x)\) Lösungen einer {{c1::linearen, homogenen}} Differentialgleichung, so ist auch<br>\[ {{c2::y(x) = C_1 y_1(x) + C_2 y_2(x), \quad C_1, C_2 \in \mathbb{R}}} \]eine Lösung der gleichen Differentialgleichung.
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::2._Lösungsstruktur

Note 31: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: q;kZaA@xt9
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung
Definition Differentialgleichung: Eine Differentialgleichung ist eine Gleichung, in welcher die gesuchte Funktion sowie deren Ableitungen auftreten.

Bezeichnungen am Beispiel \(u'(t) = r(a - u(t))\):
  • \(t\) heisst unabhängige Variable
  • \(u\) heisst abhängige Variable (gesuchte Funktion)

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung
Definition Differentialgleichung: Eine Differentialgleichung ist eine Gleichung, in welcher die gesuchte Funktion sowie deren Ableitungen auftreten.

Bezeichnungen am Beispiel \(u'(t) = r(a - u(t))\):
  • \(t\) heisst unabhängige Variable
  • \(u\) heisst abhängige Variable (gesuchte Funktion)
Field-by-field Comparison
Field Before After
Text <b>Definition Differentialgleichung:</b> Eine Differentialgleichung ist eine Gleichung, in welcher {{c1::die gesuchte Funktion sowie deren Ableitungen auftreten}}.<br><br>Bezeichnungen am Beispiel \(u'(t) = r(a - u(t))\):<ul><li>{{c2::\(t\) heisst <b>unabhängige Variable</b>}}</li><li>{{c3::\(u\) heisst <b>abhängige Variable</b> (gesuchte Funktion)}}</li></ul>
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::2._Lineare_homogene::1._Klassifizierung

Note 32: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: tvE6GF:g2Q
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::1._Methodik
5-Schritt-Methodik zum Aufstellen einer Differentialgleichung für eine Grösse \(y(t)\):
  1. Schritt 1: Veränderung in einem kleinen Zeitintervall \(\Delta t\) bilanzieren: {{c1::\(y(t + \Delta t) = y(t) + \text{Zuwachs} - \text{Abnahme}\)}}
  2. Schritt 2: Differenz bilden: \(\Delta y = y(t + \Delta t) - y(t)\)
  3. Schritt 3: Proportionale Veränderung (Differenzenquotient): {{c3::\(\dfrac{\Delta y}{\Delta t} = \dfrac{y(t + \Delta t) - y(t)}{\Delta t}\)}}
  4. Schritt 4: Grenzwert \(\Delta t \to 0\): {{c4::\(\dfrac{dy}{dt} = \lim\limits_{\Delta t \to 0} \dfrac{\Delta y}{\Delta t}\)}}
  5. Schritt 5: Differentialgleichung \(y'(t) = \dots\) zusammenfassen

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::1._Methodik
5-Schritt-Methodik zum Aufstellen einer Differentialgleichung für eine Grösse \(y(t)\):
  1. Schritt 1: Veränderung in einem kleinen Zeitintervall \(\Delta t\) bilanzieren: {{c1::\(y(t + \Delta t) = y(t) + \text{Zuwachs} - \text{Abnahme}\)}}
  2. Schritt 2: Differenz bilden: \(\Delta y = y(t + \Delta t) - y(t)\)
  3. Schritt 3: Proportionale Veränderung (Differenzenquotient): {{c3::\(\dfrac{\Delta y}{\Delta t} = \dfrac{y(t + \Delta t) - y(t)}{\Delta t}\)}}
  4. Schritt 4: Grenzwert \(\Delta t \to 0\): {{c4::\(\dfrac{dy}{dt} = \lim\limits_{\Delta t \to 0} \dfrac{\Delta y}{\Delta t}\)}}
  5. Schritt 5: Differentialgleichung \(y'(t) = \dots\) zusammenfassen
Field-by-field Comparison
Field Before After
Text <b>5-Schritt-Methodik</b> zum Aufstellen einer Differentialgleichung für eine Grösse \(y(t)\):<ol><li><b>Schritt 1:</b> Veränderung in einem kleinen Zeitintervall \(\Delta t\) bilanzieren: {{c1::\(y(t + \Delta t) = y(t) + \text{Zuwachs} - \text{Abnahme}\)}}</li><li><b>Schritt 2:</b> Differenz bilden: {{c2::\(\Delta y = y(t + \Delta t) - y(t)\)}}</li><li><b>Schritt 3:</b> Proportionale Veränderung (Differenzenquotient): {{c3::\(\dfrac{\Delta y}{\Delta t} = \dfrac{y(t + \Delta t) - y(t)}{\Delta t}\)}}</li><li><b>Schritt 4:</b> Grenzwert \(\Delta t \to 0\): {{c4::\(\dfrac{dy}{dt} = \lim\limits_{\Delta t \to 0} \dfrac{\Delta y}{\Delta t}\)}}</li><li><b>Schritt 5:</b> {{c5::Differentialgleichung \(y'(t) = \dots\) zusammenfassen}}</li></ol>
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::1._Methodik

Note 33: ETH::2. Semester::Analysis

Deck: ETH::2. Semester::Analysis
Note Type: Horvath Cloze
GUID: {#Z!M:@yu,
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle
Bevölkerungsmodell: Sei \(B(t)\) die Geburtenrate und \(T(t)\) die Sterberate (jeweils pro Zeiteinheit). Dann ist die DGl für die Bevölkerung \(y(t)\):

\[ y'(t) = B(t) - T(t) \]
Begründung: Im Intervall \(\Delta t\) gilt \(y(t+\Delta t) = y(t) + B(t)\,\Delta t - T(t)\,\Delta t\), und der Grenzwert \(\Delta t \to 0\) liefert die DGl.

Back

ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle
Bevölkerungsmodell: Sei \(B(t)\) die Geburtenrate und \(T(t)\) die Sterberate (jeweils pro Zeiteinheit). Dann ist die DGl für die Bevölkerung \(y(t)\):

\[ y'(t) = B(t) - T(t) \]
Begründung: Im Intervall \(\Delta t\) gilt \(y(t+\Delta t) = y(t) + B(t)\,\Delta t - T(t)\,\Delta t\), und der Grenzwert \(\Delta t \to 0\) liefert die DGl.
Field-by-field Comparison
Field Before After
Text <b>Bevölkerungsmodell:</b> Sei \(B(t)\) die Geburtenrate und \(T(t)\) die Sterberate (jeweils pro Zeiteinheit). Dann ist die DGl für die Bevölkerung \(y(t)\):<br><br>\[ {{c1::y'(t) = B(t) - T(t)}} \]<br>Begründung: Im Intervall \(\Delta t\) gilt {{c2::\(y(t+\Delta t) = y(t) + B(t)\,\Delta t - T(t)\,\Delta t\)}}, und der Grenzwert \(\Delta t \to 0\) liefert die DGl.
Tags: ETH::2._Semester::Analysis::6._Differentialgleichungen::1._Aufstellen::2._Modelle

Note 34: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: $JRc9>k3KE
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
Implementation of a semaphore without spinning (with a blocking queue \(Q_S\)):
acquire(S):                 release(S):
  if S > 0: dec(S)            if Q_S == \(\emptyset\): inc(S)
  else: put(Q_S, self);        else: get(Q_S, p);
        block(self)                  unblock(p)
The condition test plus queue operation must be atomic (e.g. under an internal lock). release only increments S if no one is waiting: otherwise it directly unblocks a waiting process without S ever becoming positive.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
Implementation of a semaphore without spinning (with a blocking queue \(Q_S\)):
acquire(S):                 release(S):
  if S > 0: dec(S)            if Q_S == \(\emptyset\): inc(S)
  else: put(Q_S, self);        else: get(Q_S, p);
        block(self)                  unblock(p)
The condition test plus queue operation must be atomic (e.g. under an internal lock). release only increments S if no one is waiting: otherwise it directly unblocks a waiting process without S ever becoming positive.

Advantage over busy-wait: waiting threads consume no CPU. The price is context-switch overhead, which only pays off once waits are long enough to dwarf it (short critical sections may still favour spinning).
Field-by-field Comparison
Field Before After
Text Implementation of a semaphore {{c1::without spinning (with a blocking queue \(Q_S\))}}: <pre>acquire(S): release(S): if S &gt; 0: dec(S) if Q_S == \(\emptyset\): inc(S) else: put(Q_S, self); else: get(Q_S, p); block(self) unblock(p)</pre>The condition test plus queue operation must be {{c2::atomic}} (e.g. under an internal lock). {{c3::<code>release</code> only increments <code>S</code> if no one is waiting}}: otherwise it directly unblocks a waiting process without <code>S</code> ever becoming positive.
Extra Advantage over busy-wait: waiting threads consume no CPU. The price is context-switch overhead, which only pays off once waits are long enough to dwarf it (short critical sections may still favour spinning).
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores

Note 35: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: +7_a8+a@b@
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
In the 2nd reusable-barrier trial, the release(mutex) is moved to after the release(barrier) on the entry side (and analogously on the exit side). It still fails because a single process can lap the others: while \(n-1\) processes are still in the post-barrier region, one fast process re-enters the entry section, increments count, and could even reach count == n a second time before the others have finished the first round. Violated invariant: "even when a single process has passed the barrier, barrier = 0": the lapping process leaves barrier open behind it.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
In the 2nd reusable-barrier trial, the release(mutex) is moved to after the release(barrier) on the entry side (and analogously on the exit side). It still fails because a single process can lap the others: while \(n-1\) processes are still in the post-barrier region, one fast process re-enters the entry section, increments count, and could even reach count == n a second time before the others have finished the first round. Violated invariant: "even when a single process has passed the barrier, barrier = 0": the lapping process leaves barrier open behind it.

The fundamental issue: a single semaphore cannot serve as both "all have arrived" and "all have left". Two semaphores in sequence are needed.
Field-by-field Comparison
Field Before After
Text In the 2nd reusable-barrier trial, the <code>release(mutex)</code> is moved to <em>after</em> the <code>release(barrier)</code> on the entry side (and analogously on the exit side). It still fails because {{c1::a single process can lap the others: while \(n-1\) processes are still in the post-barrier region, one fast process re-enters the entry section, increments <code>count</code>, and could even reach <code>count == n</code> a second time before the others have finished the first round}}. Violated invariant: {{c2::"even when a single process has passed the barrier, <code>barrier = 0</code>": the lapping process leaves <code>barrier</code> open behind it}}.
Extra The fundamental issue: a single semaphore cannot serve as both "all have arrived" and "all have left". Two semaphores in sequence are needed.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers

Note 36: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: -T60qL&2-|
modified

Before

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
The three conditions for a correct critical-section solution according to Ben-Ari are mutual exclusion (statements from CSes of different processes must not interleave), freedom from deadlock (if some processes are trying to enter a CS, at least one must eventually succeed), and freedom from starvation (any process trying to enter its CS must eventually succeed).

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
The three conditions for a correct critical-section solution according to Ben-Ari are mutual exclusion (statements from CSes of different processes must not interleave), freedom from deadlock (if some processes are trying to enter a CS, at least one must eventually succeed), and freedom from starvation (any process trying to enter its CS must eventually succeed).

Hierarchy: starvation freedom \(\Rightarrow\) deadlock freedom (if every individual gets through, then certainly some individual gets through), but not the converse.

After

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
The three conditions for a correct critical-section solution according to Ben-Ari are:
  1. Mutual exclusion (statements from CSes of different processes must not interleave).
  2. Freedom from deadlock (if some processes are trying to enter a CS, at least one must eventually succeed).
  3. Freedom from starvation (any process trying to enter its CS must eventually succeed).

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
The three conditions for a correct critical-section solution according to Ben-Ari are:
  1. Mutual exclusion (statements from CSes of different processes must not interleave).
  2. Freedom from deadlock (if some processes are trying to enter a CS, at least one must eventually succeed).
  3. Freedom from starvation (any process trying to enter its CS must eventually succeed).

Hierarchy: starvation freedom \(\Rightarrow\) deadlock freedom (if every individual gets through, then certainly some individual gets through), but not the converse.
Field-by-field Comparison
Field Before After
Text The three conditions for a correct critical-section solution according to Ben-Ari are {{c1::mutual exclusion (statements from CSes of different processes must not interleave)}}, {{c2::freedom from deadlock (if some processes are trying to enter a CS, at least one must eventually succeed)}}, and {{c3::freedom from starvation (any process trying to enter its CS must eventually succeed)}}. The three conditions for a correct critical-section solution according to Ben-Ari are:<br><ol><li>{{c1::Mutual exclusion (statements from CSes of different processes must not interleave)}}.</li><li>{{c2::Freedom from deadlock (if some processes are trying to enter a CS, at least one must eventually succeed)}}.</li><li>{{c3::Freedom from starvation (any process trying to enter its CS must eventually succeed)}}.</li></ol>
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers

Note 37: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: /J$dsYJ
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
A barrier synchronises a number \(n\) of processes such that no process passes the barrier until all \(n\) of them have reached it.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
A barrier synchronises a number \(n\) of processes such that no process passes the barrier until all \(n\) of them have reached it.

Unlike a rendezvous (which is for exactly two processes), a barrier generalises to arbitrarily many. This fits BSP naturally: between any two supersteps stands a barrier.
Field-by-field Comparison
Field Before After
Text A {{c1::barrier}} synchronises {{c2::a number \(n\) of processes such that no process passes the barrier until all \(n\) of them have reached it}}.
Extra Unlike a rendezvous (which is for exactly two processes), a barrier generalises to arbitrarily many. This fits BSP naturally: between any two supersteps stands a barrier.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers

Note 38: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: 1*Jyz+ZJLF
modified

Before

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
When constructing mutex algorithms from atomic registers, three assumptions are made:
  1. atomic reads and writes of primitive-type variables
  2. no reorderings of read/write sequences (not true in practice; assumed here for simplicity) 
  3. threads that enter a critical section eventually leave it.
About progress outside the critical section, no assumption is made.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
When constructing mutex algorithms from atomic registers, three assumptions are made:
  1. atomic reads and writes of primitive-type variables
  2. no reorderings of read/write sequences (not true in practice; assumed here for simplicity) 
  3. threads that enter a critical section eventually leave it.
About progress outside the critical section, no assumption is made.

Threads may therefore stall, die, or pause arbitrarily long outside a CS. This matters for arguments like starvation freedom: an algorithm must not rely on the "other" thread continuing to make progress.

After

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
When constructing mutex algorithms from atomic registers, three assumptions are made:
  1. atomic reads and writes of primitive-type variables
  2. no reorderings of read/write sequences (not true in practice; assumed here for simplicity) 
  3. threads that enter a critical section eventually leave it.
About progress outside the critical section, no assumption is made.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
When constructing mutex algorithms from atomic registers, three assumptions are made:
  1. atomic reads and writes of primitive-type variables
  2. no reorderings of read/write sequences (not true in practice; assumed here for simplicity) 
  3. threads that enter a critical section eventually leave it.
About progress outside the critical section, no assumption is made.

Threads may therefore stall, die, or pause arbitrarily long outside a CS. This matters for arguments like starvation freedom: an algorithm must not rely on the "other" thread continuing to make progress.
Field-by-field Comparison
Field Before After
Text When constructing mutex algorithms from atomic registers, three assumptions are made: <br><ol><li>{{c1::atomic reads and writes of primitive-type variables}}</li><li>{{c2::no reorderings of read/write sequences (not true in practice; assumed here for simplicity)}}&nbsp;</li><li>{{c3::threads that enter a critical section eventually leave it}}. </li></ol>About progress {{c4::outside the critical section, no assumption is made}}.<br> When constructing mutex algorithms from atomic registers, three assumptions are made: <br><ol><li>{{c1::atomic reads and writes of primitive-type variables}}</li><li>{{c2::no reorderings of read/write sequences (not true in practice; assumed here for simplicity)}}&nbsp;</li><li>{{c3::threads that enter a critical section eventually leave it}}. </li></ol>About progress outside the critical section, {{c4::no assumption is made}}.<br>
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers

Note 39: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: 43#$Fc|Xs+
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
Two-phase barrier solution: with mutex=1, barrier1=0, barrier2=1, count=0,
acquire(mutex)
count++
if (count==n) { acquire(barrier2); release(barrier1); }
release(mutex)
acquire(barrier1); release(barrier1);   // phase 1
acquire(mutex)
count--
if (count==0) { acquire(barrier1); release(barrier2); }
release(mutex)
acquire(barrier2); release(barrier2);   // phase 2
Idea: two semaphores act as alternating gates: the \(n\)-th arriver flips barrier1 open and barrier2 closed; the last leaver flips them back. Between phases the invariant is barrier1 = 1 and barrier2 = 0 for all processes (and after phase 2: barrier1 = 0, barrier2 = 1).

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
Two-phase barrier solution: with mutex=1, barrier1=0, barrier2=1, count=0,
acquire(mutex)
count++
if (count==n) { acquire(barrier2); release(barrier1); }
release(mutex)
acquire(barrier1); release(barrier1);   // phase 1
acquire(mutex)
count--
if (count==0) { acquire(barrier1); release(barrier2); }
release(mutex)
acquire(barrier2); release(barrier2);   // phase 2
Idea: two semaphores act as alternating gates: the \(n\)-th arriver flips barrier1 open and barrier2 closed; the last leaver flips them back. Between phases the invariant is barrier1 = 1 and barrier2 = 0 for all processes (and after phase 2: barrier1 = 0, barrier2 = 1).

The barrier is now safely reusable: each iteration ends with the same initial state (count = 0, one barrier closed, one open). In practice this is very slow; specialised x86 barriers (e.g. spiral.net) can be many times faster.
Field-by-field Comparison
Field Before After
Text Two-phase barrier solution: with <code>mutex=1, barrier1=0, barrier2=1, count=0</code>, <pre>acquire(mutex) count++ if (count==n) { acquire(barrier2); release(barrier1); } release(mutex) acquire(barrier1); release(barrier1); // phase 1 acquire(mutex) count-- if (count==0) { acquire(barrier1); release(barrier2); } release(mutex) acquire(barrier2); release(barrier2); // phase 2</pre>Idea: {{c1::two semaphores act as alternating gates: the \(n\)-th arriver flips <code>barrier1</code> open and <code>barrier2</code> closed; the last leaver flips them back}}. Between phases the invariant is {{c2::<code>barrier1 = 1</code> and <code>barrier2 = 0</code> for all processes (and after phase 2: <code>barrier1 = 0</code>, <code>barrier2 = 1</code>)}}.
Extra The barrier is now safely reusable: each iteration ends with the same initial state (<code>count = 0</code>, one barrier closed, one open). In practice this is very slow; specialised x86 barriers (e.g. spiral.net) can be many times faster.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers

Note 40: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: 6>tVnB+D6%
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
Correct (one-shot) barrier with semaphores mutex = 1, barrier = 0 and integer count = 0:
acquire(mutex)
count++
release(mutex)
if (count == n) release(barrier)
acquire(barrier)
release(barrier)
The mutex protects the race on count++; the trailing acquire(barrier); release(barrier); is called a turnstile and ensures that each thread that gets through immediately admits the next, so all \(n\) threads pass in sequence.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
Correct (one-shot) barrier with semaphores mutex = 1, barrier = 0 and integer count = 0:
acquire(mutex)
count++
release(mutex)
if (count == n) release(barrier)
acquire(barrier)
release(barrier)
The mutex protects the race on count++; the trailing acquire(barrier); release(barrier); is called a turnstile and ensures that each thread that gets through immediately admits the next, so all \(n\) threads pass in sequence.

After one run, count = n and barrier = 1: the barrier is not reusable (a reusable version needs a second phase, often called a "two-phase barrier"). Exactly one thread (the \(n\)-th) calls release(barrier), and the turnstile passes the token along.
Field-by-field Comparison
Field Before After
Text Correct (one-shot) barrier with semaphores <code>mutex = 1</code>, <code>barrier = 0</code> and integer <code>count = 0</code>: <pre>acquire(mutex) count++ release(mutex) if (count == n) release(barrier) acquire(barrier) release(barrier)</pre>The mutex protects {{c1::the race on <code>count++</code>}}; the trailing <code>acquire(barrier); release(barrier);</code> is called a {{c2::turnstile}} and ensures that {{c3::each thread that gets through immediately admits the next, so all \(n\) threads pass in sequence}}.
Extra After one run, <code>count = n</code> and <code>barrier = 1</code>: the barrier is not reusable (a reusable version needs a second phase, often called a "two-phase barrier"). Exactly one thread (the \(n\)-th) calls <code>release(barrier)</code>, and the turnstile passes the token along.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers

Note 41: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: 8rwYF+/ZRs
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::Terminology
Starvation denotes the repeated but unsuccessful attempt of a recently unblocked process to continue its execution.

Back

ETH::2._Semester::PProg::Terminology
Starvation denotes the repeated but unsuccessful attempt of a recently unblocked process to continue its execution.

Contrast with deadlock: under deadlock the whole system makes no progress; under starvation the system does make progress, but a particular process never gets through. Starvation is a liveness violation.
Field-by-field Comparison
Field Before After
Text {{c1::Starvation}} denotes {{c2::the repeated but unsuccessful attempt of a recently unblocked process to continue its execution}}.
Extra Contrast with deadlock: under deadlock the whole system makes no progress; under starvation the system does make progress, but a particular process never gets through. Starvation is a liveness violation.
Tags: ETH::2._Semester::PProg::Terminology

Note 42: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID:
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
Scaled dot product \(x = (a^T \cdot d) \cdot z\) with partial sums \(x_A, x_B\) on two threads: with locks (lock(); x = x + x_A; unlock(); in both threads) it is unclear when \(x\) is finished. With a semaphore \(S\) initialised to \(0\), the order can be enforced: thread A computes x = x + x_A and then calls release(S); thread B does acquire(S) first, then x = x + x_B, then x = x*z. This guarantees that A adds before B.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
Scaled dot product \(x = (a^T \cdot d) \cdot z\) with partial sums \(x_A, x_B\) on two threads: with locks (lock(); x = x + x_A; unlock(); in both threads) it is unclear when \(x\) is finished. With a semaphore \(S\) initialised to \(0\), the order can be enforced: thread A computes x = x + x_A and then calls release(S); thread B does acquire(S) first, then x = x + x_B, then x = x*z. This guarantees that A adds before B.

This is exactly what locks cannot deliver: not only mutual exclusion, but a concrete ordering between threads. The trick with initial value \(0\): the first acquire blocks until a release unblocks it: the semaphore is used as a signal, not as a mutex.
Field-by-field Comparison
Field Before After
Text Scaled dot product \(x = (a^T \cdot d) \cdot z\) with partial sums \(x_A, x_B\) on two threads: with locks ({{c1::<code>lock(); x = x + x_A; unlock();</code> in both threads}}) it is unclear <i>when</i> \(x\) is finished. With a semaphore \(S\) initialised to \(0\), the order can be enforced: {{c2::thread A computes <code>x = x + x_A</code> and then calls <code>release(S)</code>}}; {{c2::thread B does <code>acquire(S)</code> first, then <code>x = x + x_B</code>, then <code>x = x*z</code>}}. This guarantees that A adds before B.
Extra This is exactly what locks cannot deliver: not only mutual exclusion, but a concrete ordering between threads. The trick with initial value \(0\): the first <code>acquire</code> blocks until a <code>release</code> unblocks it: the semaphore is used as a <em>signal</em>, not as a mutex.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores

Note 43: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: >^UKYB#lC@
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
A naive reusable barrier extends the one-shot barrier with a symmetric "second half"
acquire(mutex); count--; release(mutex);
if (count==0) acquire(barrier);
after the turnstile, intended to reset count and barrier. It is broken because the invariant "after all processes have passed, barrier = 0" is violated: release(barrier) can be executed multiple times across iterations before any thread reaches the resetting acquire(barrier), so barrier drifts to \(2, 3, \dots\), and the if (count == 0) acquire(barrier) check happens outside the mutex, so it cannot reliably restore the semaphore to 0 in the presence of fast re-entrants.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
A naive reusable barrier extends the one-shot barrier with a symmetric "second half"
acquire(mutex); count--; release(mutex);
if (count==0) acquire(barrier);
after the turnstile, intended to reset count and barrier. It is broken because the invariant "after all processes have passed, barrier = 0" is violated: release(barrier) can be executed multiple times across iterations before any thread reaches the resetting acquire(barrier), so barrier drifts to \(2, 3, \dots\), and the if (count == 0) acquire(barrier) check happens outside the mutex, so it cannot reliably restore the semaphore to 0 in the presence of fast re-entrants.

Concrete scheduling: thread A finishes phase 1 with count = 1; meanwhile B and C race into the next iteration, both increment count back up, hit count == n, and each calls release(barrier). The semaphore is no longer a clean 0/1 toggle. The fix is a proper two-phase split with separate semaphores for the two halves.
Field-by-field Comparison
Field Before After
Text A naive reusable barrier extends the one-shot barrier with a symmetric "second half" <pre>acquire(mutex); count--; release(mutex); if (count==0) acquire(barrier);</pre>after the turnstile, intended to reset <code>count</code> and <code>barrier</code>. It is broken because {{c1::the invariant "after all processes have passed, <code>barrier = 0</code>" is violated: <code>release(barrier)</code> can be executed multiple times across iterations before any thread reaches the resetting <code>acquire(barrier)</code>, so <code>barrier</code> drifts to \(2, 3, \dots\)}}, and {{c2::the <code>if (count == 0) acquire(barrier)</code> check happens outside the mutex, so it cannot reliably restore the semaphore to 0 in the presence of fast re-entrants}}.
Extra Concrete scheduling: thread A finishes phase 1 with <code>count = 1</code>; meanwhile B and C race into the next iteration, both increment <code>count</code> back up, hit <code>count == n</code>, and each calls <code>release(barrier)</code>. The semaphore is no longer a clean 0/1 toggle. The fix is a proper two-phase split with separate semaphores for the two halves.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers

Note 44: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: >aq{oB;vc7
modified

Before

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
The structure of the critical-section problem per process inside an infinite loop is: non-critical section \(\to\) preprotocol \(\to\) critical section \(\to\) postprotocol.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
The structure of the critical-section problem per process inside an infinite loop is: non-critical section \(\to\) preprotocol \(\to\) critical section \(\to\) postprotocol.

Preprotocol = entry code (lock acquire). Postprotocol = exit code (lock release). Only global variables are shared between processes; local variables are private per process.

After

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
The structure of the critical-section problem per process inside an infinite loop is:
non-critical section \(\to\) preprotocol \(\to\) critical section \(\to\) postprotocol.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
The structure of the critical-section problem per process inside an infinite loop is:
non-critical section \(\to\) preprotocol \(\to\) critical section \(\to\) postprotocol.

Preprotocol = entry code (lock acquire). Postprotocol = exit code (lock release). Only global variables are shared between processes; local variables are private per process.
Field-by-field Comparison
Field Before After
Text The structure of the critical-section problem per process inside an infinite loop is: {{c1::non-critical section}} \(\to\) {{c2::preprotocol}} \(\to\) {{c3::critical section}} \(\to\) {{c4::postprotocol}}. The structure of the critical-section problem per process inside an infinite loop is: <br>{{c1::non-critical section}} \(\to\) {{c1::preprotocol}} \(\to\) {{c1::critical section}} \(\to\) {{c1::postprotocol}}.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers

Note 45: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: ?Sz*VQ/MVU
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition
Disadvantage of the plain producer-consumer with Lock + Condition: signal() is called on every enqueue and dequeue, even when no thread is currently waiting on that condition (a wasted call into the runtime). Dijkstra's Sleeping Barber variant adds two counters \(m\) and \(n\) with the semantics \(m \leq 0 \Leftrightarrow\) buffer full and \(-m\) producers are waiting and \(n \leq 0 \Leftrightarrow\) buffer empty and \(-n\) consumers are waiting, so signals are issued only when someone is actually waiting.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition
Disadvantage of the plain producer-consumer with Lock + Condition: signal() is called on every enqueue and dequeue, even when no thread is currently waiting on that condition (a wasted call into the runtime). Dijkstra's Sleeping Barber variant adds two counters \(m\) and \(n\) with the semantics \(m \leq 0 \Leftrightarrow\) buffer full and \(-m\) producers are waiting and \(n \leq 0 \Leftrightarrow\) buffer empty and \(-n\) consumers are waiting, so signals are issued only when someone is actually waiting.

Initial values: \(n = 0\) (buffer empty, no waiters), \(m = \text{size} - 1\) (one fewer free slot than capacity, matching the unused-slot trick of the underlying ring buffer). The barber metaphor: the customer (consumer) waits if no client is in the chair; the barber (producer) sleeps if no chair is free.
Field-by-field Comparison
Field Before After
Text Disadvantage of the plain producer-consumer with <code>Lock</code> + <code>Condition</code>: {{c1::<code>signal()</code> is called on every <code>enqueue</code> and <code>dequeue</code>, even when no thread is currently waiting on that condition (a wasted call into the runtime)}}. Dijkstra's <em>Sleeping Barber</em> variant adds {{c2::two counters \(m\) and \(n\)}} with the semantics {{c3::\(m \leq 0 \Leftrightarrow\) buffer full and \(-m\) producers are waiting}} and {{c3::\(n \leq 0 \Leftrightarrow\) buffer empty and \(-n\) consumers are waiting}}, so signals are issued only when someone is actually waiting.
Extra Initial values: \(n = 0\) (buffer empty, no waiters), \(m = \text{size} - 1\) (one fewer free slot than capacity, matching the unused-slot trick of the underlying ring buffer). The barber metaphor: the customer (consumer) waits if no client is in the chair; the barber (producer) sleeps if no chair is free.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition

Note 46: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: F1>/n6vs8v
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors
A monitor is an abstract data structure equipped with a set of operations that run in mutual exclusion, plus a mechanism to wait on conditions inside the monitor. Invented by Tony Hoare and Per Brinch Hansen (1974).

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors
A monitor is an abstract data structure equipped with a set of operations that run in mutual exclusion, plus a mechanism to wait on conditions inside the monitor. Invented by Tony Hoare and Per Brinch Hansen (1974).

Beyond mutual exclusion, a monitor must let a thread that finds a condition unsatisfied release the monitor lock, wait for the condition, and be signalled when it becomes true, all without busy-waiting.
Field-by-field Comparison
Field Before After
Text A {{c1::monitor}} is {{c2::an abstract data structure equipped with a set of operations that run in mutual exclusion}}, plus a mechanism to wait on conditions inside the monitor. Invented by {{c3::Tony Hoare and Per Brinch Hansen (1974)}}.
Extra Beyond mutual exclusion, a monitor must let a thread that finds a condition unsatisfied release the monitor lock, wait for the condition, and be signalled when it becomes true, all without busy-waiting.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors

Note 47: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: IglAO#3E9?
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::7._Deadlock_Avoidance
Two cases in which deadlock prevention by a fixed lock order is straightforward: different object types: document a fixed order between the types (e.g. "when moving an item from the hashtable to the work queue, never try to acquire the queue lock while holding the hashtable lock") and objects in an acyclic data structure: use the structure itself to determine an order (e.g. "if holding a tree node's lock, do not acquire other tree nodes' locks unless they are children").

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::7._Deadlock_Avoidance
Two cases in which deadlock prevention by a fixed lock order is straightforward: different object types: document a fixed order between the types (e.g. "when moving an item from the hashtable to the work queue, never try to acquire the queue lock while holding the hashtable lock") and objects in an acyclic data structure: use the structure itself to determine an order (e.g. "if holding a tree node's lock, do not acquire other tree nodes' locks unless they are children").

Both cases break the Coffman "circular wait" condition by imposing a total order on locks. The hard case (like transferTo or StringBuffer.append) is when two objects of the same type with no natural ordering are involved.
Field-by-field Comparison
Field Before After
Text Two cases in which deadlock prevention by a fixed lock order is straightforward: {{c1::different object types: document a fixed order between the types (e.g. "when moving an item from the hashtable to the work queue, never try to acquire the queue lock while holding the hashtable lock")}} and {{c2::objects in an acyclic data structure: use the structure itself to determine an order (e.g. "if holding a tree node's lock, do not acquire other tree nodes' locks unless they are children")}}.
Extra Both cases break the Coffman "circular wait" condition by imposing a total order on locks. The hard case (like <code>transferTo</code> or <code>StringBuffer.append</code>) is when two objects of the same type with no natural ordering are involved.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::7._Deadlock_Avoidance

Note 48: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: Jj5bulRE#&
modified

Before

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
In the 1st-try mutex
p2: while(wantq);
p3: wantp = true;
p4: critical section
the order "first wait for the neighbour, then set my own flag" violates mutual exclusion, because {{c2::both threads can leave their while with wantp{=}wantq{=}false before either of them sets its flag}}.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers
In the 1st-try mutex
p2: while(wantq);
p3: wantp = true;
p4: critical section
the order "first wait for the neighbour, then set my own flag" violates mutual exclusion, because {{c2::both threads can leave their while with wantp{=}wantq{=}false before either of them sets its flag}}.

Both threads enter the CS together; visible as state \((p4, q4, true, true)\) in the state-space diagram.

Naive fix: set the flag before the check. That solves ME but creates new problems (deadlock/livelock); see Dekker / Peterson.

After

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers


Here the order "first wait for the neighbour, then set my own flag" violates mutual exclusion, because {{c2::both threads can leave their while with wantp{=}wantq{=}false before either of them sets its flag}}.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers


Here the order "first wait for the neighbour, then set my own flag" violates mutual exclusion, because {{c2::both threads can leave their while with wantp{=}wantq{=}false before either of them sets its flag}}.

Both threads enter the CS together; visible as state \((p4, q4, true, true)\) in the state-space diagram.

Naive fix: set the flag before the check. That solves ME but creates new problems (deadlock/livelock); see Dekker / Peterson.
Field-by-field Comparison
Field Before After
Text In the 1st-try mutex <pre>p2: while(wantq); p3: wantp = true; p4: critical section</pre> the order "first wait for the neighbour, then set my own flag" violates {{c1::mutual exclusion}}, because {{c2::both threads can leave their <code>while</code> with <code>wantp{=}wantq{=}false</code> before either of them sets its flag}}. <img src="paste-2c297c3fe3ab4f7a63914ae8ad4be81fa93d9e11.jpg"><br><br>Here the order "first wait for the neighbour, then set my own flag" violates {{c1::mutual exclusion}}, because {{c2::both threads can leave their <code>while</code> with <code>wantp{=}wantq{=}false</code> before either of them sets its flag}}.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::5._Locks_with_Atomic_Registers

Note 49: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: L8nAd_#p<^
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
A rendezvous is a location in code at which two processes \(P\) and \(Q\) each wait for the other to arrive before either continues. It synchronises two threads at a common point.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
A rendezvous is a location in code at which two processes \(P\) and \(Q\) each wait for the other to arrive before either continues. It synchronises two threads at a common point.

Implementation with two semaphores P_Arrived and Q_Arrived (both initialised to 0): each thread releases "its" semaphore and acquires the other one.
Field-by-field Comparison
Field Before After
Text A {{c1::rendezvous}} is {{c2::a location in code at which two processes \(P\) and \(Q\) each wait for the other to arrive before either continues}}. It synchronises two threads at a common point.
Extra Implementation with two semaphores <code>P_Arrived</code> and <code>Q_Arrived</code> (both initialised to 0): each thread releases "its" semaphore and acquires the other one.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores

Note 50: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: LQq9qK6Fz1
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
Naive synchronised producer-consumer queue
synchronized void enqueue(long item) {
  while (isFull()) ; // wait
  doEnqueue(item);
}
is broken because the busy-wait holds the monitor lock the entire time, so no other thread (including the consumer that would make space) can enter the object: the producer spins forever and the consumer blocks at the entry. Effectively a deadlock between the spinning producer and any thread that would change the condition.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
Naive synchronised producer-consumer queue
synchronized void enqueue(long item) {
  while (isFull()) ; // wait
  doEnqueue(item);
}
is broken because the busy-wait holds the monitor lock the entire time, so no other thread (including the consumer that would make space) can enter the object: the producer spins forever and the consumer blocks at the entry. Effectively a deadlock between the spinning producer and any thread that would change the condition.

Lesson: any "wait until condition" pattern under a held lock must release the lock while waiting and reacquire it before re-checking. That is exactly what wait() / await() do.
Field-by-field Comparison
Field Before After
Text Naive synchronised producer-consumer queue <pre>synchronized void enqueue(long item) { while (isFull()) ; // wait doEnqueue(item); }</pre>is broken because {{c1::the busy-wait holds the monitor lock the entire time, so no other thread (including the consumer that would make space) can enter the object}}: the producer spins forever and the consumer blocks at the entry. Effectively a {{c2::deadlock between the spinning producer and any thread that would change the condition}}.
Extra Lesson: any "wait until condition" pattern under a held lock must <em>release</em> the lock while waiting and reacquire it before re-checking. That is exactly what <code>wait()</code> / <code>await()</code> do.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer

Note 51: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: Lf?|c7TXKB
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
Four invariants a correct barrier must satisfy: each of the processes eventually reaches the acquire statement; the barrier opens iff all processes have reached the barrier; count gives the number of processes that have passed the barrier; once all processes have reached the barrier, all waiting processes can continue.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
Four invariants a correct barrier must satisfy: each of the processes eventually reaches the acquire statement; the barrier opens iff all processes have reached the barrier; count gives the number of processes that have passed the barrier; once all processes have reached the barrier, all waiting processes can continue.

The naive 1st-try implementation violates the latter two: the race on count++ breaks (3), and the single release on a 0-initialised semaphore breaks (4).
Field-by-field Comparison
Field Before After
Text Four invariants a correct barrier must satisfy: {{c1::each of the processes eventually reaches the <code>acquire</code> statement}}; {{c2::the barrier opens iff all processes have reached the barrier}}; {{c3::<code>count</code> gives the number of processes that have passed the barrier}}; {{c4::once all processes have reached the barrier, all waiting processes can continue}}.
Extra The naive 1st-try implementation violates the latter two: the race on <code>count++</code> breaks (3), and the single <code>release</code> on a 0-initialised semaphore breaks (4).
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers

Note 52: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: MbxyJU2Qdg
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
Replacing the busy-wait with Thread.sleep(timeout) outside the synchronized block (while(true){ synchronized(this){ if (!isFull()){ doEnqueue(...); return; }} sleep(t); }) fixes the deadlock but has no good value for timeout: too short wastes CPU on repeated re-acquisition, too long adds latency between the queue freeing up and the producer noticing. The real wish is to be notified exactly when the condition becomes true (i.e. when a consumer dequeues), not to poll.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
Replacing the busy-wait with Thread.sleep(timeout) outside the synchronized block (while(true){ synchronized(this){ if (!isFull()){ doEnqueue(...); return; }} sleep(t); }) fixes the deadlock but has no good value for timeout: too short wastes CPU on repeated re-acquisition, too long adds latency between the queue freeing up and the producer noticing. The real wish is to be notified exactly when the condition becomes true (i.e. when a consumer dequeues), not to poll.

This motivates monitors / wait-notify: instead of polling, the producer waits on a condition and the consumer signals it after dequeuing.
Field-by-field Comparison
Field Before After
Text Replacing the busy-wait with <code>Thread.sleep(timeout)</code> outside the synchronized block (<code>while(true){ synchronized(this){ if (!isFull()){ doEnqueue(...); return; }} sleep(t); }</code>) fixes the deadlock but {{c1::has no good value for <code>timeout</code>}}: too short wastes CPU on repeated re-acquisition, too long adds latency between the queue freeing up and the producer noticing. The real wish is {{c2::to be notified exactly when the condition becomes true (i.e. when a consumer dequeues), not to poll}}.
Extra This motivates monitors / wait-notify: instead of polling, the producer waits on a condition and the consumer signals it after dequeuing.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer

Note 53: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: P5lCo*-DG/
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::7._Deadlock_Avoidance
Race conditions vs. deadlocks: race conditions, once you understand where they can occur, are relatively easy to handle with good programming practice and rules. Deadlock, by contrast, is the dominant problem of reasonably complex concurrent programs and must therefore be anticipated from the start.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::7._Deadlock_Avoidance
Race conditions vs. deadlocks: race conditions, once you understand where they can occur, are relatively easy to handle with good programming practice and rules. Deadlock, by contrast, is the dominant problem of reasonably complex concurrent programs and must therefore be anticipated from the start.
Field-by-field Comparison
Field Before After
Text Race conditions vs. deadlocks: {{c1::race conditions, once you understand where they can occur, are relatively easy to handle with good programming practice and rules}}. {{c2::Deadlock, by contrast, is the dominant problem of reasonably complex concurrent programs and must therefore be anticipated from the start}}.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::7._Deadlock_Avoidance

Note 54: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: S1F/!41?Q?
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition
Sleeping-Barber producer-consumer signalling logic:
enqueue(x): m--;            // claim a slot in advance
            if (m < 0) while (isFull()) notFull.await();
            doEnqueue(x);
            n++;
            if (n <= 0) notEmpty.signal();

dequeue():  n--;
            if (n < 0) while (isEmpty()) notEmpty.await();
            doDequeue();
            m++;
            if (m <= 0) notFull.signal();
The decrement-first / check-negative pattern: m-- followed by if (m < 0) reserves a slot and detects "buffer was full" before waiting; n++ followed by if (n <= 0) means "after my insert there is at least one consumer still waiting", so signal exactly then, saving the call when n > 0 (no one is waiting).

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition
Sleeping-Barber producer-consumer signalling logic:
enqueue(x): m--;            // claim a slot in advance
            if (m < 0) while (isFull()) notFull.await();
            doEnqueue(x);
            n++;
            if (n <= 0) notEmpty.signal();

dequeue():  n--;
            if (n < 0) while (isEmpty()) notEmpty.await();
            doDequeue();
            m++;
            if (m <= 0) notFull.signal();
The decrement-first / check-negative pattern: m-- followed by if (m < 0) reserves a slot and detects "buffer was full" before waiting; n++ followed by if (n <= 0) means "after my insert there is at least one consumer still waiting", so signal exactly then, saving the call when n > 0 (no one is waiting).

The asymmetry < 0 vs <= 0 on the wait side vs the signal side is intentional: at the moment of my own increment, my counter has just become +1 if I was the only waiter, so the condition for "someone else is still waiting" is <= 0.
Field-by-field Comparison
Field Before After
Text Sleeping-Barber producer-consumer signalling logic: <pre>enqueue(x): m--; // claim a slot in advance if (m &lt; 0) while (isFull()) notFull.await(); doEnqueue(x); n++; if (n &lt;= 0) notEmpty.signal(); dequeue(): n--; if (n &lt; 0) while (isEmpty()) notEmpty.await(); doDequeue(); m++; if (m &lt;= 0) notFull.signal();</pre>The decrement-first / check-negative pattern: {{c1::<code>m--</code> followed by <code>if (m &lt; 0)</code> reserves a slot and detects "buffer was full" before waiting}}; {{c2::<code>n++</code> followed by <code>if (n &lt;= 0)</code> means "after my insert there is at least one consumer still waiting", so signal exactly then, saving the call when <code>n &gt; 0</code> (no one is waiting)}}.
Extra The asymmetry <code>&lt; 0</code> vs <code>&lt;= 0</code> on the wait side vs the signal side is intentional: at the moment of <em>my own</em> increment, my counter has just become <code>+1</code> if I was the only waiter, so the condition for "someone else is still waiting" is <code>&lt;= 0</code>.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition

Note 55: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: SSYmrji*fb
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors
Why semaphores (and raw locks) are problematic for non-trivial coordination: they are unstructured: correct use requires a high level of programmer discipline (the right acquire order, the right release on every path, including exception paths) and it is easy to introduce deadlocks. What we want instead: a lock that we can temporarily escape from while waiting on a condition, and that signals us when the condition can become true.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors
Why semaphores (and raw locks) are problematic for non-trivial coordination: they are unstructured: correct use requires a high level of programmer discipline (the right acquire order, the right release on every path, including exception paths) and it is easy to introduce deadlocks. What we want instead: a lock that we can temporarily escape from while waiting on a condition, and that signals us when the condition can become true.

This wish list defines a monitor: a lock plus condition variables that atomically release the lock on wait and reacquire it on signal.
Field-by-field Comparison
Field Before After
Text Why semaphores (and raw locks) are problematic for non-trivial coordination: {{c1::they are unstructured: correct use requires a high level of programmer discipline (the right acquire order, the right release on every path, including exception paths) and it is easy to introduce deadlocks}}. What we want instead: {{c2::a lock that we can temporarily escape from while waiting on a condition, and that signals us when the condition can become true}}.
Extra This wish list defines a monitor: a lock plus condition variables that atomically release the lock on wait and reacquire it on signal.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors

Note 56: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: SX-B$lpC!#
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
A semaphore initialised to 1 (sem_mutex = Semaphore(1)) acts as a lock: lock() is sem_mutex.acquire() and unlock() is sem_mutex.release(). In general the value means: \(1\) is unlocked, \(0\) is locked, \(x > 0\) means \(x\) threads will be let into the "critical section".

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
A semaphore initialised to 1 (sem_mutex = Semaphore(1)) acts as a lock: lock() is sem_mutex.acquire() and unlock() is sem_mutex.release(). In general the value means: \(1\) is unlocked, \(0\) is locked, \(x > 0\) means \(x\) threads will be let into the "critical section".

A semaphore with initial value \(k > 1\) is therefore a generalised lock that admits up to \(k\) threads concurrently (a counting semaphore). With \(k=1\) it degenerates to a binary mutex.
Field-by-field Comparison
Field Before After
Text A semaphore initialised to {{c1::1}} (<code>sem_mutex = Semaphore(1)</code>) acts as a lock: {{c2::<code>lock()</code> is <code>sem_mutex.acquire()</code>}} and {{c2::<code>unlock()</code> is <code>sem_mutex.release()</code>}}. In general the value means: \(1\) is {{c3::unlocked}}, \(0\) is {{c3::locked}}, \(x &gt; 0\) means {{c3::\(x\) threads will be let into the "critical section"}}.
Extra A semaphore with initial value \(k &gt; 1\) is therefore a generalised lock that admits up to \(k\) threads concurrently (a counting semaphore). With \(k=1\) it degenerates to a binary mutex.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores

Note 57: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: Tb@BJO%9v+
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
In the producer-consumer pattern, thread \(T_0\) computes a value \(X\) and passes it to \(T_1\) which uses \(X\). Synchronisation on \(X\) itself is not needed, because at any point in time only one thread accesses \(X\); what is needed is a synchronised mechanism to pass \(X\) from \(T_0\) to \(T_1\) (typically a queue).

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
In the producer-consumer pattern, thread \(T_0\) computes a value \(X\) and passes it to \(T_1\) which uses \(X\). Synchronisation on \(X\) itself is not needed, because at any point in time only one thread accesses \(X\); what is needed is a synchronised mechanism to pass \(X\) from \(T_0\) to \(T_1\) (typically a queue).

Producer-consumer is a fundamental parallel-programming pattern. Pipelines \(T_0 \to T_1 \to T_2\) generalise it: middle stages are both producer and consumer. Programmable hardware like Intel Stratix 10 (30 billion transistors) is built around exactly this dataflow style.
Field-by-field Comparison
Field Before After
Text In the producer-consumer pattern, thread \(T_0\) computes a value \(X\) and passes it to \(T_1\) which uses \(X\). Synchronisation on \(X\) itself is {{c1::not needed, because at any point in time only one thread accesses \(X\)}}; what is needed is {{c2::a synchronised mechanism to pass \(X\) from \(T_0\) to \(T_1\) (typically a queue)}}.
Extra Producer-consumer is a fundamental parallel-programming pattern. Pipelines \(T_0 \to T_1 \to T_2\) generalise it: middle stages are both producer and consumer. Programmable hardware like Intel Stratix 10 (30 billion transistors) is built around exactly this dataflow style.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer

Note 58: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: UvyKN*oVmU
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition
A Java Condition (obtained via lock.newCondition()) offers await(): must be called with the lock held; atomically releases the lock and waits until the thread is signalled; on return, the lock is guaranteed to be held again; the thread always needs to re-check the condition (use while, not if). Plus signal() / signalAll(): also called with the lock held, wakes one or all threads waiting on this specific condition.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition
A Java Condition (obtained via lock.newCondition()) offers await(): must be called with the lock held; atomically releases the lock and waits until the thread is signalled; on return, the lock is guaranteed to be held again; the thread always needs to re-check the condition (use while, not if). Plus signal() / signalAll(): also called with the lock held, wakes one or all threads waiting on this specific condition.

Crucial difference from wait/notify on intrinsic locks: a single lock can have multiple conditions, so producers and consumers can wait on different ones (notFull, notEmpty) and the right kind of waiter can be woken directly without notifying all.
Field-by-field Comparison
Field Before After
Text A Java <code>Condition</code> (obtained via <code>lock.newCondition()</code>) offers {{c1::<code>await()</code>}}: must be called with the lock held; {{c2::atomically releases the lock and waits until the thread is signalled}}; on return, the lock is {{c3::guaranteed to be held again}}; the thread {{c4::always needs to re-check the condition (use <code>while</code>, not <code>if</code>)}}. Plus <code>signal()</code> / <code>signalAll()</code>: also called with the lock held, wakes one or all threads waiting on this specific condition.
Extra Crucial difference from <code>wait/notify</code> on intrinsic locks: a single lock can have <em>multiple</em> conditions, so producers and consumers can wait on different ones (<code>notFull</code>, <code>notEmpty</code>) and the right kind of waiter can be woken directly without notifying all.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition

Note 59: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: ZTD^ST04cP
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
A bounded FIFO queue is implemented as a circular buffer with two indices: in (next free slot) and out (next element to remove), both advanced modulo size. The state of the buffer is determined by these two indices: isEmpty() returns in == out and isFull() returns (in + 1) % size == out.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
A bounded FIFO queue is implemented as a circular buffer with two indices: in (next free slot) and out (next element to remove), both advanced modulo size. The state of the buffer is determined by these two indices: isEmpty() returns in == out and isFull() returns (in + 1) % size == out.

The wrap-around semantics of (i + 1) % size is what makes it "circular": the buffer can be visualised as a ring with in chasing out.
Field-by-field Comparison
Field Before After
Text A bounded FIFO queue is implemented as a {{c1::circular buffer}} with two indices: <code>in</code> (next free slot) and <code>out</code> (next element to remove), both advanced modulo <code>size</code>. The state of the buffer is determined by these two indices: <code>isEmpty()</code> returns {{c2::<code>in == out</code>}} and <code>isFull()</code> returns {{c2::<code>(in + 1) % size == out</code>}}.
Extra The wrap-around semantics of <code>(i + 1) % size</code> is what makes it "circular": the buffer can be visualised as a ring with <code>in</code> chasing <code>out</code>.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer

Note 60: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: ^q02oC6MbX
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition
Producer-consumer with ReentrantLock + two conditions notFull and notEmpty:
void enqueue(long x) {
  lock.lock();
  while (isFull()) notFull.await();
  doEnqueue(x);
  notEmpty.signal();
  lock.unlock();
}
Why this is cleaner than synchronized + wait / notifyAll: with two conditions, the producer signals only consumers on notEmpty, not all waiters on the object's single intrinsic queue, so signal() instead of signalAll() suffices in this pattern (every waiter on notEmpty is a consumer, every waiter on notFull is a producer, no risk of waking the wrong kind of thread).

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition
Producer-consumer with ReentrantLock + two conditions notFull and notEmpty:
void enqueue(long x) {
  lock.lock();
  while (isFull()) notFull.await();
  doEnqueue(x);
  notEmpty.signal();
  lock.unlock();
}
Why this is cleaner than synchronized + wait / notifyAll: with two conditions, the producer signals only consumers on notEmpty, not all waiters on the object's single intrinsic queue, so signal() instead of signalAll() suffices in this pattern (every waiter on notEmpty is a consumer, every waiter on notFull is a producer, no risk of waking the wrong kind of thread).

With a single intrinsic monitor and one queue (mixing producers and consumers), notify() could wake a producer when the queue is full, which would just go back to wait: hence notifyAll is required there.
Field-by-field Comparison
Field Before After
Text Producer-consumer with <code>ReentrantLock</code> + two conditions <code>notFull</code> and <code>notEmpty</code>: <pre>void enqueue(long x) { lock.lock(); while (isFull()) notFull.await(); doEnqueue(x); notEmpty.signal(); lock.unlock(); }</pre>Why this is cleaner than <code>synchronized</code> + <code>wait</code> / <code>notifyAll</code>: {{c1::with two conditions, the producer signals only consumers on <code>notEmpty</code>, not all waiters on the object's single intrinsic queue}}, so {{c2::<code>signal()</code> instead of <code>signalAll()</code> suffices in this pattern (every waiter on <code>notEmpty</code> is a consumer, every waiter on <code>notFull</code> is a producer, no risk of waking the wrong kind of thread)}}.
Extra With a single intrinsic monitor and one queue (mixing producers and consumers), <code>notify()</code> could wake a producer when the queue is full, which would just go back to <code>wait</code>: hence <code>notifyAll</code> is required there.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::12._Lock_and_Condition

Note 61: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: _19oq0$uNl
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
Correct rendezvous implementation with P_Arrived = Q_Arrived = 0:
PQ
release(P_Arrived)
acquire(Q_Arrived)
release(Q_Arrived)
acquire(P_Arrived)
Rule: signal first ("I am here"), then wait ("are you here too?"). No deadlock is possible because the own release is already executed before waiting on the other one.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
Correct rendezvous implementation with P_Arrived = Q_Arrived = 0:
PQ
release(P_Arrived)
acquire(Q_Arrived)
release(Q_Arrived)
acquire(P_Arrived)
Rule: signal first ("I am here"), then wait ("are you here too?"). No deadlock is possible because the own release is already executed before waiting on the other one.

Whether P or Q arrives first does not matter: the earlier one waits, the later one triggers both releases before its acquire. Both pass the rendezvous as soon as the second thread arrives.
Field-by-field Comparison
Field Before After
Text Correct rendezvous implementation with <code>P_Arrived = Q_Arrived = 0</code>: <table border="1" cellpadding="4"><tr><th>P</th><th>Q</th></tr><tr><td>{{c1::<code>release(P_Arrived)</code><br><code>acquire(Q_Arrived)</code>}}</td><td>{{c1::<code>release(Q_Arrived)</code><br><code>acquire(P_Arrived)</code>}}</td></tr></table>Rule: {{c2::signal first ("I am here"), then wait ("are you here too?")}}. No deadlock is possible because the own <code>release</code> is already executed before waiting on the other one.
Extra Whether P or Q arrives first does not matter: the earlier one waits, the later one triggers both releases before its acquire. Both pass the rendezvous as soon as the second thread arrives.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores

Note 62: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: dGibG|?+t-
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors
A monitor adds, on top of mutual exclusion, the following condition mechanism: if a condition does not hold, release the monitor lock, wait for the condition to become true, and use a signalling mechanism (rather than a busy-loop) to be woken when it does. Internally, a monitor maintains two queues: a waiting entry queue (threads trying to acquire the monitor) and a waiting condition queue (threads inside the monitor that have called wait).

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors
A monitor adds, on top of mutual exclusion, the following condition mechanism: if a condition does not hold, release the monitor lock, wait for the condition to become true, and use a signalling mechanism (rather than a busy-loop) to be woken when it does. Internally, a monitor maintains two queues: a waiting entry queue (threads trying to acquire the monitor) and a waiting condition queue (threads inside the monitor that have called wait).

The two queues are conceptually distinct: a thread that is signalled is moved from the condition queue back to the entry queue (under signal-and-continue), it does not get the lock immediately.
Field-by-field Comparison
Field Before After
Text A monitor adds, on top of mutual exclusion, the following condition mechanism: if a condition does not hold, {{c1::release the monitor lock}}, {{c2::wait for the condition to become true}}, and use {{c3::a signalling mechanism (rather than a busy-loop) to be woken when it does}}. Internally, a monitor maintains two queues: {{c4::a <em>waiting entry</em> queue (threads trying to acquire the monitor)}} and {{c4::a <em>waiting condition</em> queue (threads inside the monitor that have called wait)}}.
Extra The two queues are conceptually distinct: a thread that is signalled is moved from the condition queue back to the entry queue (under signal-and-continue), it does not get the lock immediately.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors

Note 63: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: fuGa|7fW/T
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors
A monitor-based semaphore with
synchronized acquire() { if (number <= 0) wait(); number--; }
synchronized release() { number++; if (number > 0) notify(); }
is broken under signal-and-continue semantics (which is what Java uses). Concrete scenario with threads P, Q, R: (1) P entered earlier and decremented number to 0; (2) Q sees 0 and goes to the condition queue; (3) P calls release(): increments number to 1, calls notify() which moves Q to the entry queue, then P exits the monitor; (4) R now calls acquire(), finds number = 1 > 0, decrements to 0 and proceeds; (5) Q, when it finally acquires the lock, decrements number to \(-1\), an inconsistency. The cure: replace if with while (re-check the condition after waking).

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors
A monitor-based semaphore with
synchronized acquire() { if (number <= 0) wait(); number--; }
synchronized release() { number++; if (number > 0) notify(); }
is broken under signal-and-continue semantics (which is what Java uses). Concrete scenario with threads P, Q, R: (1) P entered earlier and decremented number to 0; (2) Q sees 0 and goes to the condition queue; (3) P calls release(): increments number to 1, calls notify() which moves Q to the entry queue, then P exits the monitor; (4) R now calls acquire(), finds number = 1 > 0, decrements to 0 and proceeds; (5) Q, when it finally acquires the lock, decrements number to \(-1\), an inconsistency. The cure: replace if with while (re-check the condition after waking).

Under signal-and-wait the lock would have been handed straight to Q, blocking R, and if would have sufficed. Java's signal-and-continue is what forces the while idiom, together with the possibility of spurious wakeups.
Field-by-field Comparison
Field Before After
Text A monitor-based semaphore with <pre>synchronized acquire() { if (number &lt;= 0) wait(); number--; } synchronized release() { number++; if (number &gt; 0) notify(); }</pre>is {{c1::broken under signal-and-continue semantics (which is what Java uses)}}. Concrete scenario with threads P, Q, R: {{c2::(1) P entered earlier and decremented <code>number</code> to 0; (2) Q sees 0 and goes to the condition queue; (3) P calls <code>release()</code>: increments <code>number</code> to 1, calls <code>notify()</code> which moves Q to the entry queue, then P exits the monitor; (4) R now calls <code>acquire()</code>, finds <code>number = 1 &gt; 0</code>, decrements to 0 and proceeds; (5) Q, when it finally acquires the lock, decrements <code>number</code> to \(-1\), an inconsistency}}. The cure: {{c3::replace <code>if</code> with <code>while</code> (re-check the condition after waking)}}.
Extra Under signal-and-wait the lock would have been handed straight to Q, blocking R, and <code>if</code> would have sufficed. Java's signal-and-continue is what forces the <code>while</code> idiom, together with the possibility of spurious wakeups.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors

Note 64: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: g-H0<*^eyz
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
Locks alone are insufficient because they only enforce atomicity via mutual exclusion, but provide no means for threads to communicate about state changes, and they provide no order: if threads A and B both lock object X, it is undetermined who comes first. Canonical example where this hurts: producer / consumer queues.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
Locks alone are insufficient because they only enforce atomicity via mutual exclusion, but provide no means for threads to communicate about state changes, and they provide no order: if threads A and B both lock object X, it is undetermined who comes first. Canonical example where this hurts: producer / consumer queues.

Semaphores and higher-level primitives fill exactly this gap: they let one thread signal another that something has happened, and thus impose a partial order on executions.
Field-by-field Comparison
Field Before After
Text Locks alone are insufficient because {{c1::they only enforce atomicity via mutual exclusion, but provide no means for threads to communicate about state changes}}, and {{c2::they provide no order: if threads A and B both lock object X, it is undetermined who comes first}}. Canonical example where this hurts: {{c3::producer / consumer queues}}.
Extra Semaphores and higher-level primitives fill exactly this gap: they let one thread signal another that something has happened, and thus impose a partial order on executions.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores

Note 65: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: h#Z>rJrnYr
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
In a circular-buffer FIFO, one slot is left unusable on purpose so that isFull() is (in + 1) % size == out rather than using a separate counter variable. The benefit of avoiding a counter: in is only written by the producer and out only by the consumer, so for the single-producer single-consumer case the two indices need no mutual exclusion against each other.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
In a circular-buffer FIFO, one slot is left unusable on purpose so that isFull() is (in + 1) % size == out rather than using a separate counter variable. The benefit of avoiding a counter: in is only written by the producer and out only by the consumer, so for the single-producer single-consumer case the two indices need no mutual exclusion against each other.

A counter count would be incremented by the producer and decremented by the consumer, a write-write conflict that forces synchronisation even on the fast path. Sacrificing one slot of capacity buys a much cleaner concurrency story.
Field-by-field Comparison
Field Before After
Text In a circular-buffer FIFO, one slot is left unusable on purpose so that <code>isFull()</code> is <code>(in + 1) % size == out</code> rather than using a separate counter variable. The benefit of avoiding a counter: {{c1::<code>in</code> is only written by the producer and <code>out</code> only by the consumer, so for the single-producer single-consumer case the two indices need no mutual exclusion against each other}}.
Extra A counter <code>count</code> would be incremented by the producer and decremented by the consumer, a write-write conflict that forces synchronisation even on the fast path. Sacrificing one slot of capacity buys a much cleaner concurrency story.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer

Note 66: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: iM|cWW?YzD
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
Scaling a dot product to 1 million entries on 10 000 threads is impractical with semaphores or locks. It calls for a higher-level abstraction supporting threads in bulk mode (all moving in lock-step). The corresponding programming model is Bulk-Synchronous Parallel (BSP).

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
Scaling a dot product to 1 million entries on 10 000 threads is impractical with semaphores or locks. It calls for a higher-level abstraction supporting threads in bulk mode (all moving in lock-step). The corresponding programming model is Bulk-Synchronous Parallel (BSP).

The full BSP model (Valiant, 1990) is more general and supports distributed memory: computation proceeds in supersteps consisting of local computation, communication, and a global barrier. In shared-memory code the barrier is the central building block.
Field-by-field Comparison
Field Before After
Text Scaling a dot product to 1 million entries on 10 000 threads is impractical with semaphores or locks. It calls for a higher-level abstraction supporting {{c1::threads in bulk mode}} (all moving in lock-step). The corresponding programming model is {{c2::Bulk-Synchronous Parallel (BSP)}}.
Extra The full BSP model (Valiant, 1990) is more general and supports distributed memory: computation proceeds in supersteps consisting of local computation, communication, and a global barrier. In shared-memory code the barrier is the central building block.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers

Note 67: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: kU$/VTuynM
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::7._Deadlock_Avoidance
The historic Java StringBuffer.append(StringBuffer sb) (synchronized append(...){ int len = sb.length(); ... sb.getChars(0, len, value, count); }) has two problems: the lock on sb is not held between sb.length() and sb.getChars(...), so sb can grow or shrink in between (a shrinking sb definitely breaks append) and deadlock potential on crossing calls x.append(y) and y.append(x) on two threads, analogous to the bank-account transfer example.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::7._Deadlock_Avoidance
The historic Java StringBuffer.append(StringBuffer sb) (synchronized append(...){ int len = sb.length(); ... sb.getChars(0, len, value, count); }) has two problems: the lock on sb is not held between sb.length() and sb.getChars(...), so sb can grow or shrink in between (a shrinking sb definitely breaks append) and deadlock potential on crossing calls x.append(y) and y.append(x) on two threads, analogous to the bank-account transfer example.

Neither problem is easy to fix without overhead: you do not want a unique id on every StringBuffer, nor a single global lock for all of them. The Java library initially fixed neither (only changed the javadoc) and later split the API into StringBuffer (claimed synchronized) and StringBuilder (not synchronized), leaving clients to avoid such situations with their own protocols.
Field-by-field Comparison
Field Before After
Text The historic Java <code>StringBuffer.append(StringBuffer sb)</code> (<code>synchronized append(...){ int len = sb.length(); ... sb.getChars(0, len, value, count); }</code>) has two problems: {{c1::the lock on <code>sb</code> is not held between <code>sb.length()</code> and <code>sb.getChars(...)</code>, so <code>sb</code> can grow or shrink in between (a shrinking <code>sb</code> definitely breaks <code>append</code>)}} and {{c2::deadlock potential on crossing calls <code>x.append(y)</code> and <code>y.append(x)</code> on two threads, analogous to the bank-account transfer example}}.
Extra Neither problem is easy to fix without overhead: you do not want a unique id on every <code>StringBuffer</code>, nor a single global lock for all of them. The Java library initially fixed neither (only changed the javadoc) and later split the API into <code>StringBuffer</code> (claimed synchronized) and <code>StringBuilder</code> (not synchronized), leaving clients to avoid such situations with their own protocols.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::7._Deadlock_Avoidance

Note 68: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: ntkbNkNy_m
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors
Two main monitor signalling semantics: signal and wait: the signalling process exits the monitor (goes to the waiting-entry queue) and passes the monitor lock directly to the signalled process. signal and continue: the signalling process continues running and merely moves the signalled process to the waiting-entry queue, where it must reacquire the lock like anyone else.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors
Two main monitor signalling semantics: signal and wait: the signalling process exits the monitor (goes to the waiting-entry queue) and passes the monitor lock directly to the signalled process. signal and continue: the signalling process continues running and merely moves the signalled process to the waiting-entry queue, where it must reacquire the lock like anyone else.

Other variants exist (signal-and-exit, signal-and-urgent-wait, ...). Java uses signal-and-continue, which has important consequences for how condition checks must be coded (always while, never if).
Field-by-field Comparison
Field Before After
Text Two main monitor signalling semantics: {{c1::<em>signal and wait</em>}}: {{c2::the signalling process exits the monitor (goes to the waiting-entry queue) and passes the monitor lock directly to the signalled process}}. {{c3::<em>signal and continue</em>}}: {{c4::the signalling process continues running and merely moves the signalled process to the waiting-entry queue, where it must reacquire the lock like anyone else}}.
Extra Other variants exist (signal-and-exit, signal-and-urgent-wait, ...). Java uses <em>signal-and-continue</em>, which has important consequences for how condition checks must be coded (always <code>while</code>, never <code>if</code>).
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::11._Monitors

Note 69: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: sCYbBLISvG
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
A semaphore is an integer-valued abstract data type S with some initial value \(s \geq 0\) and two atomic operations: acquire(S): wait until S > 0, then dec(S) and release(S): inc(S).

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
A semaphore is an integer-valued abstract data type S with some initial value \(s \geq 0\) and two atomic operations: acquire(S): wait until S > 0, then dec(S) and release(S): inc(S).

Introduced by Edsger W. Dijkstra (1965); originally called P (probeeren) and V (vrijgeven), often also wait and signal. Unlike a lock, a semaphore has no owner: the thread that calls release need not be the one that called acquire.
Field-by-field Comparison
Field Before After
Text A {{c1::semaphore}} is an integer-valued abstract data type <code>S</code> with some initial value \(s \geq 0\) and two atomic operations: {{c2::<code>acquire(S)</code>: wait until <code>S &gt; 0</code>, then <code>dec(S)</code>}} and {{c2::<code>release(S)</code>: <code>inc(S)</code>}}.
Extra Introduced by Edsger W. Dijkstra (1965); originally called <code>P</code> (probeeren) and <code>V</code> (vrijgeven), often also <em>wait</em> and <em>signal</em>. Unlike a lock, a semaphore has no owner: the thread that calls <code>release</code> need not be the one that called <code>acquire</code>.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores

Note 70: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: x$osz_e?7R
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
Wrong rendezvous implementation with P_Arrived = Q_Arrived = 0:
PQ
acquire(Q_Arrived)
release(P_Arrived)
acquire(P_Arrived)
release(Q_Arrived)
Problem: deadlock, because both threads acquire before anyone has released: P needs Q_Arrived (held by Q), Q needs P_Arrived (held by P): a circular wait.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores
Wrong rendezvous implementation with P_Arrived = Q_Arrived = 0:
PQ
acquire(Q_Arrived)
release(P_Arrived)
acquire(P_Arrived)
release(Q_Arrived)
Problem: deadlock, because both threads acquire before anyone has released: P needs Q_Arrived (held by Q), Q needs P_Arrived (held by P): a circular wait.

Lesson: in a rendezvous, always signal first, then wait. Otherwise a classic hold-and-wait cycle forms because neither thread ever reaches its release.
Field-by-field Comparison
Field Before After
Text Wrong rendezvous implementation with <code>P_Arrived = Q_Arrived = 0</code>: <table border="1" cellpadding="4"><tr><th>P</th><th>Q</th></tr><tr><td><code>acquire(Q_Arrived)</code><br><code>release(P_Arrived)</code></td><td><code>acquire(P_Arrived)</code><br><code>release(Q_Arrived)</code></td></tr></table>Problem: {{c1::deadlock}}, because {{c2::both threads acquire before anyone has released: <code>P</code> needs <code>Q_Arrived</code> (held by Q), <code>Q</code> needs <code>P_Arrived</code> (held by P): a circular wait}}.
Extra Lesson: in a rendezvous, always <em>signal first, then wait</em>. Otherwise a classic hold-and-wait cycle forms because neither thread ever reaches its <code>release</code>.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::8._Semaphores

Note 71: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: xHZU%tugzy
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
Producer-consumer with three semaphores nonEmpty = Semaphore(0), nonFull = Semaphore(size), manipulation = Semaphore(1): the order manipulation.acquire(); nonFull.acquire(); in enqueue (and analogously manipulation before nonEmpty in dequeue) deadlocks: a producer holding manipulation on a full queue waits on nonFull, while the consumer needs manipulation to remove an item: a circular wait between manipulation and nonFull / nonEmpty. Fix: acquire the resource semaphore before the manipulation mutex (nonFull.acquire(); manipulation.acquire();), so the resource wait happens outside the critical section.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer
Producer-consumer with three semaphores nonEmpty = Semaphore(0), nonFull = Semaphore(size), manipulation = Semaphore(1): the order manipulation.acquire(); nonFull.acquire(); in enqueue (and analogously manipulation before nonEmpty in dequeue) deadlocks: a producer holding manipulation on a full queue waits on nonFull, while the consumer needs manipulation to remove an item: a circular wait between manipulation and nonFull / nonEmpty. Fix: acquire the resource semaphore before the manipulation mutex (nonFull.acquire(); manipulation.acquire();), so the resource wait happens outside the critical section.

General rule when nesting semaphores: acquire the one you might block on first, the one you merely need for exclusion second. This breaks the hold-and-wait cycle.
Field-by-field Comparison
Field Before After
Text Producer-consumer with three semaphores <code>nonEmpty = Semaphore(0)</code>, <code>nonFull = Semaphore(size)</code>, <code>manipulation = Semaphore(1)</code>: the order <code>manipulation.acquire(); nonFull.acquire();</code> in <code>enqueue</code> (and analogously <code>manipulation</code> before <code>nonEmpty</code> in <code>dequeue</code>) {{c1::deadlocks}}: a producer holding <code>manipulation</code> on a full queue waits on <code>nonFull</code>, while the consumer needs <code>manipulation</code> to remove an item: {{c2::a circular wait between <code>manipulation</code> and <code>nonFull</code> / <code>nonEmpty</code>}}. Fix: {{c3::acquire the resource semaphore <em>before</em> the <code>manipulation</code> mutex (<code>nonFull.acquire(); manipulation.acquire();</code>)}}, so the resource wait happens outside the critical section.
Extra General rule when nesting semaphores: acquire the one you might block on first, the one you merely need for exclusion second. This breaks the hold-and-wait cycle.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::10._Producer-Consumer

Note 72: ETH::2. Semester::PProg

Deck: ETH::2. Semester::PProg
Note Type: Horvath Cloze
GUID: y4X/i|x>Tz
added

Previous

Note did not exist

New Note

Front

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
Wrong barrier implementation with semaphore barrier = 0 and shared variable count = 0: each thread does count++; if (count == n) release(barrier); acquire(barrier);. Problems: race condition on count++ (no mutex) and deadlock, because release is called only once but \(n\) threads acquire: after the first acquire the semaphore is back to 0, so all others wait forever.

Back

ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
Wrong barrier implementation with semaphore barrier = 0 and shared variable count = 0: each thread does count++; if (count == n) release(barrier); acquire(barrier);. Problems: race condition on count++ (no mutex) and deadlock, because release is called only once but \(n\) threads acquire: after the first acquire the semaphore is back to 0, so all others wait forever.

Violated invariants: "count gives the number of processes that have passed the barrier" and "once all processes have reached the barrier, all waiting processes can continue". Both must be fixed separately: the race with a mutex, the deadlock with a turnstile.
Field-by-field Comparison
Field Before After
Text Wrong barrier implementation with semaphore <code>barrier = 0</code> and shared variable <code>count = 0</code>: each thread does <code>count++; if (count == n) release(barrier); acquire(barrier);</code>. Problems: {{c1::race condition on <code>count++</code> (no mutex)}} and {{c2::deadlock, because <code>release</code> is called only once but \(n\) threads <code>acquire</code>: after the first <code>acquire</code> the semaphore is back to 0, so all others wait forever}}.
Extra Violated invariants: "count gives the number of processes that have passed the barrier" and "once all processes have reached the barrier, all waiting processes can continue". Both must be fixed separately: the race with a mutex, the deadlock with a turnstile.
Tags: ETH::2._Semester::PProg::12._Shared_Memory_Concurrency::9._Barriers
↑ Top