بینایی ماشین با SIMD روی میکروکنترلر ۲ دلاری ESP32-S3
خلاصهٔ کاملتر
ESP32-S3 یه میکروکنترلر حدوداً ۲ دلاریه با پردازندهی دوهستهای ۲۴۰ مگاهرتزی، WiFi و Bluetooth Low Energy. نویسنده موقع خوندن راهنمای فنی چیپ متوجه شده که یه سری دستور SIMD هم داره (یعنی دستورهایی که یه عملیات رو همزمان روی چند داده انجام میدن). هر رجیستر برداری ۱۲۸ بیته و میتونه ۱۶ عدد ۸ بیتی رو نگه داره.
به گفتهی نویسنده، این دستورها مخفی نیستن ولی کمتر کسی ازشون استفاده کرده. فقط سه تا منبع نمونهکد پیدا کرده: وبلاگ Larry Bank و دو تا کتابخونهی خود Espressif یعنی esp-dsp و esp-dl. با کمک همینها اسمبلی ESP32-S3 رو یاد گرفته و آخرش حتی یه register allocator ساده به اسم basm برای خودش نوشته.
هدفش پیادهسازی FAST feature detector بوده (یعنی الگوریتمی که نقطههای گوشهمانند تصویر رو پیدا میکنه). اول سراغ پیشآزمون FAST رفته: از هر چهار جهت اصلی یه پیکسل برمیداره و چک میکنه حداقل سه تاش «افراطی» باشن، یعنی اختلافشون با پیکسل وسط از یه آستانه بیشتر باشه. تابعش هر بار ۱۶ پیکسل رو با هم حساب میکنه.
اولین مشکل این بود که چیپ خوندن دادهی نامرتب (misaligned) رو مستقیم پشتیبانی نمیکنه، پس بلوکهای شرق و غرب پیکسل وسط رو نمیشد مستقیم خوند. راهحل یه دستور بود که از دو رجیستر چسبیده به هم، یه تیکه رو جدا میکنه توی رجیستر سوم. اینجوری بلوکهای کناری رو از دو بلوک همسایه بیرون کشیده.
مشکل دوم: مقایسهها فقط برای عددهای ۸ بیتی علامتدار هست، ولی پیکسلها بیعلامتن و بازهی ۱۲۸ تا ۲۵۵ به ۱۲۸- تا ۱- تبدیل میشه. کم کردن ۱۲۸ هم جواب نمیداد چون عملیات SIMD اینجا saturating هستن (یعنی بهجای سرریز، روی حد مینیمم گیر میکنن). نویسنده نشون داده که بیت آخر عدد ارزش ۱۲۸- داره، پس x - 128 == x ^ 0x80. یعنی با یه XOR ساده کل ۱۶ پیکسل جابهجا میشن.
با این دو ترفند، توان پردازش FAST حدود ۲۲۰ درصد شده: از ۵.۱ به ۱۱.۲ مگاپیکسل در ثانیه، و هر فریم QVGA حدود ۶ میلیثانیه. نویسنده میگه این برای بینایی ماشین بلادرنگ کافیه و چیپ راحت یه استریم VGA با ۳۰ فریم در ثانیه رو جواب میده. یه تابع امتیازدهی SIMD هم نوشته که توی این پست توضیحش نداده.
نکات کلیدی:
- ESP32-S3 رجیسترهای برداری ۱۲۸ بیتی داره که ۱۶ عدد ۸ بیتی رو همزمان پردازش میکنن
- خوندن نامرتب مستقیم ممکن نیست و با دستور استخراج تیکه از دو رجیستر دور زده شده
- مقایسهها فقط علامتدارن و جمع و تفریق saturating هستن، پس از x ^ 0x80 بهجای تفریق ۱۲۸ استفاده شده
- سرعت FAST از ۵.۱ به ۱۱.۲ مگاپیکسل در ثانیه رسیده، حدود ۶ میلیثانیه برای هر فریم ۳۲۰ در ۲۴۰
- نویسنده برای راحتی کار یه register allocator ساده به اسم basm هم ساخته