Donnerstag, 28. April 2016

Zusammenspiel von lighttpd und pelican

Motivation

Seit kurzen schreibe ich meinen Blog mit Hilfe von markdown und dem Weseitengenerator pelican. Das funktioniert auch ganz gut. Pelican rendert aus den Posts eine HTML Seite, welche ich mittels markdown geschreiben habe. Diese muss ich dann nur noch bei blogger "hinein" kopieren. Alternativ möchte ich meinen Blog auch in meinem lokalen Netz (von einem Raspberry Pi) gehostet haben. Dies bietet mir die Möglichkeit, schnell mal etwas zu probieren und noch nicht fertige Posts vorab schon einmal zu begutachten. Grundsätzlich geht das auch mit dem bei pelican enthalten "develop_server.sh" Skript, aber nur auf dem Rechner wo ich pelicaninstalliert habe.

Als Webserver verwende ich daher lighttpd. Dieser ist ein Ressourcen sparender Webserver, ideal geeignet für statische Seiten und für das Raspberry Pi.

Installation

Der Webserver kann direkt aus den Paketquellen installiert werden.

sudo apt-get install lighttpd

Anschließend ist er direkt unter der IP des Servers und Port 80 erreichbar. Dazu einfach die IP in den Browser eingeben und die "Placeholder page" erscheint. Darin sind folgende Informationen dokumentiert:

  • Die Readme liegt unter /etc/lighttpd/conf-available/README
  • Die Konfigurations Datein befinden sich in /etc/lighttpd
  • Das Dokumenten root Verzeichnis liegt in /var/www/html

Standardmäßig läuft der Webserver unter dem User/Group www-data, d.h. dieser muss zumindes Leserechte für das Dokumenten root Verzeichnis haben. Für meine Zwecke habe ich die Rechte wie folgt gesetz:

#Besitzer des Dokumenten root ist der www-data user und dessen Gruppe
$sudo chown -R www-data:www-data html/
#die Zugriffsrechte habe ich wie folgt gesetz
$sudo chmod -R 750 /var/www/html/
#damit ich in das Verzeichnis schreiben kann, füge ich den user (am Beispiel pi) der Gruppe www-data hinzu
$sudo usermod -g www-data pi
#und gebe allen Gruppenmitgliedern Schreibrechte für den Ordner
$sudo chmod -R g+w /var/www/html/
#Ergebnis
$ls -l /var/www
drwxrwx--- 2 www-data www-data 4096 Apr 26 23:21 html

Konfiguration

Die Konfiguration von lighttpd erfolgt durch :die Datei /etc/lighttpd/lighttpd.conf. Ich habe für diesen Anwendungszweck keine weitere Konfiguration vorgenommen.

Deployment

Auf dem host und dem target muss rsync installiert sein bzw. werden.

sudo apt-get install rsync

Anschließend wechselt man in das Projektverzeichnis von pelican und kopiert den Inhalt des von pelican erzeugten output Ordners auf dem Server in das Dokumenten root Verzeichnis. Hier das Beispiel für meine Konfiguration

cd ~/myblog
rsync -rvzc output/ user@ip:/var/www/html/

Um diesen Prozess zu vereinfachen bietet pelican die Möglichkeit das Deployment via Makefile zu übernehmen. Dazu muss die Server Zugangsdaten wie folgt eingetragen werden:

$vi Makefile
SSH_HOST=<IP>
SSH_PORT=22
SSH_USER=<USER>
SSH_TARGET_DIR=/var/www/html

Der Upload zum Server kann anschließend mit

make rsync_upload

erfolgen. Neben dieser Möglichkeit wird auch der Upload via ssh, dropbox, ftp oder github angeboten.

Weiterhin kann für das dadurch erfolgende Veröffentlichen der Seite die zugehörige pelican Konfiguration angepasst werden. In dieser kann z.B. die Generierung von Feeds eingestellt werden. Dies erfolt in der Datei publishconf.py. Die zugehörige Dokumentation gibt es auf der Projektseite.

Sonntag, 24. April 2016

Backup SD-Karte

Zielstellung

Erstelung eines Backups einer SD-Karte am Beispiel Raspberry Pi. Reduzierung des benötigten Speicherplatzes auf dem Host.

Ergebnis

