<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Блоги: заметки с тегом flipper zero</title>
<link>https://blogengine.me/blogs/tags/flipper-zero/</link>
<description>Автоматически собираемая лента заметок, написанных в блогах на Эгее</description>
<author></author>
<language>ru</language>
<generator>Aegea 11.0 (v4079e)</generator>

<itunes:subtitle>Автоматически собираемая лента заметок, написанных в блогах на Эгее</itunes:subtitle>
<itunes:image href="" />
<itunes:explicit>no</itunes:explicit>

<item>
<title>Использую ли я «Флиппер»</title>
<guid isPermaLink="false">134005</guid>
<link>https://bolknote.ru/all/ispolzuyu-li-ya-flipper/</link>
<pubDate>Thu, 06 Feb 2025 15:26:09 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/ispolzuyu-li-ya-flipper/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2025.02.06.1@2x.webp" width="1000" height="562" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;У меня тут спросили, использую ли «Флиппер Зеро», — давно ничего про него не рассказывал. Использую, конечно, и очень интенсивно! С тех пор как потерял магнитный ключ от подъезда, каждый день туда и обратно прохожу, прикладывая вместо него «Флиппер». Всё недосуг заняться этим вопросом.&lt;/p&gt;
&lt;p&gt;Хорошо, что ещё в самом начале я записал на «Флиппер» данные всех магнитных ключей, которые у меня были — домашний, рабочий, родственников и так далее.&lt;/p&gt;
</description>
</item>

<item>
<title>Casio WQV-3</title>
<guid isPermaLink="false">132519</guid>
<link>https://bolknote.ru/all/casio-wqv-3/</link>
<pubDate>Sat, 02 Nov 2024 10:23:05 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/casio-wqv-3/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;К заметке, где я писал про камеру для «Флиппера», один из читателей &lt;a href="https://bolknote.ru/all/eschyo-fotki-kameroy-flippera/#comments"&gt;прислал ссылку&lt;/a&gt; на часы «&lt;i&gt;Casio WQV-1&lt;/i&gt;» начала 2000-х. Интересны они тем, что у них тоже есть камера, позволяющая делать чёрно-белые снимки в оттенках серого с разрешением 120×120.&lt;/p&gt;
&lt;p&gt;Разумеется я загорелся их купить.&lt;/p&gt;
&lt;p&gt;На «Ебее» их можно найти без проблем, но с пересылкой часов через границу сейчас большие проблемы. Без особой надежды я пошерстил «Авито» и оказалось, что, хотя первой модели часов там нет, зато лежит третья, которую я тут же себе купил и ношу уже несколько дней.&lt;/p&gt;
&lt;p&gt;Оцените какой ретро-футуристичный дизайн! Как будто из второй части трилогии «Назад в будущее».&lt;/p&gt;
&lt;p&gt;Всего в линейке таких часов было четыре модели с номерами «1», «2», «3» и, почему-то, «10». Третья модель, которую я и купил, &lt;a href="http://cdecas.free.fr/wristcam/tech.php"&gt;отличается&lt;/a&gt; от первой внешним видом и другой камерой — цветной с разрешением 176×144. Правда экранчик цвет не показывает, да и снимок умещается не весь — при просмотре видно только центральную часть.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.11.02@2x.jpg" width="1000" height="562" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Конечно снимки хочется из часов как-то выковырять. Проблема в том, что с часами мне не досталось ни софта, ни касиовского инфракрасного адаптера, который найти — та ещё эпопея.&lt;/p&gt;
&lt;p&gt;Под рукой, из того, что поддерживает инфракрасный обмен, у меня только «Флиппер». В принципе, если знать протокол, можно под него написать программу, которая списывала бы снимки на карточку, оттуда перекинуть на ноутбук — ноль проблем.&lt;/p&gt;
&lt;p&gt;Описание протокола найти было нетрудно. Но позже оказалось, что в третьей модели «Касио» перешли на некий стандартный протокол передачи, а его описание я ещё даже не искал. Возможно, раз протокол стандартный, снимки можно получить как-то проще, посмотрим. Если нет, то придётся писать программу под «Флиппер».&lt;/p&gt;
&lt;p&gt;Я немного посмотрел АПИ для работы с инфракрасником во «Флиппере» и, пока не забыл узнанное, сделаю заметки для себя.&lt;/p&gt;
&lt;p&gt;Для передачи сигналов подойдёт одна из двух функций. Если повезёт это будет &lt;tt&gt;infrared_send&lt;/tt&gt;, которая принимает команды в одном из стандартных кодеков, либо &lt;tt&gt;infrared_send_raw_ext&lt;/tt&gt;, где придётся возиться с ручным кодированием битов.&lt;/p&gt;
&lt;p&gt;Зависит от того, что за кодировка сигналов используется в этом самом «стандартном протоколе». Если это что-то из того, что умеет «Флиппер», дело упрощается, иначе надо будет выяснять тайминги, скорость передачи и прочие технические подробности.&lt;/p&gt;
&lt;p&gt;Наименее очевидными были для меня тайминги. Я как-то не задумывался никогда как именно кодируются «нули» и «единицы» в передачах через инфракрасный порт. Оказывается «ноль» и «единица» имеют просто разные тайминги, то есть разное время на которое загорается светодиод.&lt;/p&gt;
</description>
</item>

<item>
<title>Ещё фотки камерой «Флиппера»</title>
<guid isPermaLink="false">132431</guid>
<link>https://bolknote.ru/all/eschyo-fotki-kameroy-flippera/</link>
<pubDate>Sat, 26 Oct 2024 15:59:59 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/eschyo-fotki-kameroy-flippera/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.10.26.5.png" width="830" height="64" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Когда берёшь в руки молоток, всё вокруг становится похожим на гвозди. Раз уж я примотал камеру к «Флипперу», надо всё вокруг пофотографировать. Мы с дочкой решили сфоткать домочадцев.&lt;/p&gt;
&lt;p&gt;Жена на работе, себя я &lt;a href="https://bolknote.ru/all/kamera-dlya-flippera/"&gt;фоткал вчера&lt;/a&gt;, поэтому слева направо: улитки Тайгер и Найгер, кот Марсик, пёс Бейсик и дочь Ева.&lt;/p&gt;
</description>
</item>

