[archimedes] Re: Fragen zum C-Programm Uhrzeit

  • From: Alexander Ausserstorfer <bavariasound@xxxxxxxxxxxxxxx>
  • To: archimedes@xxxxxxxxxxxxx
  • Date: Fri, 06 Jan 2017 07:52:48 +0200

In message <2948c8f955.Alex@xxxxxxxxxxxxxxxxxxxxxxxxxxxx>
          Alexander Ausserstorfer <bavariasound@xxxxxxxxxxxxxxx> wrote:

[flackernde Uhrzeit]

Du kannst das flackern ein gutes Stück reduzieren, wenn Du
     while (newtime - oldtime >= 0)
statt
     while (newtime - oldtime > 0)
verwendest.

Sonst wird das Icon unnötigerweise mindestens zweimal in der Sekunde
gezeichnet.

Ich hab's versucht zu verstehen. Also nachzuvollziehen. Aber an irgend
etwas scheitert es.

Ich verstehe das so: Die eingebaute Laufzeituhr zählt in Stufen von
1/100 Sekunden, d. h. in Abschnitten (Zeitintervallen) von 10
Mikrosekunden weiter.
  ^^^^^^^^^^^^^

Ich meinte hier doch wohl hoffentlich Millisekunden?

Nehmen wir z. B. an, new steht bei 100, old bei 0. Das ist der Abstand
von 1 Sekunde.

Dann wird bei while (new - old >= 0) die Berechnung old = old + 100
_zweimal_ durchgeführt (bei (new - old > 0) hingegen nur einmal), so
dass old dann um den Wert 200 erhöht wird, bevor die Schleife verlassen
wird. Für mich heißt das jetzt aber, dass die nächste Aktualisierung des
Symbols dann erst nach 2 Sekunden erfolgt. Das ist aber offensichtlich
nicht der Fall. Denn dann müsste ja bei der Anzeige jeweils 1 Sekunde
übersprungen werden.

Bei wimp_poll_idle() gibtst Du an, wann sich der wimp wieder melden
soll, also ein Zeitpunkt in der Zukunft.
Ist Jetzt 100, dann ist eine Sekunde weiter in der Zukunft 200.
Genau das, was bei >= 0 rauskommt.

Beim Test > 0 wird zum Zeitpunkt 100 oldtime auch auf 100 gesetzt,
wimp_poll_idle() mit 100 aufgerufen.
Der Wimp kommt ziemlich schnell wieder zum Zeitpunkt 101 zurück (da
ist 100 vorbei).
Es hat sich nichts für die Uhrenanzeige geändert, aber erst jetzt wird
oldtime auf 200 hochgesetzt.

So ganz verstehe ich deine Antwort hier leider nicht. Aber es deckt sich
anscheinend mit dem, was ich eben kapiert habe (oder kapiert zu haben
glaube). Bitte korrigier(t) mich, wenn ich falsch bin!

Also. Ich möchte es nochmals in eigenen Worten erklären:

Ich habe die Laufzeituhr jetzt 'mal mit Hilfe von zwei Symbolen (Icons)
sichtbar gemacht, um oldtime und newtime ausgeben zu können. Dabei
stellte ich folgendes fest:

Beim erstmaligen Start des Programmes sind oldtime und newtime
blöderweise gleich. Das heißt dann wohl, dass die Bedingung

(newtime - oldtime ) > 0

nicht erfüllt ist und deshalb wenigstens beim ersten Mal oldtime nicht
um 100 höhergesetzt wird. Das Programm wird damit innerhalb der nächsten
10 Millisekunden bzw. sobald wie möglich wieder angesprungen. Das
geschieht so lange, bis sich die Laufzeituhr um wenigstens 10
Millisekunden erhöht hat. Danach erst ist nämlich die Bedingung

(newtime - oldtime ) > 0

erfüllt.

Oldtime wird also dann erst beim nächsten Durchlauf um 100 hochgesetzt,
weil erst ab hier die Bedingung newtime - oldtime > 0 erfüllt ist.
newtime wurde aber vom System auf jeden Fall zwischenzeitlich um
wenistens 1 erhöht. Damit hinkt newtime oldtime (_nach_ der Erhöhung
oldtime = oldtime + 100) durch die erfolgten sofortigen ersten Ansprünge
des Programms aber nur noch maximal 990 Millisekunden hinterher.

Wir haben durch die unverzüglichen erfolgten ersten Durchläufe
wenigstens 10 Millisekunden (oder mehr!) Abstand zwischen
newtime und oldtime verloren! Ab jetzt schreitet oldtime dann aber nur
noch maximal um 990 Millisekunden der Laufzeituhr bzw. newtime voraus.
Das heißt, das Programm wird dann schon rein theoretisch mindestens alle
990 Millisekunden angesprungen (oder schneller). Das wären dann die von
dir erwähnten 2 Neuzeichnungen pro Sekunde.

Wenn man jetzt aber die Bedingung

(newtime - oldtime) >= 0

stellt, so ist diese Bedingung bereits schon beim ersten Durchlauf
erfüllt. Damit wird gleich beim ersten Durchlauf oldtime um 100 erhöht.
Damit ist der nächste Ansprungpunkt rein theoretisch erst in einer
Sekunde (100).