Device Größe in GB Größe in 1M-Blöcke
SD-Karte 15G 56M + 14484M
backup.img 15G 14840M
backup.tar.gz 5.0G 5019M
backup.img(1) 7.5G 7598M
backup.tar.gz(1) 4.5G 4601M

(1) Mit verkleinerter rootfs Partition.

Zur Anzeige der Größe in 1M-Blöcken, wurden folgende Kommandos verwendet.

#für Verzeichnisse
ls --block-size=M -l
#für Device X
df --block-size=M /dev/sdbX

Hintergrund

Eine SD-Karte für das Raspberry Pi enthält zwei Partitionen. Die Erste ist die s.g. Boot Partition, welche den Bootloader, das Kernel Image usw. enthält. Die Zweite enthält das Rootfs mit den eigentlichen Daten. Mit dem tool raspi-config, kann die zweite Partition auf die Größe der verwendeten SD-Karte erweitert werden. Die folgende Ausschrift wurde mittels fdisk (vom HOST aus) erstellt und enthält den Inhalt einer 16GB SD-Karte, welche hier als Beispiel genommen wird.

#das verwendete device muss an das eigene System angepasst werden
$sudo fdisk -l /dev/sdb
Disk /dev/sdb: 15.6 GB, 15560867840 bytes
64 Köpfe, 32 Sektoren/Spur, 14840 Zylinder, zusammen 30392320 Sektoren
Einheiten = Sektoren von 1 × 512 = 512 Bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Festplattenidentifikation: 0x00092fac

   Gerät  boot.     Anfang        Ende     Blöcke   Id  System
/dev/sdb1            8192      122879       57344    c  W95 FAT32 (LBA)
/dev/sdb2          122880    30392319    15134720   83  Linux

Mit dem Tool df kann der freie Speicherplatz angezeigt werden.

$df -h /dev/sdb1
Dateisystem    Größe Benutzt Verf. Verw% Eingehängt auf
/dev/sdb1        56M     23M   34M   40% /media/boot
$df -h /dev/sdb2
Dateisystem    Größe Benutzt Verf. Verw% Eingehängt auf
/dev/sdb2        15G    6,8G  6,8G   51% /media/rootfs

Wie man sieht wurde das rootfs auf die volle Größe der SD-Karte erweitert und ist zur Hälfte befüllt.

Backup erstellen

Um das Backup zu erstellen, kann am einfachsten auf dd zurückgegriffen werden. Dieses erzeugt ein vollständiges Abbild der gesamten SD-Karte, d.h. es wird ein Image mit der selben Größe wie die der SD-Karte angelegt, egal ob das rootfs auf die gesamte Größe erweitert wurde. Zum Lesen des SD-Karten Devices werden root Rechte benötigt, um das Image anschließend zu bearbeiten, müssen die Rechte entsprechend geändert werden.

#das verwendete device muss an das eigene System angepasst werden
$sudo dd if=/dev/sdb of=backup.img
$sudo chown user:usergroup backup.img

Standardmäßig zeigt dd keinen Fortschritt an, dies kann aber wie folgt "ergänzt" werden. Hiermit wird dd zyklisch ein Signal gesendet, in Folge dessen es den aktuellen Stand des Kopierprozesses ausgibt.

$ sudo dd if=/dev/sdb of=backup.img&
[1] pid
$ sudo watch --interval 10 kill -USR1 pid
Alle 10,0s: kill -USR1 6068
...
5121777+0 Datensätze ein
5121776+0 Datensätze aus
2622349312 Bytes (2,6 GB) kopiert, 54,0639 s, 48,5 MB/s
...
#Am Ende muss watch noch mit STRG+C beendet werden.

Schaut man sich jetzt die Größe des Backups an, sieht man das es wie die SD-Karte 15GB groß.

Speicherplatz reduzieren

Der erste Ansatz die Größe des Backups zu reduzieren, ist das Image zu komprimieren.

tar -czf backup.tar.gz backup.img

Als Ergebnis reduziert sich die Größe von 15GB auf 5GB. Wenn das ausreichend ist, kann an dieser Stelle aufgehört werden.

Optimierung

Wenn man die komprimierte Größe weiter reduzieren möchte, können folgende Punkte berücksichtigt werden.

Rootfs Partition verkleinern

