Dies ist eine alte Version des Dokuments!


Cyclictest

Cyclictest startet mehrere Tasks, welche periodisch aufgerufen werden. Die effektive Periodendauer wird gemessen und der Jitter wird angezeigt.

Ein Vortrag von der „Embedded Linux Conference 2013“ bietet einen guten Einstig für die Benutzung des Cyclictest. Der Vortrag kann auf Youtube angeschaut werden. Die PPT Folien stehen hier zum Download bereit.

Installation

Siehe Projektwebseite#Installation

Bei der Copmpile-Fehlermeldung „src/cyclictest/rt_numa.h:23:18: fatal error: numa.h: No such file or directory“ siehe Projektwebseite

Crosscompilieren für MPC 5200

  1. „rt-tests“ auschecken
    git clone git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git

    Oder bereits angepasstest Repository verwenden und anschliessend bei Punkt 7 (Build ausführen) weiterfahren.

    git clone https://github.com/MarcelGehrig/rt-tests
  2. Ins Verzeichnis werchseln
    cd rt-test
  3. Im Makefile die 2. Zeile„CC?=\$(CROSS_COMPILE)gcc“ zu „CC:=$(CROSS_COMPILE)gcc“ ändern
  4. Im File „src/cyclictest/cyclictest.c“ in der Zeile 66 das Wort „static“ entfernen
  5. Im File „src/include/rt-sched.h“ nach der Zeile 56 folgende Zeilen hinzufügen:
    #ifdef __powerpc
    #define __NR_sched_setattr	    355
    #define __NR_sched_getattr	    356
    #endif
  6. Im File „src/lib/rt-utils.c“ nach der Zeile 24 folgende Zeilen hinzufügen:
    #ifndef SCHED_IDLE
    #define SCHED_IDLE 5
    #endif
  7. Build ausführen
    make all ARCH=powerpc CROSS_COMPILE=<pfad_zur_toolchain>powerpc-buildroot-linux-uclibc- NUMA=0
  8. „cyclictest“ auf das Target kopieren

Anwendung

Schnelle Messung

sudo ./cyclictest -p 80 -t5 -n

Erzeugt 5 Threads mit höchster Priorität von -80 (-p) mit der Verwendung von nano_sleep() (-n). Genauere Informationen siehe Projektwebseite#Run_it

Histogramm

Das Histogramm zeigt auf, welche Latenzen wie oft auftreten. Mit folgendem Befehl speichert der Cycletest die Daten in Form von einem Histogram ab.

sudo ./cyclictest -n -Sp80 -l600000 -i1000 -h1000 -q > histogramm.log
Histogramm von einem x86 mit RT Kernel. Messzeit 1h
-n use clock_nanosleep
-Sp80 S = alle Kerne; p = Priorität -80 (Realtime)
-l600000 600'000 Zyklen
-i1000 1000us pro Zyklus
-h1000 maximal Latenzen bis 1000us werden im Histogramm gemessen
-q quiet: keine Ausgaben während Messung
Messdauer: l600000*i1000 = 600e6us = 600s = 10min

Alle Messungen die länger dauern als -h1000 erscheinen nicht im Histogramm. Diese Messungen werden gezählt und am Schluss des Logfiles als Histogram Overflows: angezeigt. Die Maximale Latenz wird als Max Latencies: angezeigt.

Um das Histogramm zu plotten kann das Matlab Skript plotHistogramm.m verwendet werden.

Optionen

Die vollständige Dokumentation über die Optionen findet sich auf der Webseite des Cyclictest. Die wichtigsten Optionen werden in der folgenden Liste beschrieben:

-n use clock_nanosleep; clock_nanosleep wird von den meisten RT-Anwendungen verwendet
-p80 Priorität
-l600000 600'000 Zyklen bis der Test sich selbst beendet. Kann auch weg gelassen werden, wenn man den Test manuell mit CTL + C beendet
-i1000 1000us pro Zyklus
-h1000 maximal Latenzen bis 1000us werden im Histogramm gemessen
-q quiet: keine Ausgaben während Messung. Kann wichtig sein, wenn die SSH Verbindung die Messung stört
-m Der Cyclictest reserviert sich den benötigten Speicher zu beginn. Der Speicher muss nicht dynamisch zugewiesen werden.

Zu beachten

Priorität

Normale Prozesse haben eine Priorität zwischen 0 und 39. Wobei 0 die höchste Priorität ist. RT-Prozesse haben immer eine negative Priorität. Dabei ist -99 die höchste Priorität. Bei RT wird oft von einer positiven Priorität (z.B. +80) gesprochen. Dabei ist aber eigentlich die Priorität -80 gemeint. Eine höhere Priorität als 80 (oder korrekt -80) ist 81 (oder korrekt -81).

