Pi önyüklemesini uç noktada optimize etmek
(kittenlabs.de)- SolarCamPi, yalnızca fotoğraf çekerken Raspberry Pi Zero 2 W’yi açıp sonra kapatan şebekeden bağımsız güneş enerjili bir kamera olduğu için, önyükleme süresinin kendisi pil ömrünü belirliyor
- Debian 12 arm64 Lite temelinde
/init.shilk kullanıcı alanı kodu olarak ölçüldüğünde, ilk önyükleme yaklaşık 12 saniye ve 9,5Ws tüketiyor - HDMI, LED, HAT/PoE/LCD, kamera ve ekran otomatik algılama ile initramfs azaltılarak gereksiz beklemeler ve algılamalar kaldırıldı; akım 136,7mA → 120,6mA seviyesine düştü
- Buildroot 2024.02.1 ve özel bir çekirdeğe geçildikten sonra sürücüler, sıkıştırma, KASLR ve bazı mitigasyonlar kaldırılarak Linux kullanıcı alanı programına 3,5 saniyenin altında ulaşıldı
- Giriş voltajı 5,0V’tan 3,6V’a düşürüldüğünde toplam enerji 1,754Ws → 1,438Ws azaldı; ancak bu spesifikasyon dışı çalışma olduğu için kararlılık ve güvenilirlik doğrulaması hâlâ gerekiyor
SolarCamPi’nin önyükleme süresini neden azaltması gerekiyordu
- SolarCamPi, Raspberry Pi Zero 2 W’yi periyodik olarak başlatıp fotoğraf çeken, bunları WiFi üzerinden bir bulut servisine yükleyen ve ardından tekrar kapanan güneş enerjili bir WiFi kamerası
- Batı Avrupa kışı gibi enerjinin kısıtlı olduğu ortamlarda Pi’nin açık kaldığı her saniye doğrudan enerji maliyeti anlamına geliyor
- Kullanıcı alanı uygulamasının sunucuya bağlanması ve fotoğraf yüklemesi zaten mümkün olduğunca optimize edilmişti; elektronik devreler de uyku sırasında gücü azaltacak şekilde tasarlanmıştı
- Geriye iki tasarruf yolu kalmıştı
- Tüketilen akımı azaltmak
- Çalışma süresini azaltmak
- Yalnızca akımı düşürmek her zaman kazanç sağlamaz
- CPU turbo kapatıldığında akım azalsa bile çalışma süresi uzarsa toplam enerji aksine artabilir
- Hedef, akım-zaman grafiğinin altında kalan alanı en aza indirmektir
Ölçüm ekipmanı ve test yöntemi
- Gömülü önyükleme optimizasyonunda değişiklikten sonra gerçek çalışmayı hızlıca doğrulamak gerektiğinden, SD kartı çıkarıp takmayı ve güç işlemlerini azaltan araçlar önemlidir
- Kullanılan ekipmanlar şunlardı
- Nordic Power Profiler Kit II
- USB-SD-Mux Fast
- USB-UART dönüştürücü
- Power Profiler Kit II, test edilen cihaza güç verirken zamana göre güç tüketimini ve 8 dijital girişin durumunu birlikte ölçer
- Raspberry Pi’nin GPIO pinleri dijital girişlere bağlanır
- Uygulamanın ilk eylemi olarak GPIO toggle edilerek güç verilmesinden kullanıcı alanı kodunun çalışmasına kadar geçen süre ölçülür
- USB-SD-Mux, microSD kart ile cihaz arasına giren bir interposer’dır; bilgisayarın kartı alıp içeriğini yeniden yazmasına ve sonra cihaza geri vermesine olanak tanır
- Kartı çıkarıp okuyucuya takma ve ardından tekrar cihaza yerleştirme döngüsünü ortadan kaldırır
- Yerleşik GPIO ile test edilen hedefin reset’i veya güç kontrolü de otomatikleştirilebilir
- USB-UART konsolu, önyükleme hatası veya WiFi sorunu gibi sistem bozulduğunda durumu kontrol etmek için gereklidir
Debian temelinde önyükleme ölçümü
- Temiz bir Debian 12 bookworm arm64 Lite imajında
/boot/firmware/cmdline.txtdosyasınainit=/init.sheklendi - Bu ayar, çekirdeğin systemd’den önce
/init.shdosyasını kullanıcı alanının ilk süreci olarak çalıştırmasını sağlar - Örnek
init.sh, GPIO4’ü toggle ettikten sonraexec /sbin/initile systemd önyüklemesini sürdürür - İlk ölçümde yaklaşık 12 saniye sonra dijital giriş 0’ın low olduğu ve
init.shçalışmasının doğrulandığı görüldü - Bu önyükleme süreci toplam 1,90 coulomb kullandı
1.9As * 5.0V = 9.5Ws- Bir AA alkalin pil yaklaşık 13500Ws enerji sağlayabilir
Tüketilen akımı azaltmak
- HDMI encoder tamamen devre dışı bırakılınca akım 136,7mA’dan 122,6mA’ya düştü
- Kamera verilerinin encode edilmesi gerektiğinden GPU’nun kendisi kapatılamadı
- Kamera veya GPU gerektirmeyen uygulamalarda GPU’yu devre dışı bırakmak da denenebilir
- Yalnızca activity LED’i devre dışı bırakmak 2mA tasarruf sağlayarak akımı 122,6mA’dan 120,6mA’ya indirdi
- Kamera LED’i varsa devre dışı bırakılabilir
- LED’in görüntüye yansıma olasılığı da azalır
- Turbo ayarı değişiklik testlerinde, mevcut değişiklikler uygulanmış Pi 1,62As kullandı
- Zorunlu turbo olmadan çalıştırıldığında 1,58As kullandı
- Bilinmeyen bir nedenle turbo/boost modu kapatıldığında GPIO4’ün varsayılan durumu tersine döndüğü için
init.shiçinde polarite değiştirildi
Önyükleme süresini azaltmak
- Akım yaklaşık %13 azalmış olsa da Linux’un ilk çıktısı konsolda görünene kadar hâlâ yaklaşık 8 saniye sürüyordu ve bu aralıkta yaklaşık 1As tüketiliyordu
- Raspberry Pi ailesinde önce GPU ilklendirilir
- GPU, SD kartta
bootcode.bindosyasını arar - Pi 4 ve sonrası EEPROM kullanır
- GPU, SD kartta
bootcode.biniçindekiBOOT_UARTaçılırsa ayrıntılı UART logları görülebilir- Orijinal
bootcode.binyedeği gerekir ve değiştirme süreci potansiyel olarak yıkıcıdır
- Orijinal
- Önyükleyici, bağlı HDMI monitörün video parametrelerini otomatik algılamak için EDID yanıtını bekler
- HDMI kullanılmadığından, algılamadan kaçınmak için EDID dizesi sabit kodlandı
- HAT, PoE fanı, LCD ve dokunmatik ekranla ilgili I2C EEPROM algılamaları da devre dışı bırakıldı
- Bu seçenekler I2C bus yanıtını beklediği için gerekli değilse kapatılabilir
- MIPI kamera ve ekran otomatik algılaması da zaman harcar
- Kullanılan kameranın HQ Camera IMX477 olduğu belli olduğundan
camera_auto_detect=0,display_auto_detect=0ile kapatıldı vedtoverlay=imx477doğrudan yüklendi
- Kullanılan kameranın HQ Camera IMX477 olduğu belli olduğundan
- Bu değişikliklerle kendi raporladığı önyükleme süresi 5,38 saniyeden 4,75 saniyeye düştü;
auto_initramfs=1kaldırılarak initramfs kapatıldığında 4,47 saniyeye indi - SD çevre birimini 100MHz’e overclock eden
sdtweakyöntemi ölçülebilir bir önyükleme performansı farkı yaratmadı- Yazma erişiminde veri bozulması riski olduğundan uzak IoT cihazları için tercih edilir değildir
Çekirdek yükleme darboğazı ve Buildroot’a geçiş
- Bu noktada çekirdek yükleme en yavaş işlerden biriydi
kernel8.imgdosyasının 9.276.375 baytını yüklemek yaklaşık 1,54 saniye sürdü- Aktarım hızı yaklaşık 6MiB/s idi
- Çekirdek yükleme, dahili ve kapalı kaynaklı VideoCore IV işlemcisini kullanan GPU tarafından yapılır
- Loader kodunun verimsiz olması veya muhafazakâr ayarlar kullanması mümkün olsa da kara kutu olduğundan register veya parametreleri faydalı biçimde ayarlamak mümkün olmadı
- GPU işlemci çekirdeğini overclock etmek teorik olarak mümkündü ve çekirdek yükleme süresini %20 azalttı
- Güvenilirlik gibi yan etkiler bilinmediği için önerilmez
- Sistem Raspbian/Debian’dan Buildroot 2024.02.1 tabanlı özel bir dağıtıma taşındı
- native aarch64 toolchain kullanımı
- glibc ve Raspberry Pi userland araçları korundu
- Özel çekirdekte şunlar kaldırıldı veya azaltıldı
- Ses desteği
- SD/MMC ve ext4 korunarak blok cihazı ve dosya sistemi sürücülerinin çoğu
- RAID, USB, HID, DVB
- Video ve framebuffer desteği
- Tünelleme, bridging, firewall gibi gelişmiş ağ özellikleri
- Gzip çekirdek sıkıştırması ve modül sıkıştırması
- Hem çekirdeği hem de modülleri sıkıştırmasız kullanmak, GPU daha uzun süre yükleme yapsa bile toplam enerji açısından avantajlıydı
- Gzip açma işlemi çok enerji harcar ve fiilen ek bir relocation adımı içerir
- KASLR da devre dışı bırakıldı
- KASLR, exploit yazmayı zorlaştırmak için çekirdeğin belleğe yüklendiği adresi rastgeleleştirir; ancak GPU yüklemesinden sonra çekirdeğin yeniden konumlandırılması gerekir
- Bu kullanım senaryosunda ağ saldırı yüzeyi çok sınırlı ve uygulama yazılımlarının tamamı root olarak çalışıyor
- Spectre gibi spekülatif yürütme açıklarına yönelik mitigasyonlar da devre dışı bırakıldı
- Sonuçta çekirdek boyutu 8,5MiB sıkıştırmasız oldu; karşılaştırma için Gzip sıkıştırmalı boyut 4,1MiB idi
- Orijinal Raspbian çekirdeği 25MiB sıkıştırmasız, 8,9MiB Gzip sıkıştırmalıydı
Nihai sonuç ve giriş voltajı optimizasyonu
- Sonuçta Linux kullanıcı alanı programına 3,5 saniyenin altında ulaşıldı
- Linux çekirdeği içinde geçen süre yaklaşık 400ms idi
- Toplam enerji tüketimi 0.364As * 5.0V = 1.82Ws oldu
- stock Debian’ın kullanıcı alanına ulaşma enerjisi olan 9,5Ws ile karşılaştırıldığında yaklaşık beşte bir seviyesinde
- Yayından sonra Graham Sutherland / Polynomial, Pi Zero’nun regülatörünün 5,0V girişte verimli olmadığını belirtti
- Test senaryosunda ve bitmiş üründe giriş voltajı 4,0V seviyesine kadar düşürülebildi
- 5.0V:
350.94mAs * 5.0V = 1.754Ws - 4.0V:
390.77mAs * 4.0V = 1.563Ws - 3.6V:
399.60mAs * 3.6V = 1.438Ws
- 5.0V:
- Voltaj düşürüldüğünde mC, yani mAs, akım artışı nedeniyle yükselir; ancak toplam enerji belirgin şekilde azalır
- 3,6V çalışma, switching regülatörü daha ideal bir çalışma noktasında kullanarak enerjiyi yaklaşık %20 daha azalttı; ancak teknik olarak spesifikasyon dışı olduğundan kararlılık ve güvenilirlik doğrulaması için daha fazla çalışma gerekiyor
Açık ayarlar ve kod
- SolarCamPi config.txt: tam
config.txt - SolarCamPi Linux kernel defconfig: küçültülmüş çekirdek yapılandırması
- SolarCamPi-Buildroot v2 branch: tüm Buildroot ağacı; çalışma devam ediyor
1 yorum
Hacker News yorumları
Raspberry Pi ailesinin güç yönetimi kesinlikle zayıf yönlerinden biri. Bu yüzden yeni Pico 2 heyecan verici; çünkü harici donanım olmadan da görece derin uyku durumlarına girmeyi kolaylaştırmış gibi görünüyor.
Benzer amaçlı bir kamerayı Google Coral mini ile yapmıştım; kamera HQ cam kadar iyi değil ama dahili RTC ile bekleme/uyandırmayı çok kolay desteklediği için periyodik çekim yapan uygulamalar için biçilmiş kaftandı. Yüksek çözünürlüklü görüntüleri işleyecek kadar performansı ve 2 GB belleği de vardı.
HQ camera fiziksel olarak bağlanabiliyor ama bildiğim kadarıyla Coral tarafında bunu yönetecek bir yazılım hattı yok.
Raspberry Pi ekosistemi çok daha olgun ve Google’ın Coral serisini tedarik etmeye devam edeceğine kıyasla Raspberry Pi’nin gelecekte bulunabilirliğine daha çok güveniyorum. Yine de donanımda iyi güç desteğinin ne kadar faydalı olduğunu net biçimde gördüm.
İronik biçimde kameranın sonraki sürümünü bir dış yüklenici Raspberry Pi ile yaptı ve güç sorununu çok daha büyük bir pil koyarak telafi etti. Bu yüzden elimde hâlâ kutusu açılmamış 100 adet Coral dev mini ve kamera var; ya iyi bir fikir bulmam ya da bunları satmam gerekiyor.
Resmî Twitter hesabını bulmak için "google coral twitter" diye arattığımda ikinci sonucun, elindeki 100 fazla kartı satmaya çalışan senin tweet’in çıkması şaşırtıcı.
Gücü harici donanımla yönettiğini söylemiş olman, bunun sadece basit bir yazılım meselesi olmadığını düşündürüyor.
Uygulamayı çekirdeğe bağlanmış bir initramfs olarak paketlerseniz, basit durumlarda dosya sistemi bağlamaya gerek kalmayacağı için süreyi epey kısaltabilirsiniz.
Bazı durumlarda BusyBox init gibi şeyler de yalnızca asgari önyüklemeyi yapan basit bir bash betiğiyle değiştirilebilir. devtmpfs, proc, sysfs vb. bağlamak ve mümkünse glibc’den vazgeçmeyi değerlendirmek de mantıklı.
initramfs’i çekirdeğe bağlamadan önce gerekli uygulama bağımlılıklarının tamamının mevcut olup olmadığını chroot ile test etmek iyi olur. chroot içinde çalışıyorsa çekirdek de önyükleme sırasında çalıştırabilir ve geliştirme döngüsü çok daha hızlanır.
Çekirdek modüllerini kapatıp yalnızca gereken işlevleri çekirdeğe bağlarsanız alanı ve önyükleme süresini daha da azaltabilirsiniz. gzip yerine zstd sıkıştırması da denemeye değer.
Daha önceki önyükleme aşamalarının donanım performansını yeterince kullanamadığı ya da imaj büyük olduğu için yüklemeyle paralel başka işler yapmanın daha iyi olduğu durumlar buna girer.
O zaman geriye yalnızca statik bağlanmış tek bir ikili dosyayı içeren initramfs kalır.
Pi önyükleme süresini azaltma hakkında iki iyi yazı daha var.
https://www.furkantokac.com/rpi3-fast-boot-less-than-2-secon...
http://himeshp.blogspot.com/2018/08/fast-boot-with-raspberry...
Bu iki yazıyı referans alarak Pi ile dijital fotoğraf çerçevesi yaptım ve kiosk modu tarayıcıya kadar çok hızlı açılmasını sağladım. Gereksinimler çok azsa oldukça etkileyici önyükleme süreleri elde edilebiliyor.
Asıl trajedi, bootcode.bin GPU kodunun tescilli bir kara kutu olması ve kaynak kodunun bulunmaması.
Hack’ler ve hobi projeleri, değiştirilemeyen gizli bir kara kutuya sahip olmak zorunda kalıyor; berbat bir durum.
Şu anda özgür ve açık kaynak yazılım.
https://www.theregister.com/2023/11/28/microsoft_opens_sourc...
Bu, Pi firmware’inin tamamının otomatik olarak özgür ve açık kaynak olduğu anlamına gelmiyor. Çünkü bunlar sürücü değil. Ama istenirse böyle yapılabilir.
İçinde ne var da kapalı tutulması gerekiyor, merak ediyorum.
Yazının geneli hoşuma gitti ama bu kısımdan emin değilim
CPU turboyu kapatıp akım tüketiminden biraz tasarruf etmenin kötü bir tercih olduğu; yavaşlayan süre yüzünden işi hızlıca bitirip kapatmaktan daha fazla enerji harcandığı kısmı
Bilgisayar mühendisliği dersinde güç tüketiminin saat frekansının karesiyle orantılı olduğunu öğrenmiştim. Yani saat hızını iki katına çıkarırsanız güç dört katına çıkar demek
O halde saat hızındaki ikinci dereceden artışın, iş süresi uzadıkça oluşan sabit güç tüketiminin çarpımından büyük olup olmadığını görmek için gerçek güç farkını ölçmek gerekir gibi geliyor
Bununla ilgili olarak Pi CPU’nun veri sayfasından türetilebilecek ya da register’larla gerçek zamanlı sunulabilecek ayrıntılı güç tüketimi bilgisi sağlaması iyi olurdu
Çoğu çip daha yüksek saat hızlarına ulaşmak için daha yüksek voltaja ihtiyaç duyar; ikinci dereceden ilişki de buradan çıkar
Ama bildiğim kadarıyla Raspberry Pi’de dinamik voltaj kontrolü yok; dolayısıyla voltajı düşürmeden yalnızca saat hızını düşürürseniz toplam anahtarlama enerjisi tüketimine etkisi olmayacak gibi
Elbette bir optimum nokta da var. CPU’yu çok fazla overclock ederseniz watt başına performans çok düşer ve race to idle artık işe yaramaz
Bu yüzden modern gömülü sistemler çoğu zaman "race-to-sleep" veya "race-to-halt" stratejilerini kullanır: işi çok hızlı çalıştırıp, sonraki olay gelene kadar bileşenlerin çoğunu kapalı tutarlar
Bir hesaplamayı 1 saniyede yapmak 1J gerektiriyorsa, örneğin 1GHz’de 1W ise, kusursuz küresel inek modelinde aynı hesaplamayı 0,5 saniyede yapmak 2J gerektiriyor demek sanırım. Çünkü 2GHz’de 4W oluyor
Ancak bu yalnızca CPU tüketimine bakıyor; tüm sistemde 4W sabit tüketim varsa 1GHz’de CPU 1J ve sistem 4J olmak üzere toplam 5J, 2GHz’de ise CPU 2J ve sistem 2J olmak üzere toplam 4J harcanır
Doğru anladıysam, tüm sistemin güç tüketimi turbo durumundaki CPU güç tüketimine yakınsa turboyu kullanmak mantıklı, değilse değil mi?
Etkileyici. Ama böyle yazıları her okuduğumda Pi Zero’da Plan 9 önyüklemesini kaydettiğim an aklıma geliyor: https://taoofmac.com/space/blog/2020/09/02/1900#resurrecting
GIF gerçek zamanlı çıktıdır
Ama özgün projede gereken kamera ve Wi‑Fi sürücülerini yükleyip yükleyemeyeceği ayrı mesele
Kişisel olarak Linux dağıtımlarının önyükleme süreleri genel olarak epey hayal kırıklığı yaratıyor; böyle zayıf donanımlarda bu sorun çok daha büyüyor
MQ-Pro SBC’de de benzer optimizasyonlar denedim. Dizüstünde de bunu epey hissediyorum. MacBook belki istisna olabilir ama her hâlükârda sinir bozucu bir konu
Bir kez açıldıktan sonra yalnızca tekrar giriş yapmak anlık oluyor ama yeniden başlatma epey zaman alıyor
Ancak dağıtımlar makul nedenlerle çok genel amaçlı bir kernel ve initramfs oluşturur; bu kombinasyon da özellikle hızlı önyüklenmez
[0]: https://blog.davidv.dev/posts/minimizing-linux-boot-times/
Tabii NetworkManager’ın var olmayan Wi‑Fi için 90 saniye beklemesi gibi korkunç bir yanlış yapılandırma yoksa. Benim Linux makinem graphical.target’a yaklaşık 4 saniyede ulaşıyor; bunun çoğu Wi‑Fi bağlantısı ve ntpd yüzünden, ikisi de prensipte isteğe bağlı
Gerçekten hızlı önyükleme istiyorsanız bootloader uyumluluk katmanlarını, soyutlamaları ve initramfs gibi dinamik yapılandırılabilirlik özelliklerini tamamen atabilirsiniz. Ama o zaman donanım tedarikçilerine bağımlı hâle gelirsiniz; buna değmez
Örneğin Linux kurulu MacBook Air 11’de giriş ekranı o kadar hızlı geliyor ki önyükleme günlüklerini neredeyse göremiyorum. systemd-analyze’a göre graphical target’a 4 saniyenin altında ulaşıyor
Kilit nokta iki şey gibi görünüyor. Masaüstü ortamı kullanmamak; metin modunda önyükleyip gerektiğinde startx çalıştırmak ya da hafif bir giriş yöneticisiyle (lightdm) X’e önyüklemek. Masaüstü ortamı olmayınca servis sayısı tek haneli katlarda azalıyor ve eski donanımda önyükleme sırasında I/O baskısı ciddi biçimde düşüyor. X çalışsa bile önyüklenmiş sistem 200MB’nin altında
Bir diğeri de EFI stub’ın hızı artırabilmesi: https://wiki.archlinux.org/title/EFISTUB
İlk sezgim, başka bir çekirdek kullanılamaz mıydı diye düşünmek oldu. Fotoğraf çekip buluta göndermek için gerçekten Linux gerekli mi?
Donanım tarafında biri değilim; bu işi minimum bütçeyle nasıl tamamlayabileceğimizi merak ediyorum. İlginç bir yazıydı
Şu anda yemek masamın üzerinde iki ESP32-CAM olduğu için olabilir ama ESP32-CAM kurulumunun nasıl karşılaştırılacağını merak ettim. Muhtemelen yalnızca 2 megapiksel görüntülere kadar sorun olmazdı; başlangıç süresi ve güç tüketimi ise ikisi de neredeyse bir basamak daha düşük olurdu
Merak ederseniz ayrıntılar burada: https://components101.com/modules/esp32-cam-camera-module
Prensipte bare metal ile de mümkün, ama gerekli çevre birimlerini çalıştırmak kolay değil
Özel kernelin neden bu kadar geç gündeme geldiğini merak ettim. Optimizasyon yapacaksanız LFS ya da kaynak tabanlı bir dağıtımdan başlamaz mısınız? Böyle bir cihazda otonom yazılım güncellemeleri de pek şart gibi görünmüyor
Ayrıca böyle cihazlarda EFI/BIOS'un optimize edilip edilemeyeceğini de merak ediyorum. En azından benim sıradan Arch Linux masaüstümde önyükleme süresinin önemli bir kısmını oluşturuyor
$ systemd-analyzeStartup finished in 10.076s (firmware) + 1.339s (loader) + 1.569s (kernel) + 2.974s (initrd) + 3.894s (userspace) = 19.854sRaspberry Pi donanımını tam bilmiyorum, ama diğer birçok gömülü SoC, u-boot ile çalışan oldukça minimal bir bootloader'a sahip ve genelde çok hızlılar. Kullanıcı girdisini bekleyen gecikme süresini 0'a ayarlarsanız özellikle öyle
Minimal bir kernel ve busybox sistemi çok daha az zahmetli; Gentoo da kötü bir seçenek değil
> systemd-analyzeStartup finished in 3.259s (firmware) + 35.127s (loader) + 1.823s (kernel) + 2.927s (userspace) = 43.138s3,5 saniye harika, ama tüm senaryo gerçekten birkaç dakikada bir Wi‑Fi'ye bağlanıp görüntü yüklemekse, ESP32 güç tüketimi açısından çok daha iyi bir seçim olurdu
Tabii Pi kamera modülünde, ESP32-CAM uyumlu kameralarda olmayan belirli bir özellik mutlaka gerekmiyorsa
Bir mikrodenetleyicinin neredeyse hiç zorlanmadan yapabileceği bir işi yapmak için fazla fazla uğraşılıyor gibi görünüyor