Um ein SD-Karten Image unter Linux mit gparted zu bearbeiten, muss zuvor ein loop device angelegt werden. Dazu wird das tool losetup benötigt. Falls das loop modul als ladbares Kernel Modul verwendet wird, muss dieses zunächst geladen werden. Dieser Ansatz kann auch dafür verwendet werden, wenn man das Image auf einer kleineren SD-Karte (z.b. 16GB -> 8GB) verwenden möchte.

sudo modprobe loop

Als Zweites muss das erste freie loop device herausgesucht werden.

sudo losetup -f

Angenommen das erste freie loop device ist /dev/loop0, wird dieses verwendet, um dieses mit dem SD-Karten Image einzurichten.

sudo losetup /dev/loop0 backup.img

Im Nächsten Schritt wird die Partitions Tabelle des loop devices (eigentlich des SD-Karten Images) dem System bekannt gemacht.

sudo partprobe /dev/loop0

Jetzt können die Partitionen des SD-Card images mit gparted geändert (verkleinert/vergrößert) werden. Dazu die neue Größe so anlegen, dass diese etwas Größer ist, als der belegte Speicher des rootfs. An der Größe der boot Partition darf NICHTS geändert werden.

sudo gparted /dev/loop0

Am Ende kann das loop device mit folgendem Befehl wieder gelöscht werden.

sudo losetup -d /dev/loop0

Bis jetzt hat sich aber an der Image Größe noch Nichts geändert, nur die Partition des rootfs ist jetzt kleiner geworden. Das Ergebnis kann man sich wieder mittels fdisk ansehen.

$fdisk -l backup.img 

Disk backup.img: 15.6 GB, 15560867840 bytes
255 Köpfe, 63 Sektoren/Spur, 1891 Zylinder, zusammen 30392320 Sektoren
Einheiten = Sektoren von 1 × 512 = 512 Bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Festplattenidentifikation: 0x00092fac

     Gerät  boot.     Anfang        Ende     Blöcke   Id  System
backup.img1            8192      122879       57344    c  W95 FAT32 (LBA)
backup.img2          122880    15560703     7718912   83  Linux

Um jetzt auch das Image zu verkleinern, kann dieses mit truncate auf die geänderte Größe der Partionen angepasst werden.

#truncate --size=$[(Ende+1)*sector size] backup.img
truncate --size=$[15560704*512] backup.img 

In meinem Beispiel konnte die Größe des Image auf 7.5GB und komprimiert auf 4.5GB reduziert werden. Außerdem besteht so die Möglichkeit das Image ggfls. auch auf einer 8GB SD-Karte zu verwenden.

Rootfs aufräumen

Ein recht einfacher Weg die Größe zu reduzieren, ist nicht benötigte Daten zu löschen. Zuerst wird wie im Schritt "Rootfs Partition verkleinern" beschrieben, ein loop device angelegt, welches anschließend gemounten und bearbeitet werden kann.

mkdir rootfs
sudo mount /dev/loop0p2 rootfs
#löschen nicht benötigter Daten etc.
sudo umount rootfs

Komprimierung verbesseren

Zur Verbesserung der Komprimierung, kann der freie Speicherplatz mit NULL beschrieben werden, dazu kann das Tool zerofree verwendet werden. Dies ist Notwendig, da gelöschte Daten nicht physikalisch gelöscht werden, sondern nur der Eintrag im Dateisystem. Dies führt bei der Komprimierung dazu, dass dieser Bereich nicht optimal verkleinert werden kann. Wie stark der Effekt ist, hängt natürlich vom verwendeten Image ab. Be

Zuerst, wie im Schritt "Rootfs Partition verkleinern" beschrieben ein loop device anlegen, dann zerofree anwenden und am Ende das Image komprimieren.

sudo zerofree -n /dev/loop0p2

Powered by Pelican. Theme blueidea, inspired by the default theme.

Mittwoch, 20. April 2016

Raspberry Pi Benchmarks - Ein Vergleich der Generationen

Hardware Gegenüberstellung

Generation Architektur CPU SDRAM
RPi 1 ARMv6 BCM2835, single core 256/512 MB
RPi 2 ARMv7, Cortex-A7 BCM2836, quad core 1 GB
RPi 3 ARMv8, Cortex-A53 BCM2837, quad core 2 GB

Trotz 64bit Architektur wird der RPi 3 aus kompatibilitäts Gründen als 32 CPU betrieben.

Benchmarks

coremark