<item>
<title>Камера для «Флиппера»</title>
<guid isPermaLink="false">132425</guid>
<link>https://bolknote.ru/all/kamera-dlya-flippera/</link>
<pubDate>Sat, 26 Oct 2024 01:18:39 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/kamera-dlya-flippera/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Около трёх месяцев назад, болтаясь по интернету, я, волею случая, наткнулся на &lt;a href="https://github.com/CodyTolene/Flipper-Zero-Camera-Suite"&gt;репозиторий&lt;/a&gt; с софтом, позволяющим подключить к «Флипперу» небольшую веб-камеру. Для подключения внешних модулей у него на боку есть специальный разъём.&lt;/p&gt;
&lt;p&gt;Выглядело это забавно, да и цена вопроса — всего 400 рублей, плюс комплект перемычек за 30. Невеликие траты за такую прикольную штуку. Я что-то тянул с этой покупкой, но, в конечном счёте, купил, конечно. Кстати, камеру можно было найти и дешевле, но я побоялся, что приедет какой-нибудь мусор, а тут хотя бы продавец с хороший рейтингом.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.10.25.2@2x.jpg" width="1000" height="562" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;«Флиппер Зеро» с камерой в сборе&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Из-за того, что нужные программы довольно долго скачивались, собрал всё вместе и поставил нужный софт примерно за час. Чистого времени ушло минут двадцать, мог бы и меньше потратить, но перепутал штырьки.&lt;/p&gt;
&lt;p&gt;Если внимательно следовать инструкции, то всё просто: четырьмя перемычками соединяешь «Флиппер» и плату, ещё одной замыкаешь между собой два штырька — это нужно, чтобы залить в камеру прошивку. Потом скачиваешь редактор для «Ардуино», там ставишь плагин, далее через «Флиппер» с его помощью заливаешь в камеру прошивку, размыкаешь перемычку. Потом через магазин приложений ставишь нужную программу и развлекаешься.&lt;/p&gt;
&lt;p&gt;Единственная хитрость — плагин надо ставить второй версии, а не третьей, в третьей почему-то нет поддержки нужной платы.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.10.25.3.png" width="880" height="64" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Экранчик у «Флиппера» маленький и чёрно-белый, поэтому изображение посредственное, но так только интереснее — качественное изображение я могу и на смартфоне увидеть, а тут настоящий олдскул!&lt;/p&gt;
</description>
</item>

<item>
<title>Доделал приложение пароля для «Войи»</title>
<guid isPermaLink="false">130537</guid>
<link>https://bolknote.ru/all/dodelal-prilozheniya-parolya-dlya-voyi/</link>
<pubDate>Sun, 08 Sep 2024 00:12:26 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/dodelal-prilozheniya-parolya-dlya-voyi/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Глаза боятся, руки делают. Что-то я сначала приуныл, когда понял сколько возни предстоит, чтобы сделать интерфейс ввода часового пояса, который я &lt;a href="https://bolknote.ru/all/eschyo-pro-inzhenerny-parol-ot-voyi/"&gt;решил добавить&lt;/a&gt; в программу для получения инженерного пароля «Войи» под «Флиппер».&lt;comment style="display:none"&gt;Flipper Zero&lt;/comment&gt; Даже как-то руки опустились.&lt;/p&gt;
&lt;p&gt;Начал потихоньку — накидал сначала функций-заглушек, а потом всё реализовал в течение дня. Всё, теперь &lt;a href="https://github.com/bolknote/Flipper-Zero-Voyah-Password"&gt;программа&lt;/a&gt; приобрела законченный вид. Публиковать в каталог, правда, не планирую — очень уж невелика аудитория. Много ли владельцев «Войи» с «Флиппером»?&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.09.07@2x.png" width="677" height="269" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Программа, запущенная на «Флипере Зеро». Виден указанный часовой пояс — &lt;i&gt;GMT+03:00&lt;/i&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;В этот раз столкнулся с кое-чем новеньким. В одном месте мне надо было нарисовать две большие стрелки — влево и вправо. Открыл редактор, нарисовал в одну строну, наложил, посмотрел как смотрится в интерфейсе, всё прекрасно.&lt;/p&gt;
&lt;p&gt;Чтобы получить стрелку в другу строну, повернул её в редакторе, проделал всё то же, что с первой, но при отображении стрелка получалась в какую-то неравномерную крапинку.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.09.07.1@2x.png" width="256" height="128" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Интерфейс задания часового пояса&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Как я &lt;a href="https://bolknote.ru/all/operator-has-include/"&gt;уже рассказывал&lt;/a&gt;, инструментарий для компиляции программ сам конвертирует картинки в нужный «Флипперу» формат. Я не ковырял, но по виду это обычный &lt;i&gt;XBM&lt;/i&gt; — формат двухцветной чёрно-белой графики.&lt;/p&gt;
&lt;p&gt;Предполагаю, что при преобразовании входного изображения в двухцветное, используется какой-то очень простой алгоритм. Например, всё что в точности чёрное оставляем чёрным, остальное считаем белым. Вероятно где-то у меня в изображении были пиксели, которые только казались чёрными, но ими не были.&lt;/p&gt;
&lt;p&gt;Сначала я решил это проверить. Поводил «пипеткой» на картинке, не нашёл. Нарисовал заново. Это ситуацию не исправило. Решил посмотреть в бинарном виде сконвертированные файлы, оказалось сложновато, плюнул. Пошёл смотреть в чём разница у исходных файлов. Оказалось, что один у меня в формате &lt;i&gt;1-bit colormap PNG&lt;/i&gt;, а второй (который с дырками) — &lt;i&gt;1-bit grayscale PNG&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;Подумал, что проблема в этом, но как преобразовать одно в другое сходу не разобрался. Утилитой &lt;tt&gt;magick&lt;/tt&gt; начал конвертировать проблемную картинку в &lt;i&gt;PNG&lt;/i&gt;, перебирая все известные мне ключи подряд, пока в один момент дырки не пропали. Я так и не выяснил какое сочетание настроек мне помогло, потому что в процессе потерял исходную «дырявую» картинку, а делать новую не хотелось — мне ещё предстояло много программировать.&lt;/p&gt;
&lt;p&gt;«Что это было, Бэрримор» — непонятно до сих пор, но на всякий случай записываю себе этот случай, чтобы в следующий раз хотя бы примерно понимать как с ним бороться.&lt;/p&gt;
</description>
</item>

