Hlavní navigace

Raspberry Pi 4B: 64bit či nebýt – to je otázka

Jan Fikar

V minulém článku jsme představili novou verzi populárního jednodeskového počítače Raspberry Pi 4B a také instalaci nové verze distribuce Raspbian Buster. V pokračování se dostaneme do větší hloubky.

Doba čtení: 10 minut

Sdílet

minulém článku jsme představili novou Raspberry Pi 4B a nový Raspbian Buster. Porovnali jsme novou malinu se starším modelem a vyřešili některé problémy. V dnešním pokračování se dostaneme zase o kousek dále.

32 bitů či 64 bitů?

Když před sedmi lety vyšla první Raspberry Pi, obsahovala jednojádrový 32bitový procesor ARM1176JZF-S z rodiny ARM11, který má architekturu ARMv6Z. Stejný procesor je také ve stále prodávané Raspberry Pi Zero. Raspberry Pi 2 pak obsahovalo stále 32bitový Cortex-A7 s architekturou ARMv7-A.

Raspberry Pi 3 uvedené v roce 2016 přineslo již 64bitový procesor Cortex-A53 s architekturou ARMv8-A a stejně i nová Raspberry Pi 4 má 64bitový procesor Cortex-A72 se stejnou architekturou. Raspberry Pi Foundation se svým Raspbianem přitom chce podporovat všechny maliny, proto je zatím operační systém Raspbian pouze 32bitový.

Když ale nakouknete do /boot, najdete tam kernel.img pro Raspberry Pi Zero, 1 a 2, kernel7.img pro Raspberry Pi 3 a kernel7l.img pro Raspberry Pi 4 s LPAE kvůli adresaci více než 2 GB RAM. Také proto byla nedávno doporučena změna velikosti oddílu /boot ze 40 MB na 256 MB.

Raspberry Pi Foundation stejně směřuje k 64bitovému Raspbianu, jen zatím neříká, kdy k tomu dojde. Pokud si ještě pamatujete přechod ze 32 bitů na 64 na architektuře x86, tak přechod byl doprovázen výrazným zvýšením výkonu. Důvodem bylo velmi málo registrů architektury x86 (jen osm 32bitových registrů), které bylo zvýšeno v x86_64 na šestnáct 64bitových registrů. Ve skutečnosti je registrů v procesoru víc a ten s nimi dělá různá kouzla kvůli zvýšení výkonu. Například aktuální architektura AMD Zen2 má interně sto osmdesát 64bitových registrů, oproti Zen, který má sto šedesát osm 64bitových registrů. Kompilátor si však musí vystačit jen s dostupnými registry dané architektury.

Oproti tomu procesory ARM mají v 32bitech patnáct 32bitových registrů a v 64bitech jednatřicet 64bitových registrů, tedy víc, než x86. Proto se při přechodu z 32 bitů na 64 na procesorech ARM nedá očekávat takové zrychlení, jaké si pamatujeme z přechodu na x86. K tomu procesory ARM mají menší vyrovnávací paměti (cache), na které nepříznivě působí zvětšení kódu při přechodu z 32 na 64 bitů.

Jádro

Co tedy potřebujeme, aby nám Raspberry Pi 3 nebo 4 běželo na 64bitech? Nejprve je třeba jádro. V podstatě stačí překompilovat oficiální jádro pro novou architekturu arm64, taktéž zvanou aarch64. Pokud si to chcete zkusit, je tu pěkný a podrobný návod od Andreie Gherzana. Potřebujete nejprve cross-kompilátor, který běží na arm a kompiluje pro aarch64. Mimochodem, v té době nebylo možné na Raspberry Pi 4 používat více než 1 GB RAM kvůli kolizi s ovladačem USB 3. Tato chyba je již opravena a paměť lze používat celou.

Druhá možnost je použít experimentální 64bitové jádro přímo od Raspberry Pi Foundation. S posledními aktualizacemi totiž najdete v /boot  i soubor kernel8.img. Jádro je zatím experimentální a určené pro Raspberry Pi 4, i když může fungovat i na Raspberry Pi 3.

Poslední, a asi zatím asi nejlepší, možností jsou pravidelně předkompilovaná jádra zvlášť pro Raspberry Pi 3 a Raspberry Pi 4 od vývojářky Sakaki. Výhodou je, že jádra -bis mají oproti oficiálnímu jádru navíc zkompilované různé užitečné vlastnosti. Například virtualizaci KVM, komprimovaný SWAP, BFP pro firewall a BTRFS kompilované ne jako modul, proto může být oddíl /  na souborovém systému BTRFS.