Um sich die Priorität von Prozessen anzeigen zu lassen eignet sicht htop am besten. htop lässt sich mit dem Befehl sudo apt-get install htop installieren.

Wenn htop nicht installiert werden kann, kann die Priorität auch über das Terminal ausgegeben werden. Dafür muss erst mit Hilfe von top die PID des Hauptprozesses ermittelt werden. Die RT-Prozesse, die vom Hauptprozess aus gestartet werden, haben aufeinander folgende PIDs. Mit folgendem Befehl kann dann die Priorität eines Prozesses angezeigt werden (hier vom Prozess mit der PID = 711):

awk '{print $18}' /proc/711/stat

Oder um auch noch den Namen und den „Nice“-Wert auszugeben :

awk '{print "Name: " $2, " Prio: " $18, " Nice: " $19}' /proc/<PID>/stat

Grundsätzlich empfiehlt sich für RT Anwendungen eine hohe Priorität. Wenn die maximale Latenz für eine Anwendung gemessen werden soll, dann sollte die Priorität um eins höher gewählt werden, als die Priorität der zu testenden Anwendung oder Prozess.

Eine Priorität von -80 ist für RT-Prozesse mit hoher Priorität gut geeignet.

Wenn eine Priorität von -49 oder kleiner gewählt wird, wird der Cyclictest von Kerneltasks und Interrupthandler unterbrochen. Dies kann gewollt sein, wenn die RT-Anwendung diese Tasks und Interrupthandler nicht unterbrechen darf.

SSH

Eine SSH Verbindung kann notwendig sein, um eine Messung auf einem Target überhaupt starten zu können. Allerdings kann eine solche Verbindung auch einen Einfluss auf die Latenz haben. Insbesondere wenn die Priorität kleiner als 50 gewählt wurde kann das Öffnen einer neuen SSH Verbindung die maximale Latenz erhöhen.

Wenn der Test läuft, werden die aktuellsten Daten mit einer hohen Aktualisierungsrate zum Client geschickt. Um dies zu verhindern kann der Cyclictest mit der Option -q für quiet gestartet werden. Dann werden die Messdaten erst übermittelt, wenn die Messung abgeschlossen ist, oder abgebrochen wird.

Zu erwartende Ergebnisse

MPC 5200

Für einen zyklischen Task mit einem Intervall von 1000us und der Priorität -80 ist ein Jitter von maximal 100-150us zu erwarten. Diese Ergebnisse können schlechter ausfallen, wenn zusätzliche Prozesse mit hoher Priorität (z.B. Interrupt Prozesse) laufen.

./cyclictest -n -p80 -t1 -i1000

In einem Blogpost schriebt Wolfgang Grandegger von ähnlichen Ergebnissen. Messungen innerhalb der NTB haben die Resultate bestätigt.

Alexander Bauer zeigt in seinem Paper Realtime capabilities of low-end PowerPC and ARM boards for embedded systems sogar noch bessere Ergebnisse auf. Laut diesem Paper ist der maximale Jitter gerade mal 45us. Allerdings wird nicht genau beschrieben, wie die Messung gemacht wurde. Solche Ergebnisse konnten in der NTB auch nicht reproduziert werden.

Messungen

Nur Cyclictest, ohne zusätzliche Last
# ./cyclictest -p 80 -t5 -n

15h 45min lange Messung

  • T: 0 ( 3264) P:80 I:1000 C:56714706 Min: 21 Act: 63 Avg: 49 Max: 106
  • T: 1 ( 3265) P:80 I:1500 C:37809807 Min: 22 Act: 52 Avg: 49 Max: 116
  • T: 2 ( 3266) P:80 I:2000 C:28357356 Min: 22 Act: 61 Avg: 51 Max: 108
  • T: 3 ( 3267) P:80 I:2500 C:22685885 Min: 22 Act: 69 Avg: 47 Max: 103
  • T: 4 ( 3268) P:80 I:3000 C:18904904 Min: 24 Act: 54 Avg: 50 Max: 124
Mit //Cache Calibrator// als zusätzliche Last
./cyclictest -p 80 -t5 -n