<item>
<title>Оператор «__has_include»</title>
<guid isPermaLink="false">130519</guid>
<link>https://bolknote.ru/all/operator-has-include/</link>
<pubDate>Thu, 05 Sep 2024 20:12:09 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/operator-has-include/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Одна штука мне очень не нравилась в программировании под «Флиппер». Фреймворк устроен так, что картинки, используемые в приложениях, должны внедряться определённым способом.&lt;/p&gt;
&lt;p&gt;А именно — в манифесте приложения, в директиве &lt;tt&gt;fap_icon_assets&lt;/tt&gt; мы указываем папку, каждая картинка в которой, позже, на этапе сборки, будет преобразована в специальный массив. Этот массив всегда называется &lt;tt&gt;I_имя_файла_картинки&lt;/tt&gt;. Массивы засовываются в файл со специальным именем, который надо импортировать в код через &lt;tt&gt;#include&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Поскольку это происходит во время сборки, редактор (я использую «Визуал Студио Код») этот файл не видит, поэтому подчёркивает мне его импорт и все использования массивов, которые в нём описаны, как ошибку.&lt;/p&gt;
&lt;p&gt;Лично меня такое раздражает. В редакторе мне хочется видеть полное отсутствие ошибок.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.09.05.1@2x.jpg" width="1000" height="250" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Пример того как отображаются упомянутые ошибки в приложении «Пароль для Войи»&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;В «&lt;a href="https://bolknote.ru/tags/hangman-game/"&gt;Виселице&lt;/a&gt;» я с этим смирился, а сегодня каким-то чудом вспомнил про нестандартную директиву &lt;tt&gt; __has_include&lt;/tt&gt;, которую как-то не доводилось использовать прежде. Она проверяет как раз то, что мне нужно — доступен файл для импорта или нет.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.09.05.2@2x.jpg" width="1000" height="172" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Реальный пример того как можно сделать, чтобы редактор не считал, что у меня ошибка&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Получается, что если файл для импорта ещё не готов, то мы его не импортируем, а нужный нам массив объявляем, как имеющий внешнюю реализацию. В итоге, в редакторе ошибок не остаётся.&lt;/p&gt;
</description>
</item>

<item>
<title>Ещё про инженерный пароль от «Войи»</title>
<guid isPermaLink="false">130516</guid>
<link>https://bolknote.ru/all/eschyo-pro-inzhenerny-parol-ot-voyi/</link>
<pubDate>Thu, 05 Sep 2024 15:56:18 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/eschyo-pro-inzhenerny-parol-ot-voyi/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Ну началось 😅 Теперь меня не отпускают мысли как можно доработать приложение для &lt;a href="https://bolknote.ru/all/inzhenerny-parol-ot-voyi/"&gt;получения инженерного пароля&lt;/a&gt;, которое я написал вчера.&lt;/p&gt;
&lt;p&gt;Как я говорил, у «Флиппера» есть проблема — он &lt;a href="https://github.com/akopachov/flipper-zero_authenticator/wiki/Flipper-Authenticator-generates-invalid-codes,-why-so%3F"&gt;ничего не знает&lt;/a&gt; о часовом поясе. В каждом приложении, где нужно его знать, приходится что-то решать отдельно, централизованного решения нет.&lt;/p&gt;
&lt;p&gt;Я пока не стал заморачиваться, просто показываю три кода из трёх разных дней. Это, конечно, не совсем правильно. Учитывая, что часовые пояса у нас бывают от &lt;i&gt;GMT-12:00&lt;/i&gt; до &lt;i&gt;GMT+14:00&lt;/i&gt;, есть небольшое окошко, где можно показать не три, а два кода. Но вряд ли это существенно что-то меняет, поэтому я этого делать не стал.&lt;/p&gt;
&lt;p&gt;В общем, решил сделать как все — окошко с настройкой часового пояса. Если пояс задан, он будет показан на кнопке и выводиться будет только один код, если нет, на кнопке будет написано что-то типа «&lt;i&gt;set timezone&lt;/i&gt;» и кодов будет три.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.09.05@2x.jpg" width="1000" height="562" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Проектирование интерфейса для установки часового пояса&lt;/div&gt;
&lt;/div&gt;
</description>
</item>

<item>
<title>Инженерный пароль от «Войи»</title>
<guid isPermaLink="false">130496</guid>
<link>https://bolknote.ru/all/inzhenerny-parol-ot-voyi/</link>
<pubDate>Wed, 04 Sep 2024 23:40:55 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/inzhenerny-parol-ot-voyi/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Чтобы совсем не позабыть как писать и компилировать программы для «Флиппера», написал &lt;a href="https://github.com/bolknote/Flipper-Zero-Voyah-Password"&gt;небольшую программу&lt;/a&gt;, которая выводит инженерный пароль для моей машины.&lt;/p&gt;
&lt;p&gt;Пароль там можно даже на калькуляторе вычислять, но это неудобно — надо сложить поциферно месяц-день с годом. Поэтому я написал программу.&lt;/p&gt;
&lt;p&gt;День берётся по часовому поясу Китая, а поскольку «Флиппер» ничего про часовые пояса не знает, поэтому приходится показывать три числа — для разных дней.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.09.04@2x.jpg" width="1000" height="562" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Пароль от инженерного меню «Войи» на сегодня&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Полезное упражнение, подзабыл некоторые особенности, как самой сборки, так и наличествующего АПИ.&lt;/p&gt;
</description>
</item>