Coremark ist ein Performance Benchmark für embedded CPUs. Daher eignet er sich gut, um die drei Pi Generationen zu vergleichen. Nähere Details, weitere Ergebnisse und den Quellcode findet man auf der Webseite der Entwickler von EMBC.

Durchführung

Der Benchmark wurde per Skript mehrfach als Performance Run (ITERATIONS=160000) durchgeführt und die Ergebnisse gemittelt. Folgende compiler Schalter wurden dafür verwendet:

RPi1: export CC="gcc -march=armv6 -mfloat-abi=hard -mfpu=vfp"

RPi2/3: export CC="gcc -march=armv7-a --mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4"

Ergebnisse

CoreMark 1.0 : siehe Tabelle/ GCC4.9.2 -O2 -DPERFORMANCE_RUN=1 -lrt / Heap

Generation Ergebnis Ergebnis/MHz
RPi 1 900MHz 1849.1032 2.054
RPi 2 1000MHz 2315.0526 2.315
RPi 3 1200MHz 3164.2406 2.637

whetstone

Der whetstone Benchmark gehört zu den klassischen CPU Benchmarks. Ich habe hier die Version von der Roy Longbottom's PC Benchmark Collection verwendet. Auf dieser Seite wurden auch Ergebnisse für das Raspberry Pi veröffentlicht und es gibt weitere Details zu dem Benchmark.

Durchführung

Zur Durchführung habe ich den code wie folgt kompiliert.

  • RPI1: Single Precision C Benchmark Opt 3 32 Bit gcc whets.c cpuidc.c -lm -lrt -O3 -march=armv6 -mfloat-abi=hard -mfpu=vfp -o whetstonePiA6

  • RPi2/3: Single Precision C Benchmark vfpv4 32 Bit gcc whets.c cpuidc.c -lm -lrt -O3 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 -o whetstonePiA7

Ergebnisse

Generation MFLOPS MFLOPS/MHz
RPi 1 900MHz 303.817 0.3376
RPi 2 1000MHz 486.357 0.4864
RPi 3 1200MHz 711.297 0.5927

dhrystone

Wie der whetstone handelt es sich beim dhrystone auch um einen klassischen Benchmark. Ich habe hier wieder die Version von der Roy Longbottom's PC Benchmark Collection verwendet. Auf dieser Seite gibt es auch die Hintergrundinformationen zu dem dhrystone Benchmark.

Durchführung

Zur Durchführung habe ich den code wie folgt kompiliert.

  • RPi1: gcc dhry_1.c dhry_2.c cpuidc.c -lm -lrt -O3 -march=armv6 -mfloat-abi=hard -mfpu=vfp -o dhrystonePiA6

  • RPI2/3: gcc dhry_1.c dhry_2.c cpuidc.c -lm -lrt -O3 -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 -o dhrystonePiA7

Ergebnisse

Generation VAX MIPS rating VAX MIPS rating/MHz
RPi 1 900MHz 1118.51 1.243
RPi 2 1000MHz 1833.64 1.834
RPi 3 1200MHz 1245.41 1.038 (todo: freq scaling prüfen)

UnixBench

Beim UnixBench handelt es sich um eine Sammlung von einzelnen Benchmarks, welche nacheinander durchgeführt werden. Am Ende des Tests werden die Einzelergebnisse und als Zusammenfassung ein Index Score zur Bewertung des Systems in einer HTML ausgegeben. Ich habe den Benchmark in der Version 5.1.3 ausgeführt.

Durchführung

Der Benchmark wird durch ausführen des enthaltenden RUN Skriptes gestartet. Die HTML mit den Ergebnissen wird in das Verzeichnis results geschrieben. Folgende Tests werden durchgeführt:

  • Dhrystone
  • Whetstone
  • Execl Throughput
  • File Copy
  • Pipe Throughput
  • Pipe-based Context Switching
  • Process Creation
  • Shell Scripts
  • System Call Overhead

Ergebnisse

Die folgende Tabelle enthält zur Gegenüberstellung der Pi Generationen nur den Index Score als Ergebnis.

Benchmark Run: 1 CPU; 1 parallel process

Generation System Benchmarks Index Score
RPi 1 900MHz 100
RPi 2 1000MHz 154.5
RPi 3 1200MHz 171.8

Benchmark Run: 4 CPUs; 4 parallel process

Generation System Benchmarks Index Score
RPi 1 900MHz -
RPi 2 1000MHz 266.7
RPi 3 1200MHz 361.8

