Bläddra i källkod

typos, engl/german mix into german only!

Michael Mächtel 8 år sedan
förälder
incheckning
2ba735c946
2 ändrade filer med 192 tillägg och 58 borttagningar
  1. 1
    1
      hw4/task1/README.md
  2. 191
    57
      hw4/task2/README.md

+ 1
- 1
hw4/task1/README.md Visa fil

253
 ## Kontrolle Ihres Repositories
253
 ## Kontrolle Ihres Repositories
254
 
254
 
255
 Haben Sie die Aufgaben komplett bearbeitet, so sollten sich folgende Dateien in
255
 Haben Sie die Aufgaben komplett bearbeitet, so sollten sich folgende Dateien in
256
-Ihrem HW (Homework) Verzeichnis befinden:
256
+Ihrem Projekt-Verzeichnis befinden:
257
 
257
 
258
 ```text
258
 ```text
259
 .
259
 .

+ 191
- 57
hw4/task2/README.md Visa fil

1
 # Homework hw4 task2
1
 # Homework hw4 task2
2
 
2
 
3
-Some hints, to solve this task with Rust:
3
+Die folgenden Informationen sollen helfen, sich schneller in die Materie des
4
+'Timings' von Programmen einzuarbeiten:
4
 
5
 
5
-- Have a look into the [std::mem] module.
6
-- Timings with the external crate [time][] is more constructive than the methods in the standard library.
7
-- As Rust uses the time keeping of the operating system, it might be interesting, if you "scan" reading through the following chapter to get an idea, whats going on beyond the Rust API.
6
+- Das externe Crate time][] bietet mehr und vor allem einfachere Funktionalität
7
+  als die Rust Standard-Bibliothek.
8
+- Alle Betriebssysteme stellen eine Time API zu Verfügung. Es kann hilfreich
9
+  sein zu verstehen, wie diese funktioniert. Daher beschäftigt sich das nächste
10
+  Kapitel ausführlich mit dieser API.
11
+- Das Modul [std::mem] aus der Standardbibliothek ist zur Lösung dieser Aufgabe
12
+  sehr hilfreich.
8
 
13
 
9
 [time]: https://docs.rs/time
14
 [time]: https://docs.rs/time
10
 [std::mem]: https://doc.rust-lang.org/std/mem/
15
 [std::mem]: https://doc.rust-lang.org/std/mem/
11
 
16
 