<item>
<title>А что «Флиппер»?</title>
<guid isPermaLink="false">130055</guid>
<link>https://bolknote.ru/all/a-chto-flipper/</link>
<pubDate>Sun, 11 Aug 2024 16:53:53 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/a-chto-flipper/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Меня тут недавно спросили — куда пропали мои посты про «Флиппер»? Пропали, потому что писать особо нечего. У меня в голове есть идея небольшого, полезного лично для меня приложения для него, кроме того, незакрытым гештальтом висит на душе добавление туда Юникода, но времени нет ни на первое, ни на второе.&lt;/p&gt;
&lt;p&gt;Пока лето, в выходные я в разъездах, в будни тоже хочется куда-нибудь сходить, — ведь тепло. Холодно станет, может тогда и займусь.&lt;/p&gt;
&lt;p&gt;Пока же я его использую только в быту — чтобы что-нибудь открыть. В последний раз пользовался сегодня — командовал шлагбаумом около дома, где мы снимали квартиру в Йошкар-Оле. Иначе пришлось бы возвращаться в квартиру, чтобы оставить брелок от шлагбаума.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.08.11@2x.jpg" width="1000" height="562" alt="" /&gt;
&lt;/div&gt;
</description>
</item>

<item>
<title>Завтра — отпуск!</title>
<guid isPermaLink="false">128103</guid>
<link>https://bolknote.ru/all/zavtra-otpusk/</link>
<pubDate>Tue, 28 May 2024 10:51:29 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/zavtra-otpusk/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Завтра отпуск. Я надеялся позаниматься «Флиппером Зеро», но вовремя сообразил, что отношение к этому устройству по всему миру неоднозначное. Лучше его за границу не возить, тем более со снимающей ограничения прошивкой, которая стоит у меня.&lt;/p&gt;
&lt;p&gt;В принципе, устройство везти не обязательно, можно использовать «&lt;a href="https://github.com/bolknote/Flipper-Zero-UTF-8-playground"&gt;песочницу&lt;/a&gt;» с минимальный кодом. Его хватит для моей задачи — добавить, наконец, в прошивку поддержку Юникода. Я пока забросил эту задачу, планирую заняться в отпуске, не всё же на пляже тюленить.&lt;/p&gt;
</description>
</item>

<item>
<title>Юникод во «Флиппере»: глубока ли кроличья нора</title>
<guid isPermaLink="false">126424</guid>
<link>https://bolknote.ru/all/yunikod-vo-flippere-gluboka-li-krolichya-nora/</link>
<pubDate>Mon, 25 Mar 2024 22:25:58 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/yunikod-vo-flippere-gluboka-li-krolichya-nora/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Юникод во «Флиппере» неисчерпаем, как атом.&lt;/p&gt;
&lt;p&gt;Сначала мне стало просто интересно почему для «Флиппера» нет ни одного русскоязычного приложения, потом я выяснил что мешает это сделать и научился обходить эти ограничения, потом написал &lt;a href="https://bolknote.ru/tags/hangman-game/"&gt;русскоязычную игру&lt;/a&gt;, после чего залез в прошивку и начал добавлять в неё поддержку Юникода, погружаясь всё глубже и глубже.&lt;/p&gt;
&lt;p&gt;К моим коммитам отнеслись довольно благосклонно, но в один момент дело застопорилось — авторы прошивки решили обновить сторонний фреймворк для вывода на экран, что могло повлиять на мои изменения, поэтому работу над ними я отложил. Но уже тогда у меня возникла мысль, что надо бы добавить Юникод и в библиотеку работы со строками, которую использует «Флиппер Зеро».&lt;/p&gt;
&lt;p&gt;Пока я ждал обновления, &lt;a href="https://bolknote.ru/all/konec-uskorennoy-strlen-na-flippere/"&gt;занял&lt;/a&gt; себя векторизацией функции подсчёта длины строки в кодировке &lt;i&gt;UTF-8&lt;/i&gt;, а когда коммит отклонили, поставил всю эту движуху на паузу.&lt;/p&gt;
&lt;p&gt;И вот сегодня я получил &lt;a href="https://github.com/flipperdevices/flipperzero-firmware/pull/3303#issuecomment-2018337204"&gt;новый комментарий&lt;/a&gt; к моему коммиту от авторов прошивки — мне порекомендовали заняться тем, о чём я когда-то размышлял, а именно — поддержкой Юникода в библиотеке работы со строками и только после этого закончить свой предыдущий коммит.&lt;/p&gt;
&lt;p&gt;Размер доработок всё ширится, а результат всё дальше. Интересно, насколько глубока кроличья нора?&lt;/p&gt;
</description>
</item>