sysbench

Bei sysbench handelt es sich um einen Systembenchmark bei dem verschiedene Anwendungsfälle untersucht werden können. Der Benchmark wurde in Version sysbench 0.4.12 durchgeführt und enthält folgende Tests:

  • CPU performance benchmark
  • memory operations speed test
  • file IO performance

Durchführung/Ergebnisse

Die Installation erfolgte mittels

$sudo apt-get install sysbench

CPU performance benchmark

$sysbench --test=cpu --cpu-max-prime=10000 --num-threads=1 run >cpu_single_thread.txt
$sysbench --test=cpu --cpu-max-prime=10000 --num-threads=4 run >cpu_multi_thread.txt

Maximum prime number checked in CPU test: 10000

Generation single thread 4 threads
RPi 1 900MHz 389.4594s 390.2572s
RPi 2 1000MHz 261.8984s 107.4812s
RPi 3 1200MHz 183.8759s 88.8605s

memory operations speed test

$sysbench --test=memory --memory-block-size=1M --memory-total-size=10G --num-threads=1 run >memory_single_thread.txt
$sysbench --test=memory --memory-block-size=1M --memory-total-size=10G --num-threads=4 run >memory_multi_thread.txt

Memory block size: 1024K

Memory transfer size: 2048M

Memory operations type: write Memory scope type: global

Generation single thread 4 threads
RPi 1 900MHz 4.5108s 4.5222s
RPi 2 1000MHz 1.6497s 2.0846s
RPi 3 1200MHz 1.8262s 0.9973s

file IO

ToDo: Dieser Test muss mit einer größeren file-size wiederholt werden, damit der Einfluss des RAM Cache minimiert wird.

#vor test start
$sysbench --test=fileio --file-test-mode=rndwr --file-total-size=16MB --num-threads=1 prepare 
#am testende
$sysbench --test=fileio --file-total-size=16MB cleanup

random write

$sysbench --test=fileio --file-test-mode=rndwr --file-total-size=16MB --max-requests=1000 --num-threads=1 run >random_write_single_thread.txt
$sysbench --test=fileio --file-test-mode=rndwr --file-total-size=16MB --max-requests=1000 --num-threads=4 run >random_write_multi_thread.txt
Generation single thread 4 threads
RPi 1 900MHz 145.4520s 150.9156s
RPi 2 1000MHz 133.6695s 147.7475s
RPi 3 1200MHz 135.9898s 130.1161s

random read

$sysbench --test=fileio --file-test-mode=rndrd --file-total-size=16MB --max-requests=10000 --num-threads=1 run >random_read_single_thread.txt
$sysbench --test=fileio --file-test-mode=rndrd --file-total-size=16MB --max-requests=10000 --num-threads=4 run >random_read_multi_thread.txt
Generation single thread 4 threads
RPi 1 900MHz 0.5942s 0.7321s
RPi 2 1000MHz 0.2888s 0.2670s
RPi 3 1200MHz 0.2822s 0.0835s

From File /proc/cpuinfo

Zum Abschluss noch eine Übersicht über Systeminformationen der Pi Generationen.

Raspberry Pi 1

processor   : 0
model name  : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS    : 2.57
Features    : half thumb fastmult vfp edsp java tls 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xb76
CPU revision    : 7

Hardware    : BCM2708
Revision    : 000e
Serial      : 00000000e8b7b357

Raspberry Pi 2

processor   : 0
model name  : ARMv7 Processor rev 5 (v7l)
BogoMIPS    : 38.40
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xc07
CPU revision    : 5

processor   : 1
model name  : ARMv7 Processor rev 5 (v7l)
BogoMIPS    : 38.40
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xc07
CPU revision    : 5

processor   : 2
model name  : ARMv7 Processor rev 5 (v7l)
BogoMIPS    : 38.40
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xc07
CPU revision    : 5

processor   : 3
model name  : ARMv7 Processor rev 5 (v7l)
BogoMIPS    : 38.40
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : Linux version 4.1.19-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #858 SMP Tue Mar 15 15:56:00 GMT 2016

Raspberry Pi 3

processor   : 0
model name  : ARMv7 Processor rev 4 (v7l)
BogoMIPS    : 76.80
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xd03
CPU revision    : 4

