Computer Vision auf einem 2-Dollar-ESP32-S3 mit SIMD beschleunigen
(shraiwi.github.io)- Mit den 128-Bit-SIMD-Befehlen des günstigen ESP32-S3 wurde der FAST-Feature-Detector beschleunigt, sodass QVGA-Frames (320×240) in etwa 6 ms verarbeitet werden
- Der Chip ist ein Mikrocontroller mit Dual-Core-CPU bis 240 MHz, WiFi und Bluetooth Low Energy; im Technical Reference Manual ist eine eingeschränkte SIMD-Unterstützung dokumentiert
- Der Kern der Implementierung besteht darin, im FAST-Corner-Pre-Test 16 8-Bit-Pixel gleichzeitig zu verarbeiten; dafür mussten jedoch unaligned reads und Einschränkungen bei signed-Vergleichen umgangen werden
- Um unsigned 8-Bit-Pixel an signed-Vergleiche anzupassen, wurde die Eigenschaft
x - 128 == x ^ 0x80genutzt und die Werte per 0x80-XOR umgewandelt - Der Testdurchsatz stieg von 5,1 MP/s auf 11,2 MP/s, womit auch die Verarbeitung von VGA-Streams mit 30 fps auf dem ESP32-S3 erreichbar ist
Beschleunigung des FAST-Feature-Detectors auf dem ESP32-S3
- Für den ESP32-S3 wurde ein SIMD-beschleunigter FAST-Feature-Detector implementiert, der gegenüber der Referenzimplementierung ungefähr die doppelte Leistung erreicht
- Die Verarbeitung eines QVGA-Frames (320×240) dauert etwa 6 ms
- Der ESP32-S3 ist ein günstiger Mikrocontroller, bietet aber eine Dual-Core-CPU bis 240 MHz sowie WiFi und Bluetooth Low Energy
- Im ESP32-S3 technical reference manual lässt sich eine eingeschränkte Unterstützung für SIMD-Befehle nachlesen
Weniger bekannte SIMD-Befehle und Vorbereitung der Implementierung
- Die SIMD-Befehle des ESP32-S3 sind keine geheime Funktion, waren aber vergleichsweise wenig bekannt
- Als Referenzen lassen sich drei Beispiele nennen
- Larry Bank’s blog: Erkundung der Funktionen und ein minimal example
esp-dsp: eine Espressif-Bibliothek für DSP-nahe Funktionen wie Convolution und FFTesp-dl: eine Espressif-Bibliothek für On-Chip-AI-Beschleunigung
- Im Verlauf der Implementierung wurden die Grundlagen der ESP32-S3-Assemblersprache erarbeitet, außerdem entstand der eigene einfache Register-Allocator
basm
SIMD-Verarbeitung im FAST-Corner-Pre-Test
- Beim Corner-Pre-Test des FAST feature detector werden Pixel in Ost-, West-, Süd- und Nordrichtung abgetastet, um zu prüfen, ob es mindestens drei „extreme“ Pixel gibt
- Ein extremes Pixel ist dabei ein Pixel, dessen absoluter Unterschied zum Zentrumspixel einen bestimmten Schwellwert überschreitet
- Da jedes Vektorregister 16 Werte zu je 8 Bit speichern kann, wurde die Berechnung der Extremwert-Anzahl für 16 Pixel gleichzeitig aufgebaut
- Dafür werden aus jeder der vier Richtungen vier Pixel-Chunks gesampelt und mit den jeweils zugehörigen Zentrumspixeln verglichen
Einschränkungen von ESP32-S3-SIMD und ihre Umgehung
- Die erste Einschränkung ist, dass die ISA keine direkten misaligned reads erlaubt
- Nimmt man an, dass die Zentrumspixel ausgerichtet sind, dann sind die östlichen und westlichen Blöcke nicht ausgerichtet
- Die Ost-/West-Blöcke werden durch einen Befehl gewonnen, der zwei benachbarte Register zusammenfügt und dann einen Teilausschnitt daraus extrahiert
- Die zweite Einschränkung ist, dass der ESP32-S3 nur signed-8-Bit-Vergleiche implementiert
- Pixeldaten werden jedoch als unsigned 8 Bit gespeichert; interpretiert man sie direkt als signed, wird der Bereich
[128, 255]nichtlinear auf[-128, -1]abgebildet - In diesem Zustand funktionieren Vergleichsoperationen nicht korrekt
- Pixeldaten werden jedoch als unsigned 8 Bit gespeichert; interpretiert man sie direkt als signed, wird der Bereich
Unsigned-Pixel für signed-Vergleiche anpassen
- Die Pixelwerte müssen von
[0, 255]nach[-128, 127]verschoben werden, damit Vergleiche und Arithmetik sinnvoll funktionieren - Es wirkt zunächst naheliegend, einfach 128 zu subtrahieren, doch genau hier entsteht ein Problem, weil die SIMD-Arithmetik des ESP32-S3 vollständig saturating arithmetic verwendet
- Pixelwerte oberhalb von 127 underflowen dadurch nicht korrekt, sondern werden auf
-128geklemmt
- Pixelwerte oberhalb von 127 underflowen dadurch nicht korrekt, sondern werden auf
- Die Lösung ist eine parallele Subtraktion von 128 ohne Subtraktionsbefehl
- Bei signed 8 Bit hat das höchstwertige Bit den Stellenwert
-128 x - 128ist daher äquivalent dazu, das höchstwertige Bit umzuschalten- Deshalb wird die Beziehung
x - 128 == x ^ 0x80verwendet
- Bei signed 8 Bit hat das höchstwertige Bit den Stellenwert
- Bei jedem Laden eines unsigned-8-Bit-Werts wird daher per XOR mit
0x80in einen linearen Bereich transformiert, in dem Arithmetik und Vergleiche funktionieren
Performance-Ergebnisse und Echtzeitpotenzial
- Mit diesen zwei Umgehungstechniken wurde ein SIMD-beschleunigter FAST-Corner-Pre-Test implementiert
- Mit einer ähnlichen Kombination von Operationen wurde auch eine SIMD-beschleunigte Scoring-Funktion geschrieben, auf Details wird jedoch nicht eingegangen
- In den Tests stieg der Durchsatz des FAST-Feature-Detectors von 5,1 MP/s auf 11,2 MP/s
- Das entspricht rund 220 % des bisherigen Niveaus
- Diese Leistung liegt in einem für Echtzeit-Computer-Vision akzeptablen Bereich und ermöglicht es dem ESP32-S3, VGA-Streams mit 30 fps problemlos zu verarbeiten
1 Kommentare
Hacker-News-Kommentare
weil Großkonzerne lokale Farmen ausbeuten und faktisch regionale Monopole aufrechterhalten, sodass die Farmen gezwungen sind, an diese Konzerne weit unter dem tatsächlichen Wert zu verkaufen
Staaten auf der ganzen Welt kaufen solche Dinge in Milliardenstückzahlen, um ihre Bürger zu überwachen, und Big Brother schafft damit gewaltige Skaleneffekte
Es wirkt wie eine günstige Zynq-Variante für Computer Vision
https://wiki.sipeed.com/hardware/en/tang/Tang-Nano-4K/Nano-4...
https://www.aliexpress.us/item/3256806880637138.html
Die S3-Variante rechtfertigt die kleinen Mehrkosten locker, weil sie SIMD und FPU hat und dadurch leicht um ein Mehrfaches im einstelligen Bereich schneller ist
https://github.com/espressif/esp-dl/tree/master/examples/fac...
54 ms für Personenerkennung ist beeindruckend: https://github.com/espressif/esp-tflite-micro?tab=readme-ov-...
Wir arbeiten direkt mit verschiedenen Anbietern zusammen und optimieren Deep Learning-, Computer Vision- und Digital-Signal-Processing-Aufgaben auf niedriger Ebene für Dutzende Mikrocontroller- und CPU-Architekturen, Spezialbeschleuniger (einschließlich neuromorphem Computing) und Edge-GPUs
ESP32 ist auch dabei: https://docs.edgeimpulse.com/docs/edge-ai-hardware/mcu/espre...
Du kannst TensorFlow-, PyTorch- und JAX-Modelle hochladen und bekommst dann mit ein paar Zeilen Python auf dem Notebook direkt eine optimierte C++-Bibliothek, was ziemlich beeindruckend ist
Es gibt auch ein Studio zum Trainieren von Modellen sowie hardwarebewusste Hyperparameter-Optimierung, um die besten Modelle für Architekturen zu finden, die auf verschiedener Embedded-Hardware gut laufen, abgestimmt auf Latenz und Speicherverbrauch des Zielgeräts
Features from accelerated segment test: https://en.wikipedia.org/wiki/Features_from_accelerated_segm...
Ich frage mich, ob Chips in dieser Preisklasse auch etwas TPU-Ähnliches haben
Neon ist eine optionale SIMD-Befehlssatzerweiterung für ARMv7 und ARMv8, also haben Pi Zero und aufwärts SIMD-Erweiterungen
Den Orrin Nano verstehe ich mit 40 TOPS als leistungsfähig genug für Copilot+. "A PCIe Coral TPU Finally Works on Raspberry Pi 5" https://news.ycombinator.com/item?id=38310063
Laut https://phys.org/news/2024-06-infrared-visible-device-2d-mat... wurde eine Infrarotwellenlänge von 1550 nm in sichtbare 622 nm hochkonvertiert, und die ausgegebene Lichtwelle kann von herkömmlichen siliziumbasierten Kameras erkannt werden
Dabei bleibt die Kohärenz erhalten, sodass, wenn man der eingehenden Infrarotfrequenz ein bestimmtes Muster aufprägt, dieses automatisch auf die neue Ausgangsfrequenz übertragen wird
"Show HN: PicoVGA Library – VGA/TV Display on Raspberry Pi Pico" https://news.ycombinator.com/item?id=35117847#35120403
https://news.ycombinator.com/item?id=40275530
"Designing a SIMD Algorithm from Scratch" https://news.ycombinator.com/item?id=38450374
Die SIMD-Befehle des ESP32-S3 scheinen dafür ausgelegt zu sein, die Inferenz quantisierter AI-Modelle zu beschleunigen (https://github.com/espressif/esp-dl); dazu gehört auch Signalverarbeitung wie FFT.
In dem Sinne, dass es spezielle Befehle zur Unterstützung von ML-Inferenz gibt, könnte man es auch als TPU-ähnlich bezeichnen. Zum Beispiel führt EE.VRELU.Sx eine ReLU-Operation aus.
Wenn man solche Befehle nutzt, wird allerdings weiterhin CPU-Zeit verbraucht, und normalerweise arbeitet eine TPU asynchron auf separaten Verarbeitungskernen, daher ist es eher mit ARM NEON vergleichbar.
Software und Dokumentation waren ziemlich gut, leider hat sich das Gerät aber nicht breit durchgesetzt.
Heute findet man leicht günstige Entwicklungsboards auf Basis von RV1103 ("LuckFox"), BL808 ("Ox64/Pine64") und CV1800B/SG20002 ("MilkV"), die alle etwas grundlegend TPU-Ähnliches haben.
Da sie jedoch als Linux-Boards konzipiert sind, ist alles rund um die TPU extrem abstrahiert, und interne Dokumentation gibt es praktisch gar nicht; deshalb ist völlig unklar, ob es sich um echte TPUs handelt oder um clevere Code-Optimierungen, die das nur nachahmen.
MicroPython wirkt auf den ersten Blick ziemlich zugänglich, und ich frage mich, wie einfach sich dieser Code nach WebAssembly portieren ließe.
Gerätebezogene Anwendungsfälle kann man unter https://micropython.org/unicorn/ ausprobieren.
Für die clientseitige Entwicklung kann es in PyScript verwendet werden, und es gibt auch eine JavaScript/DOM-Bridge.
https://pyscript.net/tech-preview/micropython/about.html
no-std in Rust auf dem ESP32 ist meiner Erfahrung nach ebenfalls nicht schlecht, aber insbesondere die Anbindung an Komponenten wie Wi‑Fi, Networking oder Kameras ist noch nicht ganz ausgereift.
Wie in einem anderen Kommentar erwähnt, sind SIMD und Assembler-Unterstützung in Rust ausreichend vorhanden.
Bevor man tiefer einsteigt, wäre es sinnvoll, im Rust-Embedded- oder Rust-ESP32-Chat nachzufragen.
Wenn man viel SIMD einbaut und dazu SMT-4 oder SMT-8 verwendet, könnten Threads Latenzen verbergen, sodass das Verhältnis von Leistung zu Chipfläche am Ende besser ausfällt.