<item>
<title>Конец ускоренной strlen на «Флиппере»</title>
<guid isPermaLink="false">126221</guid>
<link>https://bolknote.ru/all/konec-uskorennoy-strlen-na-flippere/</link>
<pubDate>Mon, 11 Mar 2024 11:00:48 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/konec-uskorennoy-strlen-na-flippere/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;В итоге, эпопея с ускорением функции замера длины строки в кодировке &lt;i&gt;UTF-8&lt;/i&gt; на «Флиппере Зеро» подошла к концу — коммит не взяли.&lt;/p&gt;
&lt;p&gt;У меня с самого начала этой затеи были сомнения. Я понимал, что для того, чтобы решить чью-то проблему, надо сначала доказать, что она существует, чему я должного внимания не уделил. Кроме того, сейчас в мире программирования очень важно решить проблему понятным образом, а векторное ускорение мало кому знакомо.&lt;/p&gt;
&lt;p&gt;Тем не менее, я с удовольствием повозился инструкциями &lt;i&gt;SIMD&lt;/i&gt;. До этого мини-проекта у меня было теоретическое понимание о том, что это за функции, но на практике я их не использовал.&lt;/p&gt;
&lt;p&gt;Моя функция, кстати, претерпела некоторые изменения:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="cpp"&gt;size_t furi_string_utf8_length(FuriString* str) {
    size_t len = string_size(str-&amp;gt;string);
    const char * cstr = string_get_cstr(str-&amp;gt;string);
    const char* end = cstr + len;

    if(len &amp;gt;= sizeof(uint8x4_t)) {
        const char* vend = end - sizeof(uint8x4_t);

        int8x4_t zero = 0x00000000;
        int8x4_t one = 0x01010101;
        int8x4_t threshold = -1077952577; // -65, -65, -65, -65

        do {
            int8x4_t vec = *(int8x4_t*)cstr;

            __ssub8(threshold, vec);
            uint8x4_t result = __sel(one, zero);

            len -= __usada8(result, zero, 0);

            cstr += sizeof(uint8x4_t);
        } while(cstr &amp;lt;= vend);
    }

    while(cstr &amp;lt; end) {
        signed char c = *cstr++;
        len -= c &amp;lt; -64;
    }

    return len;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Оказалось, что тип &lt;i&gt;FuriString&lt;/i&gt; хранит в себе бинарную длину строки, поэтому я переделал код, чтобы он не пытался читать чужую память. В векторизованой части это было вероятно, но своих рассуждений и &lt;a href="https://github.com/flipperdevices/flipperzero-firmware/pull/3479"&gt;дискуссии по коммиту&lt;/a&gt; я сделал вывод, что в случае «Флиппера» это не имеет какого-либо значения.&lt;/p&gt;
&lt;p&gt;Тем не менее, если использовать бинарную длину, код получается более аккуратным и немного упрощается, так что грех не воспользоваться. Интересно бы, кстати, измерить наивный алгоритм без векторной части, но с использованием бинарной длины, наверное займусь этим в ближайшее время.&lt;/p&gt;
&lt;p&gt;В итоге, решая эту, возможно несуществующую, проблему, я опробовал на практике векторные инструкции расширений &lt;i&gt;NEON&lt;/i&gt; и &lt;i&gt;DSP SIMD&lt;/i&gt;, &lt;a href="https://bolknote.ru/all/nado-by-dobavit-moy-strlen-vo-flipper/"&gt;научился делать&lt;/a&gt; два параллельных запроса на вливание в «Гитхабе» и ещё раз вспомнил как компилировать и заливать свою прошивку во «Флиппер Зеро».&lt;/p&gt;
</description>
</item>

<item>
<title>Сделал PR с новой strlen во «Флиппер»</title>
<guid isPermaLink="false">126037</guid>
<link>https://bolknote.ru/all/sdelal-pr-s-novoy-strlen-vo-flipper/</link>
<pubDate>Mon, 26 Feb 2024 10:54:55 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/sdelal-pr-s-novoy-strlen-vo-flipper/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Спасибо Шурику Бабаеву за помощь, &lt;a href="https://github.com/flipperdevices/flipperzero-firmware/pull/3479"&gt;добавил&lt;/a&gt; свой коммит с векторизованной функцией для измерения длины строки в кодировке &lt;i&gt;UTF-8&lt;/i&gt; в кодовую базу прошивки «Флиппера».&lt;/p&gt;
&lt;p&gt;Попутно выяснилось, что «Флиппер» использует функцию замера длины из библиотеки &lt;a href="https://github.com/P-p-H-d/mlib"&gt;&lt;i&gt;M*LIB&lt;/i&gt;&lt;/a&gt;. Можно было бы закоммитить новую версию в неё, но не стал этого делать по двум причинам.&lt;/p&gt;
&lt;p&gt;Во-первых, моя версия заточена под конкретную платформу, а &lt;i&gt;M*LIB&lt;/i&gt;, кажется, универсальная библиотека. Во-вторых, если бы мой коммит в неё и приняли, надо было бы ещё каким-то образом добиться обновления библиотеки в прошивке «Флиппера», а это, наверняка, непростая задача.&lt;/p&gt;
&lt;p&gt;Кстати, сделал итоговые замеры. Миллион итераций с четырьмя короткими строками (от &lt;tt&gt;ЯБ12341&lt;/tt&gt; до &lt;tt&gt;ЯБ12341234&lt;/tt&gt;) моя версия делает за шесть секунд, тогда как прежняя — за 39.&lt;/p&gt;
</description>
</item>

<item>
<title>Надо бы добавить мой strlen во «Флиппер»</title>
<guid isPermaLink="false">125997</guid>
<link>https://bolknote.ru/all/nado-by-dobavit-moy-strlen-vo-flipper/</link>
<pubDate>Thu, 22 Feb 2024 10:47:20 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/nado-by-dobavit-moy-strlen-vo-flipper/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Можно подумать, что я забросил возню с «Флиппером», так как какое-то время писал об этом часто, а сейчас поутих. На самом деле я всё жду, когда разработчики прошивки &lt;a href="https://github.com/flipperdevices/flipperzero-firmware/pull/3303"&gt;вмержат мой коммит&lt;/a&gt; для поддержки Юникода, плюс потихоньку вожусь со своей &lt;a href="https://bolknote.ru/all/dsp-simd-dlya-flipper-zero/"&gt;векторной реализацией&lt;/a&gt; функции для определения длины строки в кодировке &lt;i&gt;UTF-8&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;До недавнего времени я её надеялся ускорить, поэтому пытался вносить какие-то мелкие улучшения, но все они никакого эффекта не дали. Зато при аккуратном тестировании нашёл ошибку, — неправильно задал граничное условие в векторизованном куске. Хорошо, что проверил. В блоге у меня уже исправленная версия.&lt;/p&gt;
&lt;p&gt;Будем считать, что с этим вопросом я закончил, хочу теперь попробовать добавить этот код в прошивку «Флиппера». Остались сделать два шага.&lt;/p&gt;
&lt;p&gt;На замерах моя реализация обогнала встроенную на порядок — восемь секунд против 55 на двух миллионах итераций по небольшой строке. Но теперь надо воткнуть её в прошивку, чтобы учесть влияние реализации строкового типа &lt;i&gt;FuriString&lt;/i&gt;, в котором будет использоваться эта функция и провести новые замеры. Надеюсь сделать это в ближайшие выходные.&lt;/p&gt;
&lt;p&gt;Второй шаг для меня сложнее. У меня уже есть выписанная прошивка «Флиппера», в которой торчит непринятый коммит. Я никогда раньше не создавал на «Гитхабе» два разных запроса в рамках одного чужого проекта, не знаю как это делается. Если кто-то умеет, расскажите в комментариях.&lt;/p&gt;
</description>
</item>

<item>
<title>Замеры strlen_uft8 на «Флиппере Зеро»</title>
<guid isPermaLink="false">125801</guid>
<link>https://bolknote.ru/all/zamery-strlen-uft8-na-flippere-zero/</link>
<pubDate>Tue, 06 Feb 2024 22:32:23 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/zamery-strlen-uft8-na-flippere-zero/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Ну что же, я наконец сравнил &lt;a href="https://bolknote.ru/all/dsp-simd-dlya-flipper-zero/"&gt;свой вариант&lt;/a&gt; функции определения длины строки в кодировке UTF-8 с наивной реализацией и &lt;a href="https://www.daemonology.net/blog/2008-06-05-faster-utf8-strlen.html"&gt;чужим быстрым вариантом&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Оказалось, что обычные функции замера времени под «Флиппером» не работают. мне не удалось получить значение текущего времени ни одним из способов к которым я привык на Си, поэтому опять пришлось читать исходники прошивки «Флиппера».&lt;/p&gt;
&lt;p&gt;В итоге обнаружился метод, выводящий затраченное время с секундной точностью:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="cpp"&gt;FuriHalRtcDateTime curr_dt;
furi_hal_rtc_get_datetime(&amp;amp;curr_dt);
uint32_t start = furi_hal_rtc_datetime_to_timestamp(&amp;amp;curr_dt);

for (int i = 0; i&amp;lt;1000000; i++)
len += strlen_utf8(&amp;quot;This is a test и русских букв тоже&amp;quot;);

furi_hal_rtc_get_datetime(&amp;amp;curr_dt);
uint32_t stop = furi_hal_rtc_datetime_to_timestamp(&amp;amp;curr_dt);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Хотелось бы точнее, но этого, в принципе, хватает, чтобы понять какая функция быстрее и на сколько. Надо просто сделать очень много итераций. Я попробовал запускать на миллионе и десяти миллионах.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.02.06@2x.png" width="1000" height="617" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Скриншот экрана «Флиппера», снятый через специальную программу; отображается суммарная длина и время работы — пять секунд&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;В итоге, на десяти миллионах наивная реализация выполняется примерно за 80 секунд, моя и чужая быстрая — около 50, явного лидера из этих двух реализаций выделить не удалось. Все замеры делал несколько раз.&lt;/p&gt;
</description>
</item>

<item>
<title>DSP SIMD для Flipper Zero</title>
<guid isPermaLink="false">125765</guid>
<link>https://bolknote.ru/all/dsp-simd-dlya-flipper-zero/</link>
<pubDate>Sun, 04 Feb 2024 21:47:15 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/dsp-simd-dlya-flipper-zero/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p style="background: rgb(222, 235, 217); padding: 10px; color:#000"&gt;В этом версии нет никакой защиты цикла от чтения за границей буфера, мне показалось, что во «Флиппере» это неважно, но возможно это не так.&lt;/p&gt;
&lt;p&gt;Ну что ж, разобрался я что за зверь такой этот &lt;i&gt;DSP SIMD&lt;/i&gt; и запрограммировал на нём векторизированную версию функции для измерения длины строки.&lt;/p&gt;
&lt;p&gt;Сегодня описывать и замерять уже не буду, и так времени много ушло, но по крайней мере всё работает на настоящем «Флиппере».&lt;/p&gt;
&lt;p&gt;Сразу можно заметить, что вектора тут вдвое короче — всего четыре байта, да и функций для работы с ними гораздо меньше, но этого набора оказалось достаточно, чтобы всё векторизовать.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="cpp"&gt;#include &amp;lt;arm_acle.h&amp;gt;

size_t strlen_arm_utf8(char * str) {
    uint32_t len = 0;
    int8x4_t zero = 0x00000000;
    int8x4_t one  = 0x01010101;
    int8x4_t threshold = -1077952577; // -65, -65, -65, -65

    for (;;) {
        uint8x4_t result;
        int8x4_t vec = *(int8x4_t *) str;

        __uadd8(0xFFFFFFFF, vec); result = __sel(zero, one);
        if (result &amp;gt; 0) {
            if (result == 0x01000000) {
                __ssub8(threshold, vec); result = __sel(zero, one);
                return __usada8(result, 1, len);
            }
            break;
        }

        __ssub8(threshold, vec); result = __sel(zero, one);
        len = __usada8(result, zero, len);

        str += sizeof(uint8x4_t);
    }

    for (signed char c; (c = *str); str++) {
        if (c &amp;gt;= -64) {
            len++;
        }
    }    

    return len;
}&lt;/code&gt;&lt;/pre&gt;</description>
</item>

<item>
<title>ARM бывают разные</title>
<guid isPermaLink="false">125762</guid>
<link>https://bolknote.ru/all/arm-byvayut-raznye/</link>
<pubDate>Sun, 04 Feb 2024 14:25:12 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/arm-byvayut-raznye/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Преодолев &lt;a href="https://bolknote.ru/all/pora-perenesti-izmerenie-dliny-na-flipper/"&gt;внутреннее сопротивление&lt;/a&gt;, я всё-таки занялся переносом &lt;a href="https://bolknote.ru/all/chut-bolee-bystry-podschyot-dliny-stroki-v-utf-8/"&gt;векторизованной функции измерения длины строки&lt;/a&gt; на «Флиппер Зеро». Почти сразу выяснилось, что моя интуиция меня не обманула — на этом пути куча проблем.&lt;/p&gt;
&lt;p&gt;Во «Флиппере» стоит процессор &lt;i&gt;ARM&lt;/i&gt;, а они, как оказалось, бывают очень разные.&lt;/p&gt;
&lt;p&gt;Я ещё в самом начале посмотрел спецификацию процессора «Флиппера» и, увидев слово &lt;i&gt;SIMD&lt;/i&gt;, совершенно успокоился — в моём понимании это означало, что я могу использовать любые команды векторизации, которые мне необходимы. Тут я немного поторопился, но меня подгоняло желание разобраться как устроена векторизация. Теорию я знал, а тут подвернулась, пусть немного синтетическая, но задача, которую руки чесались решить.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.02.04@2x.jpg" width="1000" height="339" alt="" /&gt;
&lt;div class="e2-text-caption"&gt;Некоторые ошибки компиляции упомянутой функции под «Флиппер Зеро»&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Как я уже говорил, мне захотелось срезать углы, поэтому функцию до этого момента я писал на своём ноутбуке, раз так случилось, что у меня на нём тоже процессор &lt;i&gt;ARM&lt;/i&gt;. И лишь сегодня я попробовал вставить её в одну из своих программ и собрать её для «Флиппера».&lt;/p&gt;
&lt;p&gt;Сначала компилятор заявил мне, что не нашёл некоторые векторные функции, в частности функцию нахождения минимума &lt;tt&gt;vminvq_u8&lt;/tt&gt; и суммы &lt;tt&gt;vaddvq_u8&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Ветку с &lt;tt&gt;vminvq_u8&lt;/tt&gt; я временно убрал, а функцию суммы &lt;tt&gt;vaddvq_u8&lt;/tt&gt; решил заменить на поэлементное сложение (&lt;tt&gt;vaddq_u8&lt;/tt&gt;), которая, вроде, компилятору знакома.&lt;/p&gt;
&lt;p&gt;Мысль простая — в векторах, сумму которых мы находим, на каждой позиции нули и единицы, поскольку каждый элемент вектора у нас восьмибитный, в общем случае у нас поместится результат 255 операций, а потом я могу просто просуммировать элементы циклом. Как-то так:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="cpp"&gt;uint8x16_t len_v = vdupq_n_u8(0);
int reset = 0;

// тут у нас цикл
uint8x16_t gt = vcgtq_s8(operand, threshold);
len_v = vaddq_u8(vandq_u8(gt, delta), len_v);

if (++reset &amp;gt;= 255) {
    for (size_t i = 0; i &amp;lt; sizeof(uint8x16_t); i++) {
        len += *((uint8_t *)&amp;amp;len_v + i);
    }

    reset = 0;
    len_v = vdupq_n_u8(0);
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Я был очень доволен решением (оно не совсем моё, его мне навеял код, используемый в &lt;i&gt;PHP&lt;/i&gt;), но оказалось, что оно тоже не компилируется.&lt;/p&gt;
&lt;p&gt;Сборка заругалась на ошибку &lt;i&gt;target specific option mismatch&lt;/i&gt;, означающую, что указанное при компиляции железо не поддерживает те возможности, которые я пытаюсь использовать в коде. Пришлось лезть в тулчейн, чтобы разобраться какие ключи компиляции сейчас используются.&lt;/p&gt;
&lt;p&gt;В файле &lt;tt&gt;compile_commands.json&lt;/tt&gt; можно увидеть, что при сборке используется ключ &lt;tt&gt;-mfpu=fpv4-sp-d16&lt;/tt&gt;, тогда как мне, чтобы использовать нужные команды векторизации нужен ключ &lt;tt&gt;-mfpu=neon&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Так как ключи компиляции указывали разработчики «Флиппера», думаю, они в точности знали в какие значения их выставить. Согласно &lt;a href="https://developer.arm.com/Processors/Cortex-M4"&gt;спецификации&lt;/a&gt; на борту использованного во «Флиппере» процессора &lt;i&gt;SIMD&lt;/i&gt; есть, но, видимо, какой-то другой. Так как &lt;i&gt;SIMD&lt;/i&gt; написано в разделе &lt;i&gt;DSP Extension&lt;/i&gt;, надо смотреть что это такое, может всё-таки можно использовать эти команды для ускорения.&lt;/p&gt;
</description>
</item>

<item>
<title>Пора перенести измерение длины на «Флиппер»</title>
<guid isPermaLink="false">125725</guid>
<link>https://bolknote.ru/all/pora-perenesti-izmerenie-dliny-na-flipper/</link>
<pubDate>Thu, 01 Feb 2024 22:32:04 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/pora-perenesti-izmerenie-dliny-na-flipper/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Кажется я то ли прокрастинирую, то ли боюсь неудачи. Предполагалось, что векторизованный алгоритм &lt;a href="https://bolknote.ru/all/chut-bolee-bystry-podschyot-dliny-stroki-v-utf-8/"&gt;измерения длины строки&lt;/a&gt; в кодировке &lt;i&gt;UTF-8&lt;/i&gt; я в конечном счёте портирую под «Флиппер», но что-то мне мешает сделать этот шаг.&lt;/p&gt;
&lt;p&gt;Он вполне может не скомпилироваться — не уверен, что на «Флиппере» есть 128-битные вектора. Судя по спецификации, скорее нет, чем есть. Наверное намечающиеся сложности заставляют меня колебаться. Надеюсь пост в блоге, как это нередко бывало раньше, подтолкнёт меня к действию.&lt;/p&gt;
</description>
</item>

<item>
<title>UTF-8 на ARM</title>
<guid isPermaLink="false">125614</guid>
<link>https://bolknote.ru/all/utf-8-na-arm/</link>
<pubDate>Wed, 24 Jan 2024 22:13:28 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/utf-8-na-arm/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Пока проект внедрения Юникода во «Флиппер Зеро» на паузе, — разработчики занимаются обновлением одной из важных библиотек, я вспомнил, что вообще-то в природе существуют разные способы ускорения обработки строки в кодировке &lt;i&gt;UTF-8&lt;/i&gt;. Именно её я выбрал для хранения строк. А поскольку железо у «Флиппера» весьма ограниченное, может быть имеет смысл подумать как сэкономить ресурсы.&lt;/p&gt;
&lt;p&gt;Например, когда-то, ещё во времена работы в «Яндексе», я &lt;a href="https://bolknote.ru/all/2855/"&gt;сравнивал&lt;/a&gt; между собой различные реализации функции &lt;tt&gt;strlen&lt;/tt&gt;, где ускорение достигалось за счёт векторизации.&lt;/p&gt;
&lt;p&gt;Любопытно посмотреть как обстоят дела с ускорением таких вещей на процессоре, который установлен на «Флиппере». Правда до него у меня руки ещё не дошли, но я уже потренировался на своём «Макбуке», благо тут процессор той же архитектуры.&lt;/p&gt;
&lt;p&gt;Идея всё та же — векторизация. За референс я взял наивную реализацию с перебором по одному байту:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="cpp"&gt;size_t strlen_naive(const char* str) {
    size_t len = 0;
    char ch;
	
    while ((ch = *str++)) {
        len += (ch &amp;amp; 0b11000000) != 0b10000000;
    }

    return len;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Попробовал несколько вариантов, но лучше всех показали себя две функции: та, которую я упоминал в первом абзаце и переделанная нашими общими с братишкой усилиями &lt;a href="https://github.com/php/php-src/blob/ea3c541640a75340ea06c460cf282bde5bf75b13/ext/mbstring/mbstring.c#L1772"&gt;реализация&lt;/a&gt;, найденная в недрах &lt;i&gt;PHP&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;После переделки она стала выглядеть так:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="cpp"&gt;size_t strlen_php(unsigned char * p) {
    size_t len = 0;

    const int8x16_t threshold = vdupq_n_s8(-64);
    const uint8x16_t delta = vdupq_n_u8(1);

    for(;;) {
        int8x16_t operand = vld1q_s8((const int8_t * ) p);
        if (vminvq_u8(operand) == 0) {
            break;
        }

        uint8x16_t lt = vcltq_s8(operand, threshold);
        len += sizeof(uint8x16_t) - vaddvq_u8(vandq_u8(lt, delta));
        p += sizeof(uint8x16_t);
    }

    for (signed char c; (c = *p); p++) {
        if (c &amp;gt;= -64) {
            len++;
        }
    }

    return len;
}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Повторюсь, у меня пока не дошли руки попробовать это всё на «Флиппере», но на моём «Макбуке» результаты выглядят следующим образом. Это десять тысяч прогонов на русскоязычном тексте, размер которого чуть больше ста тысяч символов.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="plaintext"&gt;Name   Length  Time
----   ------  ----
PHP    117465   97797
Fast   117465  143780
Naïve  117465  531535&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Не скажу, что я делал всё как положено, — надо бы считать среднее и отклонение, разносить по разным файлам, научиться прибивать процесс к производительным ядрам, но разница в результатах достаточно показательна (я запускал несколько десятков раз), поэтому, как мне кажется, и так нормально.&lt;/p&gt;
&lt;p&gt;Цифры в попугаях (больше — хуже), которые выдаёт сишная функция &lt;tt&gt;clock()&lt;/tt&gt;, компилировал компилятором &lt;i&gt;Clang 15&lt;/i&gt; с ключом &lt;tt&gt;-O3&lt;/tt&gt;.&lt;/p&gt;
</description>
</item>

<item>
<title>«Виселица» в магазине приложений</title>
<guid isPermaLink="false">125579</guid>
<link>https://bolknote.ru/all/viselica-v-magazine-prilozheniy/</link>
<pubDate>Sun, 21 Jan 2024 20:25:34 +0500</pubDate>
<author>Евгений Степанищев</author>
<comments>https://bolknote.ru/all/viselica-v-magazine-prilozheniy/</comments>
<description>
&lt;p&gt;&lt;a href="https://bolknote.ru/"&gt;Евгений Степанищев&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Я долго не знал как выглядит наша с дочкой игра «Виселица» в магазине приложений «Флиппера Зеро» — смартфон-то у меня «Хуавей», а под него нужного приложения нет.&lt;/p&gt;
&lt;p&gt;А на днях вспомнил, что &lt;a href="https://bolknote.ru/all/doogee-s98-pro/"&gt;походный-то смартфон&lt;/a&gt; у меня с обычным «Андроидом»! В общем посмотрел, даже скриншот снял на память. Надо бы, кстати, выпустить новую версию — у меня там есть досадная опечатка в английской локализации — &lt;i&gt;loose&lt;/i&gt;, вместо &lt;i&gt;lose&lt;/i&gt;.&lt;/p&gt;
&lt;div class="e2-text-picture"&gt;
&lt;img src="https://bolknote.ru/pictures/2024.01.21.1@2x.jpg" width="750" height="1250" alt="" /&gt;
&lt;/div&gt;
&lt;p&gt;Честно сказать, необходимость постоянно использовать какие-то дополнительные приседания, чтобы поставить часть приложений на «Хуавей» меня сильно утомила. Думал, что смогу с этим жить, но нет. Продержался более трёх лет, но сил моих больше нет. Кажется буду переходить. Вот только на что ещё не решил.&lt;/p&gt;
</description>
</item>


</channel>
</rss>