processor   : 1
model name  : ARMv7 Processor rev 4 (v7l)
BogoMIPS    : 76.80
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xd03
CPU revision    : 4

processor   : 2
model name  : ARMv7 Processor rev 4 (v7l)
BogoMIPS    : 76.80
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part    : 0xd03
CPU revision    : 4

processor   : 3
model name  : ARMv7 Processor rev 4 (v7l)
BogoMIPS    : 76.80
Features    : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 
CPU implementer : 0x41
CPU architecture: 7
CPU vLinux version 4.1.19-v7+ (dc4@dc4-XPS13-9333) (gcc version 4.9.3 (crosstool-NG crosstool-ng-1.22.0-88-g8460611) ) #858 SMP Tue Mar 15 15:56:00 GMT 2016

Dienstag, 12. April 2016

Raspberry Pi Bootperformance - Ein Vergleich der Generationen

Zielstellung

Vergleich der Bootperformance eines Raspberry Pi 1 im Vergleich zur 2. und 3. Generation.

Rahmenbedingungen

Für den Test wurde ein raspbian-jessie-lite vom 18.03.2016 verwendet. Dieses wurde auf eine 8GB SanDisk mSDHC geflasht. Für alle drei Pi Generationen wurde die selbe Karte verwendet, beim RPi 1 wurde zusätzlich der SanDisk Adapter benötigt. Als Tool zur Zeitmessung wurde systemd-analyze (siehe Tools zur Bootanalyse) genutzt. Gemessen wurde die Zeit zwischen Anschluss der Spannungsversorgung und dem login prompt auf der Kommandozeile.

Durchführung

Die Bootperformance habe ich wie folgt gemessen:
  • Die mSDHC wurde in das Raspberry Pi gesteckt und das Board durch Zuführung der Spannungsversorgung gestartet.
  • Jetzt habe ich für die einzelnen Versuche die CPU Clocks in der /boot/config.txt konfiguriert.
  • Wie unter Tools zur Bootanalyse beschrieben, wurde bootchart installiert. Dieser Dienst hat natürlich (minimalen) Einfluss auf die Bootzeit des Systems.
  • Anschließend wurde das Board mit
$ sudo shutdown -h now
ausgeschaltet und durch einem Power Cycle neugestartet.
  • Nachdem der Login Prompt erscheint, wurde sich angemeldet und die Bootgrafiken mit
$ bootchart
$ systemd-analyze plot >systemd.svg
erzeugt.
  • Als Bootzeit wurde die Summe aus kernel + userspace (siehe systemd-analyze plot) in Sekunden der drei Generationen gegenübergestellt.
  • Anschließend wurde der Test für eine weitere Clock Konfiguration wiederholt. Die Ergebnisse wurden durch mehrfache Durchführung validiert.

Ergebnis

Die folgenden Tabellen enthält die Bootzeiten der drei RPi Generationen für verschiedene Konfigurationen.
SUMME
Raspberry Pi 700MHz 800MHz 900MHz 1000MHz 1200MHz 1200MHz BT disabled
RPi 1 21.848s (1) 18.540s 18.117s - - -
RPi 2 - - 11.068s (1) 8.813s - -
RPi 3 - - - - 13.482s 8.332s
kernel
Raspberry Pi 700MHz 800MHz 900MHz 1000MHz 1200MHz 1200MHz BT disabled
RPi 1 4.147s (1) 2.732s 2.732s - - -
RPi 2 - - 3.043s (1) 2.528s - -
RPi 3 - - - - 2.978s 2.971s
userspace
Raspberry Pi 700MHz 800MHz 900MHz 1000MHz 1200MHz 1200MHz BT disabled
RPi 1 17.701s(1) 15.808s 15.393s - - -
RPi 2 - - 8.025s (1) 6.285s - -
RPi 3 - - - - 10.504s 5.361s
(1) default Einstellung in /boot/config.txt
Hier ein Auszug aus dieser Konfigurationsdatei, mit den Stellen wo die CPU Clock eingetragen werden kann.
[pi1]
#Frequency of the ARM CPU in MHz.
arm_freq=900
[pi2]
#Frequency of the ARM CPU in MHz.
arm_freq=1000
[pi3]
#Frequency of the ARM CPU in MHz.
arm_freq=1200

Interpretation und Optimierung