Takže nějaké 64bitové jádro máme v /boot, jak nyní jádra mezi sebou přepínat? Celkem jednoduše, napíšeme do /boot/config.txt arm_64bit=1, případně přímo můžeme označit i jméno souboru, například pomocí kernel=kernel8-p3.img. Toto jméno používá Sakaki, aby se nepletlo jádro pro Pi 3 s jádrem pro Pi 4.

Když nabootujeme 64bitové jádro, můžeme klidně dál používat 32bitový user-space, například stávající Raspbian. Otestovat výkon nového jádra můžeme třeba pomocí šifry AES. Malá poznámka: bohužel ani Raspberry Pi 3 ani Raspberry Pi 4 nemají volitelné rozšíření crypto, proto je jádrem použit alespoň pomocí instrukcí NEON (povinné SIMD rozšíření ARMv8) zrychlený algoritmus AES.

cryptsetup benchmark -c aes-xts-plain64 -s 256
cryptsetup benchmark -c aes-xts-plain64 -s 512
Raspberry Pi 4 rychlost AES [MB/s]
klíč 32 bit encrypt 32 bit decrypt 64 bit encrypt 64 bit decrypt
256 86 75 88 78
512 66 57 67 59
Raspberry Pi 3B+ rychlost AES [MB/s]
klíč 32 bit encrypt 32 bit decrypt 64b encrypt 64 bit decrypt
256 65 56 64 58
512 49 42 49 44

Lehké zvýšení rychlosti tedy vidíme, ale není to nic světoborného.

User-space

Jádro tedy už máme, jak je to nyní s 64bitovým user-space? Existuje několik možností. Nejjednodušší je použít chroot v Raspbianu a do něj nainstalovat například Debian arm64. Použijeme k tomu schrootdebootstrap.

sudo apt install -y debootstrap schroot
cat << EOF | sudo tee /etc/schroot/chroot.d/pi64
[pi64]
description=VC4 arm64 testing
type=directory
directory=/srv/chroot/pi64
users=pi
root-groups=root
profile=desktop
personality=linux
preserve-environment=true EOF sudo debootstrap --arch arm64 /srv/chroot/pi64 sudo schroot -c pi64 -- apt install -y sudo
schroot -c pi64 -- chmod a+w /dev/shm
schroot -c pi64

Tímto postupem dostaneme funkční chroot s aktuálním arm64 Debianem a přitom nám zůstanou všechny užitečné nástroje pro Raspberry Pi, které v sobě obsahuje Raspbian. Do chrootu se kdykoli dostanete posledním příkazem. Dále je možné využít nějaké formy virtualizace například KVM (výhoda jader od Sakaki) nebo kontejnery systemd-nspawn a LXC.

Další možností je použít například obrazy Ubuntu pro arm64.  Poslední možností je Gentoo 64 bit pro Raspberry Pi 3 a 4 od již několikrát zmíněné Sakaki. Obrazy v tomto případě obsahují i přímo 64bitová jádra, včetně aktualizačního mechanizmu, kdy výchozí je instalace předkompilovaných balíčků a nemusíte tedy malinu trápit dlouhým překladem. Obraz lite je podobně jako u Raspbianu určen k minimální instalaci například serveru bez desktopu.

Šifry

Takže máme jádro i user-space v 64 bitech, jak je to teď rychlé? Zkusme otestovat šifry v user-space. Nejprve třeba ssh, výchozí šifra je rychlá chacha20-poly1305@openssh.com, vyzkoušíme také aes256-gcm@openssh.com. Komprese je ve výchozím stavu vypnuta. Obě maliny mají čtyři jádra, my zatížíme dvě. Jedno bude posílat a druhé přijímat.

dd if=/dev/zero bs=1M count=4096 status=progress | ssh -c $sifra localhost  'cat > /dev/zero'
Raspberry Pi 4B výkon ssh [MB/s]
šifra 32 bit 64 bit
chacha 52,9 51,9
aes 27,7 20,5
Raspberry Pi 3B+ výkon ssh [MB/s]
šifra 32 bit 64 bit
chacha 27,0 27,4
aes 19,3 19,9

Výsledky vypadají velmi podobně, u Raspberry Pi 4 překvapivě poklesne výkon AES při přechodu z 32 na 64 bitů. Podíváme se raději přímo na výkon šifer v OpenSSL.