17
+- [Zeiten lesen in C](#zeiten-lesen-in-c)
18
+    - [Datenstrukturen](#datenstrukturen)
19
+        - [Zeit lesen](#zeit-lesen)
20
+        - [Zeitvergleich: Differenzzeitmessung](#zeitvergleich-differenzzeitmessung)
21
+          Differenzzeitmessung](#zeitvergleich-differenzzeitmessung)
12
 
22
 
13
 ## Zeiten lesen in C
23
 ## Zeiten lesen in C
14
 
24
 
25
+Das folgende Kapitel muss zur Lösung von task2 nicht komplett verstanden werden.
26
+Vielmehr soll es weitere Informationen liefern, wenn Ihnen gewisse
27
+Funktionalitäten der Thematik 'Timing' unklar sind.
28
+
15
 ### Datenstrukturen
29
 ### Datenstrukturen
16
 
30
 
17
-Betriebssysteme stellen Anwendungen Zeitgeber mit unterschiedlichen Eigenschaften zur Verfügung, über die das Zeitverhalten kontrolliert wird. Diese sind gekennzeichnet durch ihre
18
-* Genauigkeit,
19
-* die Zuverlässigkeit,
20
-* den Bezugspunkt,
21
-* die Darstellung und
22
-* den maximalen Zeitbereich.
31
+Betriebssysteme stellen Anwendungen Zeitgeber mit unterschiedlichen
32
+Eigenschaften zur Verfügung, über die das Zeitverhalten kontrolliert wird. Diese
33
+sind gekennzeichnet durch ihre
34
+
35
+- Genauigkeit,
36
+- die Zuverlässigkeit,
37
+- den Bezugspunkt,
38
+- die Darstellung und
39
+- den maximalen Zeitbereich.
23
 
40
 
24
-Das Betriebssystem repräsentiert Zeiten unter anderem mit den folgenden Datentypen (Darstellung):
41
+Das Betriebssystem repräsentiert Zeiten unter anderem mit den folgenden
42
+Datentypen (Darstellung):
25
 
43
 
26
-* clock_t: Timerticks.
27
-* struct timeval: Zeit in Mikrosekunden-Auflösung.
28
-* struct timespec: Zeit in Nanosekunden-Auflösung.
29
-* struct tm: absolute Zeitangabe.
44
+- clock_t: Timerticks.
45
+- struct timeval: Zeit in Mikrosekunden-Auflösung.
46
+- struct timespec: Zeit in Nanosekunden-Auflösung.
47
+- struct tm: absolute Zeitangabe.
30
 
48
 
31
 ```c
49
 ```c
32
 struct timeval {
50
 struct timeval {
54
 };
72
 };
55
 ```
73
 ```
56
 
74
 
57
-Die Strukturen struct timeval und struct timespec bestehen aus jeweils zwei Variablen, die einmal den Sekundenanteil und einmal den Mikro- beziehungsweise den Nanosekundenanteil repräsentieren. Die Darstellung erfolgt jeweils normiert. Das bedeutet, dass der Mikro- oder Nanosekundenanteil immer kleiner als eine volle Sekunde bleibt. Ein Zeitstempel von beispielsweise 1 Sekunde, 123456 Mikrosekunden ist gültig, 1 Sekunde, 1234567 Mikrosekunden ist ungültig. In normierter Darstellung ergäbe sich 2 Sekunden, 234567 Mikrosekunden.
58
-
59
-Die Darstellungs- beziehungsweise Repräsentationsform reflektiert auch den darstellbaren Wertebereich. Da bei den dargestellten Datenstrukturen für den Typ time\_t ein long eingesetzt wird, lassen sich auf einer 32-Bit Maschine rund 4 Milliarden Sekunden zählen, auf einer 64-Bit Maschine 2\^64 (mehr als 500 Milliarden Jahre).
60
-
61
-Als Bezugspunkte haben sich die folgenden eingebürgert: *Start des Systems, *Start eines Jobs und \*Start einer Epoche, beispielsweise "Christi Geburt" oder der 1.1.1970 (Unix-Epoche). Dieser Bezugspunkt weist zudem noch eine örtliche Komponente auf: Der Zeitpunkt 19:00 Uhr in Europa entspricht beispielsweise einem anderen Zeitpunkt in den USA (minus sechs Stunden zur Ostküste).
62
-
63
-Die Genauigkeit wird beeinflußt durch, die Taktung des Zeitgebers, deren Schwankungen und durch Zeitsprünge.
64
-
65
-Das Attribut Zuverlässigkeit eines Zeitgebers beschreibt dessen Verhalten bei (bewußten) Schwankungen der Taktung und bei Zeitsprüngen: Ein Zeitgeber kann beispielsweise der Systemuhr folgen (CLOCK\_REALTIME) oder unabhängig von jeglicher Modifikation an der Systemzeit einfach weiterzählen (CLOCK\_MONOTONIC). Die Posix-Realzeiterweiterung beziehungsweise Linux-Systeme definieren hierzu folgende Clocks [Man-Page zu clock\_gettime()](http://linux.die.net/man/3/clock_gettime):
66
-* **CLOCK\_REALTIME**: Dieser Zeitgeber repräsentiert die systemweite, aktuelle Zeit. Er reagiert auf Zeitsprünge, sowohl vorwärts als auch rückwärts, die beispielsweise beim Aufwachen (Resume) nach einem Suspend (Schlafzustand des gesamten Systems) ausgelöst werden. Er reagiert ebenfalls auf unterschiedliche Taktungen, die beispielsweise durch NTP erfolgen. Dieser Zeitgeber liefert die Sekunden und Nanosekunden seit dem 1.1. 1970 UTC (Unixzeit) zurück.
67
-* **CLOCK\_MONOTONIC**: Dieser Zeitgeber läuft entsprechend seiner Auflösung stets vorwärts, ohne dabei Zeitsprünge zu vollziehen. Er ist also unabhängig von der mit Superuserprivilegien zu verändernden Systemuhr. Allerdings reagiert dieser Zeitgeber auf Modifikationen der Taktung, die beispielsweise durch NTP erfolgen.
68
-* **CLOCK\_MONOTONIC_RAW**: Dieser Zeitgeber ist linuxspezifisch. Er reagiert weder auf Zeitsprünge noch auf in Betrieb geänderte Taktungen (NTP).
69
-* **CLOCK\_PROCESS\_CPUTIME_ID**: Dieser Zeitgeber erfasst die Verarbeitungszeit (Execution Time) des zugehörigen Prozesses. Das funktioniert aber nur zuverlässig auf Single-Core-Systemen beziehungsweise wenn sichergestellt werden kann, dass keine Prozessmigration stattfindet.
70
-* **CLOCK\_THREAD\_CPUTIME\_ID**: Dieser Zeitgeber erfasst die Verarbeitungszeit (Execution Time) des zugehörigen Threads. Das funktioniert aber nur zuverlässig auf Single-Core-Systemen beziehungsweise wenn sichergestellt werden kann, dass keine Prozessmigration stattfindet.
71
-
72
-Der maximale Zeitbereich schließlich ergibt sich durch die Auflösung des Zeitgebers und die Bitbreite der Variablen:
73
-
74
-```
75
+Die Strukturen struct timeval und struct timespec bestehen aus jeweils zwei
76
+Variablen, die einmal den Sekundenanteil und einmal den Mikro- beziehungsweise
77
+den Nanosekundenanteil repräsentieren. Die Darstellung erfolgt jeweils normiert.
78
+Das bedeutet, dass der Mikro- oder Nanosekundenanteil immer kleiner als eine
79
+volle Sekunde bleibt. Ein Zeitstempel von beispielsweise 1 Sekunde, 123456
80
+Mikrosekunden ist gültig, 1 Sekunde, 1234567 Mikrosekunden ist ungültig. In
81
+normierter Darstellung ergäbe sich 2 Sekunden, 234567 Mikrosekunden.
82
+
83
+Die Darstellungs- beziehungsweise Repräsentationsform reflektiert auch den
84
+darstellbaren Wertebereich. Da bei den dargestellten Datenstrukturen für den Typ
85
+time\_t ein long eingesetzt wird, lassen sich auf einer 32-Bit Maschine rund 4
86
+Milliarden Sekunden zählen, auf einer 64-Bit Maschine 2\^64 (mehr als 500
87
+Milliarden Jahre).
88
+
89
+Als Bezugspunkte haben sich die folgenden eingebürgert: *Start des Systems,
90
+*Start eines Jobs und \*Start einer Epoche, beispielsweise "Christi Geburt" oder
91
+der 1.1.1970 (Unix-Epoche). Dieser Bezugspunkt weist zudem noch eine örtliche
92
+Komponente auf: Der Zeitpunkt 19:00 Uhr in Europa entspricht beispielsweise
93
+einem anderen Zeitpunkt in den USA (minus sechs Stunden zur Ostküste).
94
+
95
+Die Genauigkeit wird beeinflußt durch, die Taktung des Zeitgebers, deren
96
+Schwankungen und durch Zeitsprünge.
97
+
98
+Das Attribut Zuverlässigkeit eines Zeitgebers beschreibt dessen Verhalten bei
99
+(bewußten) Schwankungen der Taktung und bei Zeitsprüngen: Ein Zeitgeber kann
100
+beispielsweise der Systemuhr folgen (CLOCK\_REALTIME) oder unabhängig von
101
+jeglicher Modifikation an der Systemzeit einfach weiterzählen
102
+(CLOCK\_MONOTONIC). Die Posix-Realzeiterweiterung beziehungsweise Linux-Systeme
103
+definieren hierzu folgende Clocks [Man-Page zu
104
+clock\_gettime()](http://linux.die.net/man/3/clock_gettime):
105
+
106
+- **CLOCK\_REALTIME**: Dieser Zeitgeber repräsentiert die systemweite, aktuelle
107
+  Zeit. Er reagiert auf Zeitsprünge, sowohl vorwärts als auch rückwärts, die
108
+  beispielsweise beim Aufwachen (Resume) nach einem Suspend (Schlafzustand des
109
+  gesamten Systems) ausgelöst werden. Er reagiert ebenfalls auf unterschiedliche
110
+  Taktungen, die beispielsweise durch NTP erfolgen. Dieser Zeitgeber liefert die
111
+  Sekunden und Nanosekunden seit dem 1.1. 1970 UTC (Unixzeit) zurück.
112
+- **CLOCK\_MONOTONIC**: Dieser Zeitgeber läuft entsprechend seiner Auflösung
113
+  stets vorwärts, ohne dabei Zeitsprünge zu vollziehen. Er ist also unabhängig
114
+  von der mit Superuserprivilegien zu verändernden Systemuhr. Allerdings
115
+  reagiert dieser Zeitgeber auf Modifikationen der Taktung, die beispielsweise
116
+  durch NTP erfolgen.
117
+- **CLOCK\_MONOTONIC_RAW**: Dieser Zeitgeber ist linuxspezifisch. Er reagiert
118
+  weder auf Zeitsprünge noch auf in Betrieb geänderte Taktungen (NTP).
119
+- **CLOCK\_PROCESS\_CPUTIME_ID**: Dieser Zeitgeber erfasst die Verarbeitungszeit
120
+  (Execution Time) des zugehörigen Prozesses. Das funktioniert aber nur
121
+  zuverlässig auf Single-Core-Systemen beziehungsweise wenn sichergestellt
122
+  werden kann, dass keine Prozessmigration stattfindet.
123
+- **CLOCK\_THREAD\_CPUTIME\_ID**: Dieser Zeitgeber erfasst die Verarbeitungszeit
124
+  (Execution Time) des zugehörigen Threads. Das funktioniert aber nur
125
+  zuverlässig auf Single-Core-Systemen beziehungsweise wenn sichergestellt
126
+  werden kann, dass keine Prozessmigration stattfindet.
127
+
128
+Der maximale Zeitbereich schließlich ergibt sich durch die Auflösung des
129
+Zeitgebers und die Bitbreite der Variablen:
130
+
131
+```text
75
 zeitbereich = auflösung * 2^bitbreite
132
 zeitbereich = auflösung * 2^bitbreite
76
 ```
133
 ```
77
 
134
 
78
 #### Zeit lesen
135
 #### Zeit lesen
79
 
136
 
80
-Es gibt unterschiedliche Systemfunktionen, mit denen die aktuelle Zeit gelesen werden kann. Favorisiert ist die Funktion *int clock\_gettime(clockid\_t clk\_id, struct timespec * tp)*, die die Zeit seit dem 1.1.1970 (Unixzeit) als Universal Time (Zeitzone UTC) zurückliefert (struct timespec). Konnte die aktuelle Zeit gelesen werden, gibt die Funktion Null, ansonsten einen Fehlercode zurück. Allerdings ist das Auslesen auf 32-Bit Systemen in so fern problematisch, da der 32-Bit Zähler am 19. Januar 2038 überläuft.
137
+Es gibt unterschiedliche Systemfunktionen, mit denen die aktuelle Zeit gelesen
138
+werden kann. Favorisiert ist die Funktion *int clock\_gettime(clockid\_t
139
+clk\_id, struct timespec * tp)*, die die Zeit seit dem 1.1.1970 (Unixzeit) als
140
+Universal Time (Zeitzone UTC) zurückliefert (struct timespec). Konnte die
141
+aktuelle Zeit gelesen werden, gibt die Funktion Null, ansonsten einen Fehlercode
142
+zurück. Allerdings ist das Auslesen auf 32-Bit Systemen in so fern
143
+problematisch, da der 32-Bit Zähler am 19. Januar 2038 überläuft.
81
 
144
 
82
 ```c
145
 ```c
83
 struct timespec {
146
 struct timespec {
99
         timestamp.tv\_sec, timestamp.tv\_nsec);
162
         timestamp.tv\_sec, timestamp.tv\_nsec);
100
 ```
163
 ```
101
 
164
 
102
-Durch die Wahl der Clock CLOCK\_PROCESS\_CPUTIME\_ID beziehungsweise CLOCK\_THREAD\_CPUTIME\_ID kann auch die Verarbeitungszeit ausgemessen werden (Profiling).
165
+Durch die Wahl der Clock CLOCK\_PROCESS\_CPUTIME\_ID beziehungsweise
166
+CLOCK\_THREAD\_CPUTIME\_ID kann auch die Verarbeitungszeit ausgemessen werden
167
+(Profiling).
168
+
169
+Die Genauigkeit der zurückgelieferten Zeit kann mit Hilfe der Funktion
170
+*clock\_getres(clockid\_t clk\_id, struct timespec * res)* ausgelesen werden.
103
 
171
 
104
-Die Genauigkeit der zurückgelieferten Zeit kann mit Hilfe der Funktion *clock\_getres(clockid\_t clk\_id, struct timespec * res)* ausgelesen werden.
172
+Die Funktion *clock\_gettime()* ist nicht in der Standard-C-Bibliothek zu
173
+finden, sondern in der Realzeit-Bibliothek librt. Daher ist bei der
174
+Programmgenerierung diese Bibliothek hinzuzulinken (Parameter -lrt). Steht nur
175
+die Standard-C-Bibliothek zur Verfügung, kann
105
 
176
 
106
-Die Funktion *clock\_gettime()* ist nicht in der Standard-C-Bibliothek zu finden, sondern in der Realzeit-Bibliothek librt. Daher ist bei der Programmgenerierung diese Bibliothek hinzuzulinken (Parameter -lrt). Steht nur die Standard-C-Bibliothek zur Verfügung, kann *time\_t time(time\_t * t)* oder auch *int gettimeofday(struct timeval * tv, struct timezone * tz)* eingesetzt werden.
177
+- time\_t time(time\_t *t) oder auch
178
+- int gettimeofday(struct timeval * tv, struct timezone * tz)
179
+
180
+eingesetzt werden.
107
 
181
 
108
 *time()* gibt die Sekunden zurück, die seit dem 1.1.1970 (UTC) vergangen sind.
182
 *time()* gibt die Sekunden zurück, die seit dem 1.1.1970 (UTC) vergangen sind.
109
 
183
 
113
 now = time(NULL);
187
 now = time(NULL);
114
 ```
188
 ```
115
 
189
 
116
-*gettimeofday()* schreibt an die per tv übergebene Speicheradresse die Sekunden und Mikrosekunden seit dem 1.1.1970. Das Argument tz wird typischerweise mit NULL angegeben.
190
+*gettimeofday()* schreibt an die per tv übergebene Speicheradresse die Sekunden
191
+und Mikrosekunden seit dem 1.1.1970. Das Argument tz wird typischerweise mit
192
+NULL angegeben.
193
+
194
+Liegen die Sekunden seit dem 1.1.1970 vor (timestamp.tv\_sec), können diese mit
195
+Hilfe der Funktionen
117
 
196
 
118
-Liegen die Sekunden seit dem 1.1.1970 vor (timestamp.tv\_sec), können diese mit Hilfe der Funktionen *struct tm * localtime\_r(const time\_t * timep, struct tm * result)* oder *struct tm * gmtime\_r(const time\_t * timep, struct tm * result)* in die Struktur struct tm konvertiert werden.
197
+- struct tm *localtime\_r(const time\_t *timep, struct tm *result) oder
198
+- struct tm *gmtime\_r(const time\_t * timep, struct tm *result)
199
+
200
+in die Struktur *struct tm* konvertiert werden.
119
 
201
 
120
 ```c
202
 ```c
121
 struct tm absolute_time;
203
 struct tm absolute_time;
128
 printf("year: %d\n", absolute_time.tm_year);
210
 printf("year: %d\n", absolute_time.tm_year);
129
 ```
211
 ```
130
 
212
 
131
-Die Funktion *time\_t mktime(struct tm * tm)* konvertiert eine über die Struktur struct tm gegebene Zeit in Sekunden seit dem 1.1.1970 (time\_t).
213
+Die Funktion *time\_t mktime(struct tm * tm)* konvertiert eine über die Struktur
214
+struct tm gegebene Zeit in Sekunden seit dem 1.1.1970 (time\_t).
132
 
215
 
133
-Mit Hilfe der Funktion *clock\_t times(struct tms \ buf)* lässt sich sowohl die aktuelle Zeit zu einem letztlich nicht genau definierten Bezugspunkt, als auch die Verarbeitungszeit (Execution-Time) des aufrufenden Prozesses bestimmen. Die Zeiten werden als Timerticks (clock\_t) zurückgeliefert. Die zurückgelieferte Verarbeitungszeit ist aufgeschlüsselt in die Anteile, die im Userland und die Anteile, die im Kernel verbraucht wurden. Außerdem werden diese Anteile auch für Kindprozesse gelistet.
216
+Mit Hilfe der Funktion *clock\_t times(struct tms \ buf)* lässt sich sowohl die
217
+aktuelle Zeit zu einem letztlich nicht genau definierten Bezugspunkt, als auch
218
+die Verarbeitungszeit (Execution-Time) des aufrufenden Prozesses bestimmen. Die
219
+Zeiten werden als Timerticks (clock\_t) zurückgeliefert. Die zurückgelieferte
220
+Verarbeitungszeit ist aufgeschlüsselt in die Anteile, die im Userland und die
221
+Anteile, die im Kernel verbraucht wurden. Außerdem werden diese Anteile auch für
222
+Kindprozesse gelistet.
134
 
223
 
135
 ```c
224
 ```c
136
 #include <stdio.h>
225
 #include <stdio.h>
158
 }
247
 }
159
 ```
248
 ```
160
 
249
 
161
-Sehr genaue Zeiten lassen sich erfassen, falls der eingesetzte Prozessor einen Zähler besitzt, der mit der Taktfrequenz des Systems getaktet wird. Bei einer x86-Architektur (PC) heißt dieser Zähler Time Stamp Counter (TSC). Der TSC kann auch von einer normalen Applikation ausgelesen werden, allerdings muss sichergestellt sein, dass sich die Taktfrequenz zwischen zwei Messungen ändert. Alternativ kann man sich vom Betriebssystem über die Taktänderung informieren lassen.
250
+Sehr genaue Zeiten lassen sich erfassen, falls der eingesetzte Prozessor einen
251
+Zähler besitzt, der mit der Taktfrequenz des Systems getaktet wird. Bei einer
252
+x86-Architektur (PC) heißt dieser Zähler Time Stamp Counter (TSC). Der TSC kann
253
+auch von einer normalen Applikation ausgelesen werden, allerdings muss
254
+sichergestellt sein, dass sich die Taktfrequenz zwischen zwei Messungen ändert.
255
+Alternativ kann man sich vom Betriebssystem über die Taktänderung informieren
256
+lassen.
162
 
257
 
163
 #### Zeitvergleich: Differenzzeitmessung
258
 #### Zeitvergleich: Differenzzeitmessung
164
 
259
 
165
-Zwei Absolutzeiten (struct tm) werden am einfachsten über deren Repräsentation in Sekunden verglichen. Die Umwandlung erfolgt über die Funktion (time\_t mktime(struct tm \*tm)). Allerdings ist dabei zu beachten, dass es auf einem 32-Bit System am 19. Januar 2038 zu einem Überlauf kommt. Wird einer der beiden Zeitstempel vor dem 19. Januar 2038 genommen, der andere danach, kommt es zu einem falschen Ergebnis, wenn nur die beiden Werte per "\<" beziehungsweise "\>" verglichen werden.
166
-
167
-Das ist ein generelles Problem und kann dann gelöst werden, wenn sichergestellt ist, dass die zu vergleichenden Zeiten nicht weiter als die Hälfte des gesamten Zeitbereiches auseinanderliegen. In diesem Fall lassen sich die Makros einsetzen, die im Linux-Kernel für den Vergleich zweier Zeiten eingesetzt werden. Das Makro time\_after(a,b) liefert true zurück, falls es sich bei a um eine spätere Zeit als b handelt. Das Makro time\_after\_eq(a,b) liefert true zurück, falls es sich bei a um eine spätere Zeit oder um die gleiche Zeit handelt, wie b handelt. Die Zeitstempel a und b müssen beide vom Typ unsigned long sein. Natürlich können die Makros auch auf andere Datentypen angepasst werden
260
+Zwei Absolutzeiten (struct tm) werden am einfachsten über deren Repräsentation
261
+in Sekunden verglichen. Die Umwandlung erfolgt über die Funktion (time\_t
262
+mktime(struct tm \*tm)). Allerdings ist dabei zu beachten, dass es auf einem
263
+32-Bit System am 19. Januar 2038 zu einem Überlauf kommt. Wird einer der beiden
264
+Zeitstempel vor dem 19. Januar 2038 genommen, der andere danach, kommt es zu
265
+einem falschen Ergebnis, wenn nur die beiden Werte per "\<" beziehungsweise "\>"
266
+verglichen werden.
267
+
268
+Das ist ein generelles Problem und kann dann gelöst werden, wenn sichergestellt
269
+ist, dass die zu vergleichenden Zeiten nicht weiter als die Hälfte des gesamten
270
+Zeitbereiches auseinanderliegen. In diesem Fall lassen sich die Makros
271
+einsetzen, die im Linux-Kernel für den Vergleich zweier Zeiten eingesetzt
272
+werden. Das Makro time\_after(a,b) liefert true zurück, falls es sich bei a um
273
+eine spätere Zeit als b handelt. Das Makro time\_after\_eq(a,b) liefert true
274
+zurück, falls es sich bei a um eine spätere Zeit oder um die gleiche Zeit
275
+handelt, wie b handelt. Die Zeitstempel a und b müssen beide vom Typ unsigned
276
+long sein. Natürlich können die Makros auch auf andere Datentypen angepasst
277
+werden
168
 
278
 
169
 [HEADERDATEI linux/jiffies.h].
279
 [HEADERDATEI linux/jiffies.h].
170
 
280
 
184
 #define time_before_eq(a,b)     time_after_eq(b,a)
294
 #define time_before_eq(a,b)     time_after_eq(b,a)
185
 ```
295
 ```
186
 
296
 
187
-Beim Benchmarking ist es häufig notwendig eine Zeitdauer zu messen, Zeitpunkte zu erfassen oder eine definierte Zeit verstreichen zu lassen. Dabei sind folgende Aspekte zu beachten:
188
-* Die Genauigkeit der eingesetzten Zeitgeber,
189
-* die maximalen Zeitdifferenzen,
190
-* Schwankungen der Zeitbasis, beispielsweise durch Schlafzustände,
191
-* Modifikationen an der Zeitbasis des eingesetzten Rechnersystems (Zeitsprünge) und
192
-* die Ortsabhängigkeit absoluter Zeitpunkte.
193
-
194
-Zur Bestimmung einer Zeitdauer verwendet man häufig eine Differenzzeitmessung. Dabei wird vor und nach der auszumessenden Aktion jeweils ein Zeitstempel genommen. Die Zeitdauer ergibt sich aus der Differenz dieser beiden Zeitstempel.
195
-
196
-Dies ist allerdings nicht immer ganz einfach. Liegt der Zeitstempel beispielsweise in Form der Datenstruktur struct timeval (als Ergebnis der Funktion *gettimeofday()*) vor, müssen die Sekunden zunächst getrennt von den Mikrosekunden subtrahiert werden. Ist der Mikrosekundenanteil negativ, muss der Sekundenanteil um eins erniedrigt und der Mikrosekundenanteil korrigiert werden. Dazu wird auf die Anzahl der Mikrosekunden pro Sekunde (also eine Million) der negative Mikrosekundenanteil addiert.
297
+Beim Benchmarking ist es häufig notwendig eine Zeitdauer zu messen, Zeitpunkte
298
+zu erfassen oder eine definierte Zeit verstreichen zu lassen. Dabei sind
299
+folgende Aspekte zu beachten:
300
+
301
+- Die Genauigkeit der eingesetzten Zeitgeber,
302
+- die maximalen Zeitdifferenzen,
303
+- Schwankungen der Zeitbasis, beispielsweise durch Schlafzustände,
304
+- Modifikationen an der Zeitbasis des eingesetzten Rechnersystems (Zeitsprünge)
305
+  und
306
+- die Ortsabhängigkeit absoluter Zeitpunkte.
307
+
308
+Zur Bestimmung einer Zeitdauer verwendet man häufig eine Differenzzeitmessung.
309
+Dabei wird vor und nach der auszumessenden Aktion jeweils ein Zeitstempel
310
+genommen. Die Zeitdauer ergibt sich aus der Differenz dieser beiden Zeitstempel.
311
+
312
+Dies ist allerdings nicht immer ganz einfach. Liegt der Zeitstempel
313
+beispielsweise in Form der Datenstruktur struct timeval (als Ergebnis der
314
+Funktion *gettimeofday()*) vor, müssen die Sekunden zunächst getrennt von den
315
+Mikrosekunden subtrahiert werden. Ist der Mikrosekundenanteil negativ, muss der
316
+Sekundenanteil um eins erniedrigt und der Mikrosekundenanteil korrigiert werden.
317
+Dazu wird auf die Anzahl der Mikrosekunden pro Sekunde (also eine Million) der
318
+negative Mikrosekundenanteil addiert.
197
 
319
 
198
 ```c
320
 ```c
199
 #define MICROSECONDS\_PER\_SECOND 1000000
321
 #define MICROSECONDS\_PER\_SECOND 1000000
216
 
338
 
217
 }
339
 }
218
 ```
340
 ```
219
-Für Zeitstempel vom Typ struct timeval gilt entsprechendes. Anstelle der MICROSECONDS\_PER\_SECOND sind NANOSECONDS\_PER\_SECOND einzusetzen. Sind die Zeitstempel vorzeichenlos, sieht die Rechnung für den Sekundenanteil etwas komplizierter aus. Das soll hier aber nicht weiter vertieft werden.
220
 
341
 
221
-Etwas einfacher ist die Differenzbildung, wenn aus der Datenstruktur eine einzelne Variable mit der gewünschten Auflösung, beispielsweise Mikrosekunden, generiert wird. Im Fall von struct timeval wird dazu der Sekundenanteil mit einer Million multipliziert und der Mikrosekundenanteil aufaddiert. Bei der Multiplikation können natürlich Informationen verloren gehen, allerdings geht der gleiche Informationsgehalt auch beim zweiten Zeitstempel verloren. Für die Differenzbildung ist das damit nicht relevant, solange der zu messende zeitliche Abstand kleiner als 1000 Sekunden ist und es während der Messung keinen Überlauf beim Sekundenanteil gibt.
342
+Für Zeitstempel vom Typ struct timeval gilt entsprechendes. Anstelle der
343
+MICROSECONDS\_PER\_SECOND sind NANOSECONDS\_PER\_SECOND einzusetzen. Sind die
344
+Zeitstempel vorzeichenlos, sieht die Rechnung für den Sekundenanteil etwas
345
+komplizierter aus. Das soll hier aber nicht weiter vertieft werden.
346
+
347
+Etwas einfacher ist die Differenzbildung, wenn aus der Datenstruktur eine
348
+einzelne Variable mit der gewünschten Auflösung, beispielsweise Mikrosekunden,
349
+generiert wird. Im Fall von struct timeval wird dazu der Sekundenanteil mit
350
+einer Million multipliziert und der Mikrosekundenanteil aufaddiert. Bei der
351
+Multiplikation können natürlich Informationen verloren gehen, allerdings geht
352
+der gleiche Informationsgehalt auch beim zweiten Zeitstempel verloren. Für die
353
+Differenzbildung ist das damit nicht relevant, solange der zu messende zeitliche
354
+Abstand kleiner als 1000 Sekunden ist und es während der Messung keinen Überlauf
355
+beim Sekundenanteil gibt.
222
 
356
 
223
 ```c
357
 ```c
224
 time_in_usec=((nachher.tv_sec*1000000)+nachher.tv_usec)-
358
 time_in_usec=((nachher.tv_sec*1000000)+nachher.tv_usec)-

Laddar…
Avbryt
Spara