Wie man den Tabellen entnehmen kann, ist Generationsübergreifend die CPU Clock ein wesentlicher Faktor zur Reduzierung der Bootzeit. Ein weiterer Faktor ist die Multicore Architektur (ab RPi2) in Kombination mit der ARMv7 Architektur (ebenfalls im RPi2). Dies wird besonders in der Gegenüberstellung RPi1 und RPi2 für 900MHz deutlich.
Auf den ersten Blick sehr erstaunlich ist, dass das RPi3 trotz 1200MHz langsamer bootet (~4.4s) als das RPi2. Durch Analyse der systemd-analyze Ausgabe wird ersichtlich, dass die Ursache im hciuart.service liegt. Dieser initialisiert beim Start das im RPi3 enthaltende Bluetooth Modul. Wird dieser Service durch
sudo systemctl disable hciuart.service 
deaktiviert, bootet der RPi3 (etwas) schneller als der RPi2. Das der Unterschied nicht größer Ausfällt liegt vermutlich daran, dass nicht die Geschwindigkeit der CPU, sondern die Bandbreite der SD-Card Schnittstelle der begrenzende Faktor ist. Gestützt wird diese Vermutung auch durch folgenden Auszug der zugehörigen bootchart Grafik:

Powered by Pelican. Theme blueidea, inspired by the default theme.

Samstag, 9. April 2016

Tools zur Bootanalyse

Auf dieser Seite möchte einige Tools dokumentieren, mit denen der Bootvorgang eines Linux Systems detailiert analysiert werden kann.

1. Bootchart

Bootchart ist ein Tool zur Analyse und Visualisierung der Performance des Linux boot processes. Die Analyse basiert darauf, dass während des Bootens zusätzliche Informationen gesammelt werden und diese anschließend ausgewertet werden können. So kann aus den Logfiles ein Zeitdiagram des Bootprozesses erzeugt werden.

Installation

Um das Tool nutzen zu können, muss dieses zunächst über den Paketmanager installiert werden.
$ sudo apt-get install bootchart

Einrichtung

Anschließend muss der bootchart daemon so eingerichtet werden, dass dieser beim init gestartet wird. Dies ist notwendig, um die benötigten Informationen beim Booten zu sammeln. Diese werden im RAM gehalten und nach Beendigung des Bootvorgangs gespeichert. Dazu muss wie folgt die Kernel command line angepasst werden.
#add init=/sbin/bootchartd add end of line
$ sudo vi /boot/cmdline.txt

Analyse Ablauf

  • Als Erstes muss wie beschrieben bootchart installiert und eingerichtet werden.
  • Anschließend muss ein System - Neustart durchgeführt werden. (z.b. per reboot oder via power cycle)
$ sudo shutdown -h now
# Power cycle durchführen
  • Nachdem das System erneut gebootet hat, sollte zuerst geprüft werden, ob bootchart eine Logdatei (/var/log/bootchart.tgz) angelegt hat.
  • Wenn diese Logdatei angelegt wurde, kann aus dieser wie folgt ein Chart generiert werden, das Bild liegt anschließend im aktuellen Verzeichnis. Das default Format ist svg.
$ bootchart
  • Jetz kann man sich das Bild anzeigen lassen und mit der Analyse beginnen.
Anbei ein Beispiel für das Raspberry Pi 3 mit raspbian-jessie-lite in der Version vom 18.03.2016.

2. systemd-analyze

Für Systeme welche mit systemd beim Booten gestartet werden, kann das bei systemd enthaltene Analyse Tool benutzt werden. Dieses erzeugt aus den beim Bootvorgang erstellten Logfiles eine Grafik, welche anschließend analysiert werden kann.

Einrichtung

Für die Einrichtung muss im Normalfall nichts unternommen werden. Wenn das System auf systemd basiert, sollte systemd-analyze bereits installiert sein.

Analyse Ablauf

  • Als erstes muss ein System - Neustart durchgeführt werden. (z.b. per reboot oder via power cycle)
$ sudo shutdown -h now
# Power cycle durchführen
  • Nachdem das System gebootet hat, kann die grafische Darstellung des Bootvorgangs mit systemd, wie folgt erstellt werden.
$systemd-analyze plot >systemd.svg
  • Jetz kann man sich das Bild anzeigen lassen und mit der Analyse beginnen.
Anbei ein Beispiel für das Raspberry Pi 3 mit raspbian-jessie-lite in der Version vom 18.03.2016.