openssl speed -evp chacha20-poly1305
openssl speed -evp aes-256-gcm
Raspberry Pi 4B výkon openssl [MB/s]
šifra 32 bit 64 bit
chacha 138,2 266,4
aes 32,3 23,5
Raspberry Pi 3B₊ výkon openssl [MB/s]
šifra 32 bit 64 bit
chacha 96,0 221,3
aes 24,3 25,8

Tady je situace podobná, chacha je na 64 bitech rychlejší, ale AES ne. Za tuto zvláštnost může Debian, který nepoužívá v OpenSSL rychlý algoritmus AES, protože je potenciálně méně bezpečný a používá místo něj pomalejší variantu. Naopak Raspbian používá rychlý algoritmus. V Debianu lze chování v případě AES přepnout systémovou proměnnou OPENSSL_armcap=0, (to by kupodivu mělo vypínat instrukce NEON). Tak sice zrychlíme AES, ale zpomalíme chacha. V Raspbianu nemá tato proměnná žádný vliv.

Raspberry Pi 4B výkon ssh [MB/s] s OPENSSL_armcap=0
šifra 32 bit 64 bit
chacha 52,9 51,5
aes 27,7 27,5
Raspberry Pi 4B výkon openssl [MB/s] s OPENSSL_armcap=0
šifra 32 bit 64 bit
chacha 138,2 139,5
aes 32,3 37,5

Komprese

Větší počet registrů by mohl mít pozitivní vliv na kompresi. Přitom velikost cache naopak vliv bude mít malý, protože dat je velké množství. Zkusme třeba kompresi pomocí zstd ve vysokém stupni na zdrojových kódech jádra. V obou případech je použito zstd ve verzi 1.3.8.

time zstd -q -19 -T $(ncpu) linux-4.19.tar
Čas komprese v sekundách
32 bit 64 bit
RPi 4 478,6 423,7
RPi 3+ 728,4 667,1

Výkon tedy v 64 bitech vzroste o 9 – 13 % oproti 32 bitům. Pro zajímavost velikost programu zstd vzroste z 628 kB jen na 632 kB. Pro srovnání stejná úloha trvá na Intel Core i5–2520M (dvě jádra, 2,5 GHz) 246,3 sekund.

Linpak 64bit

Výkon malin jsme v minulém díle testovali pomocí HPL, teď se podíváme, jaký bude výkon v 64 bitech. Místo OpenBLAS použijeme knihovnu blis 0.6.0. OpenBLAS má na malině v 64 bitech trochu problémy a i po jejich vyřešení je pomalejší než blis. Knihovnu blis kompilujeme jednoduše pro Cortex-A57, výsledek jede jak na Cortex-A72 (RPi4) tak i na Cortex-A53 (RPi3)

./configure -t openmp -p /home/pi/blis cortexa57
make -j4
make check
make install

Podobně jako minule smažeme v /home/pi/blis/lib  soubory *.so, abychom linkovali knihovnu staticky. Navíc je potřeba udělat ln -s libblis.a libblas.a, protože HPL knihovnu blis nezná, ale libblas si rádo přilinkuje. HPL 2.3 poté kompilujeme obdobně jako minule (ani minule nebylo potřeba specifikovat CPPFLAGS)

LDFLAGS='-L/home/demouser/blis/lib -fopenmp -lm' ./configure
make -j4

Pro RPi3 použijeme velikost problému Ns 10000 a pro RPi4 20000. Výsledek pro 64 bitů nejvíce záleží na parametru NBs, což je velikost bloků, do kterých se úloha rozdělí. V souboru HPL.dat můžeme specifikovat více velikostí a najít tak nejvhodnější NBs s největším výkonem. Na ostatních parametrech výkon tolik nezáleží.

HPLinpack benchmark input file
Innovative Computing Laboratory, University of Tennessee
HPL.out     output file name (if any)
6           device out (6=stdout,7=stderr,file)
1           # of problems sizes (N)
20000       Ns
15          # of NBs
32 48 64 80 96 112 128 144 160 176 192 208 224 240 256         NBs
0           PMAP process mapping (0=Row-,1=Column-major)
1           # of process grids (P x Q)
1           Ps
1           Qs
16.0        threshold
1           # of panel fact
1           PFACTs (0=left, 1=Crout, 2=Right)
1           # of recursive stopping criterium
4           NBMINs (>= 1)
1           # of panels in recursion
2           NDIVs
1           # of recursive panel fact.
2           RFACTs (0=left, 1=Crout, 2=Right)
1           # of broadcast
0           BCASTs (0=1rg,1=1rM,2=2rg,3=2rM,4=Lng,5=LnM)
1           # of lookahead depth
0           DEPTHs (>=0)
2           SWAP (0=bin-exch,1=long,2=mix)
8           swapping threshold
0           L1 in (0=transposed,1=no-transposed) form
0           U  in (0=transposed,1=no-transposed) form
1           Equilibration (0=no,1=yes)
8           memory alignment in double (> 0)

