• R/O
  • SSH

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Commit MetaInfo

Revisionb9f60973c68c46d2c08fbfc14b2219ee6374aebc (tree)
Zeit2023-04-02 00:31:07
AutorAlbert Mietus < albert AT mietus DOT nl >
CommiterAlbert Mietus < albert AT mietus DOT nl >

Log Message

asis fixed syntax and wording

Ändern Zusammenfassung

Diff

diff -r 70e2cb45f2fd -r b9f60973c68c CCastle/4.Blog/a.Heisenbug.rst
--- a/CCastle/4.Blog/a.Heisenbug.rst Sat Apr 01 16:50:23 2023 +0200
+++ b/CCastle/4.Blog/a.Heisenbug.rst Sat Apr 01 17:31:07 2023 +0200
@@ -14,17 +14,16 @@
1414 an action on an incoming message (see: :ref:`CCC-Actors`). Depending on ‘:ref:`TheMachinery`’, those events can be
1515 queued and this combination *can result* in a **beautiful Heisenbug**.
1616
17- First, let’s explain the Heisenbug, before we give a example. Then we analyse it, show how it can be solved and
18- finally formulate a *requirement* how we can prevent this kind of bugs in Castle.
19-
17+ First, let’s explain the Heisenbug, before we give an example. Then we analyze it, show how to improve the code, and
18+ finally formulate a *requirement* to prevent & detect this kind of bug in Castle.
2019
2120 What is a Heisenbug?
2221 ====================
2322
2423 The `heisenbug <https://en.wikipedia.org/wiki/Heisenbug>`__ is named to Werner Heisenberg, who described the *“observer
2524 effect”*: when you look closely, the behavior changes. The same can happen to software (bugs). The behavior apparently
26-changes when you study -or slightly adjust- that code. Often this is due (small) changes in timing; possibly even in
27-generated code. Therefore old (oldfashioned), sequential code on slow CPU’s is less likely to have heisenbugs then
25+changes when you study -or slightly adjust- that code. Often this is due to (small) changes in timing; possibly even in
26+generated code. Therefore old (old-fashioned), sequential code on slow CPUs is less likely to have heisenbugs than
2827 concurrent code on fast multi-core systems. It’s also common in threaded programs.
2928
3029 .. include:: ./Heisenbug-sidebar-Sequence.irst
@@ -32,66 +31,66 @@
3231 The sieve goes wrong
3332 ====================
3433
35-Also my standard example ‘:ref:`Castle-TheSieve`’ can suffer from this issue. The initial version did work for years,
36-but failed horrible when another “machinery” was used. After studying this, the bug is simple, and easy to fix.
34+My standard example, ‘:ref:`Castle-TheSieve`’, suffered from this issue. The initial version did work for years,
35+but failed horribly when another “machinery” was used. After studying this, the bug is simple and easy to fix.
3736
3837 There are two related timing issues, that (probably only together) result in the Heisenbug. First, we introduce them one
39-by one, and then show how the combination may fail.
38+by one and then show how the combination may fail.
4039
4140
4241 Event-order
4342 -----------
4443
45-Conceptually, the `Generator` sends (events with) integers to `Sieve(2)`, which may be forward to `Sieve(3)`, then to
44+Conceptually, the `Generator` sends (events with) integers to `Sieve(2)`, which may be forwarded to `Sieve(3)`, then to
4645 `Sieve(5)`, etc. As shown in the **Conceptual sidebar**, we probably like to assume that each integer is fully sieved
47-before the next int *starts*. This is the classic “sequential view”, we are used too.
46+before the next *’int’* *starts*. This is the classic “sequential view”, we are used to.
4847
49-However, that isn’t how it works. In Castle the order of events on a connection is defined (*one by one,
50-sequential*). And given the code, the integer sent by an Sieve comes always later then the incoming one. But that is all
51-we may assume.
48+However, that isn’t how it works. In Castle, the order of events on a connection is defined (*one by one,
49+sequential*). And given the code, the integer sent by a `Sieve` comes always later than the incoming one. That is all we
50+may assume.
5251 |BR|
53-The timing of unrelated events on multiple connections is not defined. That order may depends on :ref:`TheMachinery` and
54-many other factors. Do not, as developer, assume any order -- like I did!
52+The timing of unrelated events on multiple connections is not defined. That order may depend on :ref:`TheMachinery` and
53+many other factors. Do not as a developer, assume any order --as I did!
5554
56-As shown in the **One-by-One sidebar** diagram, this can result that the Generator output all events first. Next, Sieve(2)
57-takes-out the even integers, then the Sieve(3) process all its input, then Sieve(5), ect.
55+As shown in the **One-by-One sidebar** diagram, this can result that the Generator is outputting all events first. Next,
56+Sieve(2) filters out the even integers, then Sieve(3) processes all its input, then Sieve(5), etc.
5857 |BR|
59-Although we aren’t using concurrency, and it needs hug buffers -- especially when finding big primes-- it does
58+Although we aren’t using concurrency, and it needs huge buffers -- especially when finding big primes-- it does
6059 conceptually work. And so, it is an allowed execution [#ButImprove]_.
6160
6261
6362 Reconnecting
6463 ------------
6564
66-The chain of `Sieve`\s will grow as we find more primes. When an *int* isn’t filtered-out and so reaches the `Finder` a
67-*new prime* is found. Then, a new Sieve-component is created and inserted to the chain.
65+The chain of `Sieve`\s will grow as we find more primes. When an *int* isn’t filtered-out and so reaches the `Finder` a
66+*new prime* is found. Then, a new Sieve component is created and inserted into the chain.
6867 |BR|
69-This is done by the Main-component (which is signaled by the Finder) [#orVariant]_.
68+This is done by the Main component (which is signaled by the Finder) [#orVariant]_.
7069
71-Therefore, `Main` remembers the ``last_sieve`` and reconnects it’s output to the newly creates `Sieve`. And temporally
72-connects that new-Sieve’s output to the Finder. For every newly found prime this repeats.
70+Therefore, `Main` remembers the ``last_sieve`` and reconnects its output to the newly creates `Sieve`. And temporally
71+connects that new-Sieve’s output to the Finder. For every newly found prime, this repeats.
7372 |BR|
74-This detail is shown in the **With Details** sidebar diagram; where the `Finder` and `Main` component, and all message’s
73+This detail is shown in the **With Details** sidebar diagram; where the `Finder` and `Main` component and all messages
7574 to/from them are shown.
7675
7776 Assuming the initial “conceptual” order, you will see the same Sieve(s) become alive (“new” message), and are added to
78-the end of the sieve-chain. The integers still flow (now, shown as “try(`int`)” messages) by this sieve.
77+the end of the sieve chain. The integers still flow (now, shown as “try(`int`)” messages) by this sieve.
7978 |BR|
80-You will aslo notice the `Finder` does indeed find all primes.
79+You will also notice the `Finder` does indeed find all primes.
8180
8281
8382 The combination
8483 ===============
8584
86-Now lets study how the sieve-chain will grow with a “fast generator”, and the one-by-one order of events is used. This
85+Now let us study how the sieve chain will grow with a “fast generator”, and the one-by-one order of events is used. This
8786 diagram is shown below.
8887
89-As we can see in the picture, it goes horrible wrong. No proper sieve is created, and we will find intergers as *4* and
90-*6* as prime -- clearly this is wrong.
88+As we can see in the picture, it goes dreadfully wrong. No proper chain is created, and we will find integers like **4**
89+and **6**. This is wrong, they are not prime.
9190 |BR|
92-With a (very) *fast Generator*, **all** intergers are send to the `Finder` --before any `Sieve` is created, and so any
93-int is reported as prime. And, as for each found “prime” a Sieve-component is created, to many elements are added to the
94-chain. On top of that, no integer is ever sieved....
91+With a (very) *fast Generator*, **all** integers are sent to the `Finder` --before any `Sieve` is created, and so any
92+int is reported as prime. And, too many elements are added to the chain, as a Sieve component is created for each found
93+“prime”. On top of that, no integer is ever sieved...
9594
9695 This is just **an** example. As we can’t predict (or assume) any order, we can find other results too. And, when we add
9796 “debugging print statement” (and *look closer*), we change the timing and will find other results. We found the
@@ -104,10 +103,11 @@
104103
105104 It is not *“the timing”* that is wrong!
106105 |BR|
107- A concurent programm is only correct when it goes right for **any** possible timing.
106+ A concurrent program is only correct when it goes right for **any** possible timing.
108107
109- As in all SW-engineering, we can prove it is buggy when it goes wrong at least once. That is what we have shown. And
110- so, the original code is *wrong*.
108+ As in all software engineering, we can prove it is buggy when it goes wrong at least once. That is what we have
109+ shown. And so, the original code is *wrong*.
110+
111111
112112 How to improve?
113113 ===============
diff -r 70e2cb45f2fd -r b9f60973c68c CCastle/4.Blog/sieve-Sequence-Wrong.puml
--- a/CCastle/4.Blog/sieve-Sequence-Wrong.puml Sat Apr 01 16:50:23 2023 +0200
+++ b/CCastle/4.Blog/sieve-Sequence-Wrong.puml Sat Apr 01 17:31:07 2023 +0200
@@ -1,6 +1,6 @@
11 @startuml
22 'hide footbox
3-title Wrong (Generate faster & slow Creation)
3+title Wrong (Generate fast & Slow creation)
44
55 participant Main as M
66 participant Finder as F
@@ -51,26 +51,26 @@
5151
5252 M -[#red]\ S4: new
5353 activate S4
54-note right: Another flaw: We shouldn't a **Sieve(4)**
54+note right: Another flaw: We shouldn't have **Sieve(4)**
5555 S3 \\--o M: "reconneced to Sieve(4)"
5656
5757
5858 M -[#purple]\ S5: new
5959 activate S5
6060 hnote right: Sieve(5) never gets input; or at least to little
61-S4 \\--o M: "reconneced to Sieve(4)"
61+S4 \\--o M: "reconneced to Sieve(5)"
6262
6363
6464 M -[#red]\ S6: new
6565 activate S6
66-note right: Another flaw: We shouldn't a **Sieve(6)**
66+note right: Another flaw: We shouldn't have **Sieve(6)**
6767 S5 \\--o M: "reconneced to Sieve(6)"
6868
6969
7070 M -[#red]\ S7: new
7171 activate S7
7272 S6 \\--o M: "reconneced to Sieve(6)"
73-
73+hnote right: Again: too late
7474
7575 == etc ==
7676