3 min lange Messung

  • T: 0 ( 3135) P:80 I:1000 C: 179806 Min: 21 Act: 58 Avg: 52 Max: 103
  • T: 1 ( 3136) P:80 I:1500 C: 119873 Min: 27 Act: 60 Avg: 54 Max: 136
  • T: 2 ( 3137) P:80 I:2000 C: 89905 Min: 20 Act: 60 Avg: 53 Max: 102
  • T: 3 ( 3138) P:80 I:2500 C: 71924 Min: 29 Act: 60 Avg: 52 Max: 126
  • T: 4 ( 3139) P:80 I:3000 C: 59937 Min: 37 Act: 52 Avg: 46 Max: 99

Der Cache Calibrator belastet den Cache stark. Trotz dieser Belastung ist die maximale Latenz kaum gestiegen.

100% Prozessorlast mit ''dd''
dd if=/dev/zero of=/dev/null
./cyclictest -p 80 -t5 -n

27 min lange Messung

T: 0 ( 695) P:80 I:1000 C:1643188 Min: 23 Act: 65 Avg: 49 Max: 120 T: 1 ( 696) P:80 I:1500 C:1095459 Min: 24 Act: 61 Avg: 51 Max: 119 T: 2 ( 697) P:80 I:2000 C: 821594 Min: 33 Act: 47 Avg: 43 Max: 89 T: 3 ( 698) P:80 I:2500 C: 657275 Min: 28 Act: 41 Avg: 51 Max: 99 T: 4 ( 699) P:80 I:3000 C: 547729 Min: 28 Act: 44 Avg: 51 Max: 114

Dank der hohen Priorität des Cyclictest von -80 wird er vom dd-Prozess, der eine Priorität von +20 hat, nicht beeinflusst.

x86

Für folgende Tests wurde ein Laptop mit folgenden Kenndaten verwendet:

  • 4x Intel Core i7-4600 CPU @ 2.1GHz
  • 16GB RAM
  • Linux Mint 17.3 Rosa

Linux Mint 17.3 Rosa wird mit einem 3.19 Kernel ausgeliefert. Für den 3.19 Kernel existiert aber kein RT-Patch. Für die RT-Tests wurde deshalb ein 3.18 Kernel verwendet. Mit dem 3.18 Kernel funktionierte das System aber nicht mehr einwandfrei. Es konnte zum Beispiel keine Netzwerkverbindung mehr aufgebaut werden.

Messungen

3.19.0-32-generic; Idle
./cyclictest -p 80 -t5 -n

19 min lange Messung

  • T: 0 (16289) P:80 I:1000 C:1149325 Min: 1 Act: 2 Avg: 1 Max: 1505
  • T: 1 (16290) P:80 I:1500 C: 766219 Min: 1 Act: 2 Avg: 1 Max: 1390
  • T: 2 (16291) P:80 I:2000 C: 574664 Min: 1 Act: 2 Avg: 2 Max: 1039
  • T: 3 (16292) P:80 I:2500 C: 459731 Min: 1 Act: 1 Avg: 2 Max: 741
  • T: 4 (16293) P:80 I:3000 C: 383109 Min: 1 Act: 2 Avg: 1 Max: 1320

Die Messung zeigt deutlich, das ein nicht RT gepatchter Kernel nicht für RT Anwendungen zu gebrauchen ist.

3.19.0-32-generic; Normaler Alltagsgebrauch
./cyclictest -p 80 -t5 -n

83 min lange Messung

  • T: 0 (17458) P:80 I:1000 C:4999230 Min: 1 Act: 2 Avg: 2 Max: 5269
  • T: 1 (17459) P:80 I:1500 C:3332832 Min: 1 Act: 2 Avg: 2 Max: 11175
  • T: 2 (17460) P:80 I:2000 C:2499634 Min: 1 Act: 1 Avg: 2 Max: 2435
  • T: 3 (17461) P:80 I:2500 C:1999709 Min: 1 Act: 1 Avg: 2 Max: 1933
  • T: 4 (17462) P:80 I:3000 C:1666423 Min: 1 Act: 2 Avg: 2 Max: 4224
3.18.29-rt30; RT-Kernel; ohne GUI
sudo ./cyclictest -n -p80 -l46800000 -i1000 -h1000 -q > histogramm.log

13h lange Messung

3.18.29-rt30; RT-Kernel; ohne GUI; Histogram Overflows: 0

Das Histogramm zeigt, dass die meisten Latenzen kleiner als 250us sind. Allerdings hat es auch einige Ausreisser von bis zu 900us zu erkennen. Die Latenzen von 40us bis 250us sind vermutlich auf die SMIs, welche typisch für x86 Architekturen sind, zurückzuführen. Mehr zum Thema SMI unter Einflüsse auf die Latenz von RT-Systemen. Um die Ausreisser zu erklären sind weitere Untersuchungen notwendig.

Künstliche Last