Ještě jeden rozdíl tu je oproti verzi s OpenBLAS, která sama automaticky najde počet jader na kterých se pustí. Pro verzi s blis to musíme určit ručně přes proměnnou OMP_NUM_THREADS=4 nebo  BLIS_NUM_THREADS=4.

Výkon HPL [GFlops]
Ns optimální NBs 32 bit 64 bit
RPi 4B 20000 208 11,0 16,3
RPi 3B+ 10000 176 6,7 6,7

Vidíme, že v případě RPi 3 nedošlo k zvýšení výkonu, pravděpodobně kvůli velikosti cache. RPi 4 pak má cache o něco větší a zde pozorujeme malý nárůst.

Minule jsem zapomněl zmínit, že HPL je také dobrý test stability a opravdu jej některé RPi 3B a 3B+ občas nezvládnou a na závěr uvidíte FAILED. Není to způsobené teplotou ani zdrojem, ale zřejmě malou tolerancí napájení CPU. Jednoduché a mírné over_voltage=2 v /boot/config.txt  problém řeší. Jedna moje RPi 3B+ tento problém měla a druhá ne. Asi se to liší kus od kusu. RPi 4 by tímto problémem trpět neměly. Moje netrpí.

Rychlost SD karty A1 vs. A2

V minulém článku jsme testovali kartu SanDisk MicroSDXC 64GB Extreme A2 a zmínili jsme, že levnější varianta A1 má patrně lepší výkon. Kartu jsem koupil a přeměřil stejnou metodou a zde jsou výsledky

Rychlost SD Karty A1
sekvenční čtení
MB/s
sekvenční zápis
MB/s
náhodné čtení
MB/s
náhodný zápis
MB/s
náhodné čtení
IOPS
RPi 4 44,0 25,2 8,94 3,88 2310
RPi 3 22,6 19,4 7,37 3,57 1880
RPi 3 přetaktovaná 37,3 21,1 8,70 3,57 2170
Rychlost SD karty A2
sekvenční čtení
MB/s
sekvenční zápis
MB/s
náhodné čtení
MB/s
náhodný zápis
MB/s
náhodné čtení
IOPS
RPi 4 43,8 31,8 6,05 3,16 2050
RPi 3+ 22,7 20,4 5,43 3,28 1730
RPi 3+ přetaktovaná 37,0 23,2 6,11 3,31 1950

I když je v sekvenčním zápisu karta A2 rychlejší, zaostává v náhodném zápisu i v náhodném čtení a pro Raspberry Pi jsou zatím vhodnější levnější karty A1.

Firmware

Raspberry Pi 4 má nový způsob aktualizace firmware. Jestli používáte Raspbian, tak se vám pravděpodobně sám nainstaloval program rpi-eeprom-update. Tím můžete lehce aktualizovat bootloader a firmware USB 3 čipu VL805 (minule zmiňovaná aktualizace, která snižuje spotřebu). Nyní stačí udělat:

# sudo rpi-eeprom-update -a
BOOTLOADER: up-to-date
CURRENT: Tue 10 Sep 2019 10:41:50 AM UTC (1568112110)
 LATEST: Tue 10 Sep 2019 10:41:50 AM UTC (1568112110)
VL805: up-to-date
CURRENT: 000137ab
 LATEST: 000137ab

Nový bootloader by měl umět boot ze sítě (zatím beta). Boot z USB bude následovat. Nový firmware pro VL805 má také nižší spotřebu a navíc nevykazuje problémy s rychlostí USB 3, jako minule zmiňovaná verze. Program rpi-eeprom-update budete mít i na RPi 3 a starších, tam však nebude dělat nic.

Vypnutí signálu HDMI

Trochu překvapivě nefunguje u Raspberry Pi 4 vypnutí signálu HDMI, tedy usnutí monitoru. Místo toho jde ven pořád signál s černou obrazovkou. Vše funguje jak má u Raspberry Pi 3B+ a starších. Problém snad bude brzy vyřešen.

On the Raspberry Pi 4, setting hdmi_blanking=1 will not cause the HDMI output to be switched off, since this feature has not yet been implemented.