Das Problem ist also der erste Durchlauf bzw. die Tatsache, dass oldtime
und newtime zu Anfang identisch sind und damit die Bedingung (newtime -
oldtime) > 0 bei den ersten Durchläufen nicht erfüllt ist.

Das mit dem ersten Durchlauf stimmt. Der Rest jedoch nicht so ganz. Ich
habe mir jetzt die Mühe gemacht, die ganzen Werte in eine Datei
schreiben zu lassen.

Das Programm findet der geneigte Leser hier:

http://home.chiemgau-net.de/ausserstorfer/Computer/Peanuts/Uhrzeit_experimential.zip
(10 kB)

Enthalten ist allerdings nur die ELF samt Quellcode. Zum Starten, Ändern
und Übersetzen braucht ihr damit halt ein Entwicklungssystem (GCC).

Bei der Variante mit [ (newtime - oldtime) >= 0 ] kommt dabei heraus:

newtime: Wert von newtime
oldtime: Wert von oldtime _nach_ der Erhöhung (falls diese stattgefunden
hat)
Ansprünge: so oft wurde das Programm bisher von der WIMP angesprungen
bzw. aufgerufen.

newtime, oldtime, Ansprünge
 417032,  417115, 0
 417115,  417215, 1
 417215,  417315, 2
 417315,  417415, 3
 417415,  417515, 4
 417515,  417615, 5

Also eigentlich so, wie es sein soll.

Bei der Variante mit  [ (newtime - oldtime) > 0 ] jedoch:

newtime, oldtime, Ansprünge
 533947,  534042, 0
 534042,  534042, 1
 534042,  534042, 2
 534042,  534042, 3
 534042,  534042, 4
 534043,  534142, 5
 534142,  534142, 6
 534142,  534142, 7
 534142,  534142, 8
 534142,  534142, 9
 534142,  534142, 10
 534143,  534242, 11
 534257,  534342, 12
 534342,  534342, 13
 534342,  534342, 14
 534342,  534342, 15
 534342,  534342, 16
 534343,  534442, 17
 534442,  534442, 18
 534442,  534442, 19
 534442,  534442, 20
 534442,  534442, 21
 534443,  534542, 22
 534544,  534642, 23
 534642,  534642, 24
 534642,  534642, 25
 534642,  534642, 26
 534648,  534742, 27
 534742,  534742, 28
 534742,  534742, 29
 534742,  534742, 30
 534742,  534742, 31
 534743,  534842, 32
 534842,  534842, 33
 534842,  534842, 34
 534842,  534842, 35
 534842,  534842, 36
 534843,  534942, 37
 534942,  534942, 38
 534942,  534942, 39
 534942,  534942, 40
 534942,  534942, 41
 534943,  535042, 42
 535042,  535042, 43
 535042,  535042, 44
 535042,  535042, 45
 535042,  535042, 46
 535043,  535142, 47
 535142,  535142, 48
 535142,  535142, 49
 535142,  535142, 50
 535142,  535142, 51
 535143,  535242, 52
 535242,  535242, 53
 535242,  535242, 54
 535242,  535242, 55
 535242,  535242, 56
 535243,  535342, 57
 535342,  535342, 58
 535342,  535342, 59
 535342,  535342, 60
 535342,  535342, 61
 535343,  535442, 62
 535442,  535442, 63
 535442,  535442, 64
 535442,  535442, 65
 535442,  535442, 66
 535443,  535542, 67
 535542,  535542, 68
 535542,  535542, 69
 535542,  535542, 70
 535542,  535542, 71
 535543,  535642, 72

Das heißt, das Problem mit newtime = oldtime tritt dann bei _jedem_
Durchgang auf, so dass das Programm dann innerhalb von 10 Millisekunden
eine gewisse Anzahl wieder angesprungen wird - bis sich halt der Zähler
und damit newtime um 1 erhöht und somit die Bedingung

newtime - oldtime > 0

erfüllt ist. Wie oft das Programm innerhalb dieser 10 Millisekunden
angesprungen wird, das dürfte von der Schnelligkeit der Maschine
abhängig sein - ein Titanium schafft hier vermutlich mehr als ein
schnöder A4000. Die hier gegebenen Werte wurden auf dem RPI2
aufgezeichnet.

Leider habe ich auch noch ein anderes Problem gesichtet. Das Programm
wird manchmal auch innerhalb der vorgegebenen Sekunde unterbrochen, wenn
irgendwelche relevanten Ereignisse auftreten, welche die WIMP dem
Programm mitteilen möchte oder muss. Aber scheinbar kommt da irgend
etwas durcheinander. Weil das Programm dann wieder ständig angesprungen
wird, bis wieder die Bedingung

newtime - oldtime > 0

erfüllt ist. Warum das so ist, weiß ich nicht. Schließlich war eine
bestimmte Zeit angegeben worden, die dann aber von der WIMP ignoriert
wird.

Tschuldigung, dass ich mit solchen "Kleinigkeiten" hier so nerve und den
Mailer vollmülle. Aber ich kann schlecht einen Programmierkurs
schreiben, der dann auf Arcsite.de veröffentlicht wird, wenn ich es
selbst nicht verstanden habe oder etwas nicht gescheit funktioniert.
(Wie die Formel in den PRMs zum Beispiel.)

Alex'

-- 
http://home.chiemgau-net.de/ausserstorfer/

Other related posts: