86-DOS version 0.11

Мне интересно иногда посмотреть на старые операционные системы и программы, которые я не застал или пропустил в своё время. Предтечу MS-DOS, которая называлась 86-DOS, я уже как-то видел, но там речь шла о версии 1.0, а тут в доступе появилась 0.11.

Довольно долго разбирался как её запустить, опишу, чтобы не забыть, мало ли, вдруг когда-нибудь пригодится.

Первом делом скачиваем IMD-образ операционной системы и распаковаем его из-под ДОСбокса набором утилит ImageDisk 1.19. Получившийся после распаковки образ переименовываем в 86dos.imd.

Качаем первый попавшийся эмулятор Altairz80 под требуемую операционную систему, компилируем, в папку эмулятора кладём файлы scp86mon.txt, scp86mon.rom и образ операционной системы.

Вводим команду ./altairz80 scp86mon.txt, потом уже там несколько раз «Ввод», латинскую B, снова «Ввод» и, по идее, всё должно запуститься.

Скриншот терминала эмулятора Altair 8800: запуск 86-DOS, команда DIR показывает файлы, включая CHESS; пользователь выбирает чёрных и делает первый ход в шахматной игре.
Версия 86-DOS версии 0.11, запущенная в эмуляторе Altairz80

Смотреть там, конечно, особо не на что, хотя есть редактор, ассемблер и шахматы, а так же работают кое-какие привычные со времён ДОСа команды — COPY, DIR, TYPE и RENAME. Из непривычных есть ERASE, которая удаляет файл и CLEAR, очищающая содержимое диска.

Теперь могу говорить, что я своими собственными глазами видел самого раннего предка MS-DOS, которого только можно найти в интернете.

Оставить комментарий

Велики зимой

Интересно как быстро курьеры на великах зимой стали достаточно обыденным явлением. Всего-то ничего времени прошло, а уже никого не удивляет.

Раньше ребята на зимних фатбайках (велосипедах с толстыми шинами) были до того редкой картиной, что прохожие разве что шеи себе не сворачивали.

Курьеры всё изменили. Причём ездят они буквально на чём попало, ни о каких специальных велосипедах для зимы речи не идёт. Даже шины вполне обычные, я спрашивал. Хотя зимняя резина для великов существует и стоит как любая другая. Экономят, видимо.

Курьер в красной куртке с рюкзаком Samokat на велосипеде стоит на заснеженной дороге ночью, рядом пешеход; на заднем плане — красный автобус и дорожные знаки.

9 комментариев

Что там дальше с Юникодом под Flipper Zero?

Наверняка вам интересно, что там происходит с моим мини-проектом по внедрению Юникода во «Флиппер Зеро»? Шучу, понимаю, что всем пофигу!

Тем не менее всё равно напишу. Проект пока на паузе.

Причина — разработчики прошивки решили обновить фреймворк «U∞g²», который используется для вывода текста. Дело хорошее, но поскольку мои правки зависят от этого фреймворка, придётся подождать его обновления.

Что там в нём изменится мне интересно, можно бы посмотреть, но форсировать не буду, обновится — гляну.

А пока заметил, что переписать придётся ещё одну функцию — elements_multiline_text_aligned. Когда просматривал, не заметил, что в ней используется местный аналог printf, который с Юникодом сроду не работал:

if((start[chars_fit] == '\n') || (start[chars_fit] == 0)) {
    line = furi_string_alloc_printf("%.*s", chars_fit, start);
} else if((y + font_height) > canvas_height(canvas)) {
    line = furi_string_alloc_printf("%.*s...\n", chars_fit, start);
} else {
    chars_fit -= 1; // account for the dash
    line = furi_string_alloc_printf("%.*s-\n", chars_fit, start);
}

Конкретно это место никак не зависит от «U∞g²», можно бы и заняться. Но пока у меня с новогодними праздниками не задалось — всё ещё работаю, плюс немного заболел — горло болит и кашель. Разгребусь, выздоровлю и займусь.

21 комментарий

Обожаю всё выкидывать

С работой во время праздников и болезнью совсем пропустил свою ежегодную традицию.

Мне надоело подводить перед Новым годом итоги, так сейчас многие делают и я решил писать что-то другое, например, рассказывать о себе какие-то вещи, которые мало кто знает. Ничего постыдного, просто малоизвестные штуки.

На этот раз заспойлерил всё в заголовке, но всё-таки немного больше раскрою тему. Очень люблю выкидывать. Не совсем всё, это было бы странно, но очень люблю собирать со всего дома мусор, чтобы мусорный пакет побыстрее заполнился и можно было бы вынести его на мусорку. Испытываю от этого настоящее удовольствие.

С этой точки зрения измельчитель отходов, который мы поставили в новой квартире, был очень удачной покупкой, — теперь я полюбил ещё и уничтожать огрызки, кожуру и прочие остатки органики.

Не думаю, что я один такой, скорее всего нас таких много. Поэтому для меня удивительно, что для этого нет никакого названия, по крайней мере мне его найти не удалось.

Установленный под раковиной измельчитель отходов Bort с металлическим корпусом, подключённый к электросети и канализации, на фоне бытовой химии.
Знакомьтесь, это измельчитель отходов по имени Кальцифер

11 комментариев

В нашем доме поселился…

Как-то я уже писал про то, что на новой квартире у меня иногда показатель загрязнения воздуха уходил в потолок. Я долго пытался разобраться в чём дело, так в точности и не понял, только предположил, что от соседей может через вентиляцию или окна лететь мелкодисперсная строительная пыль.

Потом это прекратилось, а недавно началось заново — время от времени все фильтры воздуха совершенно внезапно начинают с воем увеличивать обороты вентиляторов.

Поскольку это плюс-минус совпало с моментом, когда в одной из соседских квартир на этаже начался ремонт, я считаю, что дело раскрыто. Видимо и правда виновата строительная пыль. У меня по квартире разведена вентиляция из коридора (по проекту дома так сделано), но откуда она засасывает воздух мне доподлинно неизвестно, думаю, что пыль проникает через неё.

Видимо, когда все сделают ремонт, квартирные фильтры станут окончательно бесполезными. Впрочем, можно быть имеет смысл поставить один рядом с 3д-принтером.

Круглый дисплей на белом устройстве показывает число 167, температуру 24°C, влажность 24%, значки Wi-Fi и автоматического режима, а также индикатор заряда и кнопки питания.
Стоило в соседской квартире на этаже начаться ремонту, показатель запылённости сразу попёр вверх

12 комментариев

Буду убирать микропроветривание

Месяц назад был в сомнениях — оставлять микропроветривание в окнах или нет. Но к концу декабря стало очень морозно, появился ветрище и через щель между окном и пластиковой притворной планкой так сильно стало задувать, что окна пришлось проклеивать в этом месте, как встарь.

Даже не помню когда в последний раз приходилось подобным заниматься. Кажется больше двенадцати лет назад в Москве, на уставшей съёмной квартире около метро Войковская, где мы с женой жили, когда я работал в «Яндексе».

Весной вызову спецов по окнам, пусть снимут, заодно и уплотнительную резинку попрошу поставить пошире, чтобы лучшая изоляция была.

6 комментариев

Инсайд из конного спорта

Жена и дочка уже больше трёх лет занимаются конным спортом и даже немного выступают на городских соревнования. И вот вам забавный факт из мира коняшек, который мне рассказала жена. По крайней мере мне он почему-то кажется забавным.

Во время езды на лошади, её охват постоянно уменьшается. Лошадь не стесняется пускать газы и наваливать кучи, пока ты на ней едешь.

Из-за этого долго спокойно ехать на ней не получается — начинаешь сползать вместе с седлом. Поэтому приходится спешиваться и подтягивать подпругу — ремень, затягиваемый под брюхом.

Добавлено: жена мне тут подсказывает, что спешиваться для этого совершенно не нужно, подпругу можно подтягивать прямо на ходу.

Девочка в шлеме и яркой куртке сидит верхом на коричневой лошади в снежном лесу, держит поводья и смотрит в камеру.
Дочка на лошадке по кличке Вепрь

Оставить комментарий

EV3 для ЕВЫ

Совершенно верно говорили мне читатели в комментариях к посту про «Лего Майндстормс» — для семилетнего ребёнка этот конструктор чересчур сложен. Но к тому моменту я его уже купил и подарил на день рождения.

Так он у нас с того дня и пролежал почти до новогодних праздников. Ранее мы с дочкой сделали одну попытку разобраться как с ним работать, но там надо было разыскать какие-то устаревшие уже программы, найти и скачать какие-то инструкции, в общем потерпели фиаско.

В новогодние дочь уговорила меня попробовать ещё раз, да мне и самому жалко — конструктор лежит без дела.

Решили собирать щенка. Не самая простая модель для сборки, должен сказать. Уже в первой трети процесса пожалел, что выбрали именно её.

Собрали за два дня с перерывами, инструкцию нашли на сайте «Robotsquare». Дольше разбирались что нужно, чтобы он заработал. Ожидаемо, что для каждого робота нужна своя программа, которая определяет его поведение. Для щенка она нашлась внутри приложения «EV3 Classroom», которую я нашёл на каком-то стороннем сайта. Заливал через блютуз, тут никаких проблем не возникло.

Ещё долго не мог разобраться как робот включается и что он вообще умеет. Пришлось читать программу, благо я ещё не забыл азы «Скретча» (когда-то немного смотрел его), заодно немного её модифицировал — снизил громкость храпа, а то «щенок» очень уж оглушительно спит.

На полу разобраны детали конструктора LEGO Mindstorms Education EV3, рядом открыт ноутбук с инструкцией по сборке и чёрные пластиковые контейнеры для хранения.
Собираем щенка. Потребовалась инструкция, ноутбук со специальным приложением, закачиваемая в «голову» щенка программа и море терпения

6 комментариев

«Щенок» из Лего Майндштормса

Один из читателей попросил показать как выглядит готовый «щенок», собранный из набора «Лего Майндштормс». Вот он, сидит на крышке набора.

Из активных элементов у него три мотора (два двигают задние лапы, один — голову), датчик цвета, который определяет, что ему дают «кость» (на фото кость лежит рядом) и датчик нажатия, который срабатывает, если погладить «собаку» по спинке.

Робот LEGO Mindstorms EV3 с ручкой рисует на крышке прозрачного контейнера, рядом лежат цветные кубики и шестерёнка.
Робот «Щенок» («Puppy») собранный из набора Лего Майндштормс

Программа робота крутится в цикле, в котором меняются несколько переменных, определяющих состояние робота — он может злиться, хотеть есть или спать и так далее. Кроме того, есть запрограммированные реакции на попытку его погладить или накормить. Не слишком разнообразно, дочка довольно быстро с ним наигралась.

Скриншот IDE с проектом «Щенок 3»: слева панель блоков управления моторами, справа — собранная программа из цветных блоков.
В центре — программа «щенка» на языке визуального программирования Scratch, слева — палитра операторов языка

Кажется использовать набор как конструктор для сборки чего-то готового не слишком увлекательно. Надо, может, подумать как научить дочку вносить модификации в программу, либо пока действительно купить что попроще, может там семилетнему ребёнку интересней будет. А «Майндстормс» оставить «на вырост».

13 комментариев

«Завещание профессора Доуэля»

В детстве я смотрел довольно известный в те годы фантастический фильм «Завещание профессора Доуэля». Сейчас он, кажется, совершенно забыт и, думаю, совершенно заслуженно.

Я не помню в чём была основная мысль фильма, наверное что-то про победу науки. Как вряд ли можно понять из названия, у одного из действующих героев нет тела, только голова, которая функционирует благодаря оригинальной методике.

В детстве фильм смотреть было хоть и интересно, но морально тяжело — не мог отделаться от воображения, рисующего мне мучения человека, оставшегося без тела.

Позже я узнал, что в СССР, во второй половине 1920-х годов проводились опыты по сохранению жизни голов, отделённых от тела. Правда — собачьих. Есть гипотеза, что автор книги, по которой сняли «Завещание…» почерпнул идею как раз из этих опытов.

Чёрно-белое фото лабораторной установки с колбами, трубками и кранами, соединёнными в систему для химического эксперимента или дистилляции.
На этом мутном кадре — установка для поддержания жизни в собачье голове, отделённой от тела

Есть даже документальное кино, где показан этот опыт и демонстрируется установка, поддерживающая жизнь такой головы. Я не хочу давать ссылки на эту жесть, мне жалко собак, если вам интересно, поищите сами.

Недавно я узнал, что сцены с собачьим головами в фильме, к счастью, были фальсификацией:

[…] показана отделённая от тела собачья голова. Она присоединена к аппарату и остается живой — реагирует на щекотку перышком, моргает и облизывается. Закадровый голос рассказывает, что подключенная к автожектору голова остается в таком состоянии в течение многих часов. Однако позже свидетели экспериментов Брюхоненко рассказали, что поддерживать собачьи головы в таком состоянии удавалось лишь несколько минут. А знаменитую сцену из фильма сейчас считают фальсификацией.

— Пётр Талантов, «0,05. Доказательная медицина от магии до поисков бессмертия», 2019

Эти опыты производились, разумеется не из садизма, их проведение помогло создать первый в мире аппарат искусственного кровообращения, но лично мне очень тяжело знать на что для этого пришлось пойти.

8 комментариев

Блеск и нищета нейросетевых рисунков

У меня начисто отсутствует навык любования художественной фотографией. Например, когда в гостях у известного казанского фотохудожника Евгения Канаева мне дали в руки несколько его работ, я из вежливости их полистал и, не почувствовав интереса, отложил. Видимо отсутствует насмотренность, не развиты нужные кусочки мозга.

Возможно это из-за того, что я излишне смотрю на детали и меньше на картину целиком. Из-за этого быстро сошло на нет моё бурное увлечение рисованием нейросетями. Было действительно интересно до чего техника дошла, но когда исчез эффект новизны, вскрылась правда — в деталях частенько кроется дьявол. Я уже высказывался против нейросетевой колоризации, которой все в одно время сильно злоупотребляли, сейчас хочу высказаться по поводу генерации изображений.

Группа пушистых кошек в красных шапках Санты сидит у ёлки с красными и синими шарами на деревянном полу.
Пример сгенерированной нейросетями иллюстрации на сайте Exler.RU. Самая заметная нелепо нарисованная деталь — глаза кошек

Безусловно иллюстрация иллюстрации рознь, если постараться, при помощи нейросетей можно нарисовать очень реалистичное изображение. Если повезёт, может получиться даже с первого-второго раза.

Беда в том, что людям закономерно заморачиваться не хочется, а детали кажутся несущественными. По правде говоря, сначала, пока вау-эффект застилал глаза, мне тоже казалось, что и так нормально. Но чем больше я вижу таких изображений, тем более кринжовым кажется их использование.

Очень надеюсь, что качество нейросетей будет прогрессировать быстрее, чем моё недовольство несуразицами в деталях, а то хоть в интернет не ходи.

Оставить комментарий

Реанимация акаровского выключателя

У дочки в комнате перестал работать акаровский (Aqara) «умный» выключатель — реле внутри щёлкает, но эффекта нет. Благо у меня с незапамятных времён лежал запасной, точно такой же.

Снял сломавшийся, поставил новый, но вот незадача — не хочет привязываться к сяомишному хабу. С яндексовской «Станцией» ещё более странно — привязывается, но на на команды реакции нет.

Вспомнил, что пару лет назад с такой бедой уже сталкивался. Вычитал тогда, что нужно обновить прошивку выключателя. Да, у выключателей нынче есть прошивка. Засада в том, что для этого нужен акаровский хаб, а у меня его нет.

К моему счастью, у одного сотрудника на работе оказалось нужное устройство, оно у него лежало без дела. Попросил на вечер и не успел глазом моргнуть, хаб обновил прошивку и теперь выключатель прекрасно работает.

Интерфейс умного дома: вкладки «Детская», «Зал», «Кабинет». Карточки устройств: выключатель ванной, кондиционер, лампа, очиститель, светильники, часы, экран, Яндекс Лайт.
После всех манипуляций выключатель Aqara (заведён как два светильника) заработал с хабом Xiaomi Smart Home

Оставить комментарий

Сюрпризы зарядки автомобилей

Расскажу немного о гибридном автомобиле, который мы недавно купили. Для наших широт это пока ещё экзотика, так что многие, включая меня, не до конца понимают с чем столкнутся.

Первое, что я узнал после покупки «гибрида», что разъёмов зарядок сильно больше одного. До этого момента я об этом как-то не задумывался.

Например, на подземной стоянке, где у нас машиноместо европейский Type 2, а в машине — китайский Gb/T.

Пришлось покупать переходник, благо их полно на любом интернет-базаре, да и найти их можно по нормальным ценам, особенно, если вам не срочно. Хотя за пластиковую фигню с проводами внутри и пара тысяч — довольно дорого, как по мне.

При этом бывают ещё Type 1, CHAdeMO, CCS Combo 1, CCS Combo 2 и наверняка что-то ещё, я просто не знаю. Недавно человечеству удалось навести порядок в зарядках сотовых телефонов, на очереди, надеюсь, ноутбуки, а когда дело дойдёт до автомобилей, не известно никому.

Белый зарядный разъём с оранжевым кабелем вставлен в зарядный порт красного электромобиля; рядом видна часть фары и столб с жёлто-чёрной разметкой.
«Тесла» заряжается через переходник на подземной парковке. Это не моя машина, просто мимо проходил и сфоткал

Вторая новость похуже: вопреки распространённому мнению, гибридный автомобиль не означает экономию на заправке.

Точнее, может и означать, это смотря как ездить и где заряжать, но в общем случае этого может не случиться. В моём — не случилось. В нашем случае это не проблема, так как экономия на топливе это не то, для чего мы покупали меняли машину, но такой бонус, конечно, не повредил бы.

24 комментария

Всякое дочкино

Всё пытаюсь не лениться и выкладывать всякие штуки, которая дочка делает. Вряд ли оно сохранится в физическом виде — чтобы это всё хранить, надо целый склад арендовать, зато в интернете вполне может дожить до времени когда ей будет любопытно порассматривать что она делала в детстве. Возможно даже что-то из этого поможет вспомнить что-нибудь интересное.

Акварельный рисунок зимнего городка: разноцветные домики с горящими окнами, снеговик в красном шарфе, ёлки и дым из труб на фоне голубого неба.
Свежий рисунок из художественной школы «Дашка»
Керамическая тарелка в виде тоста с глазками и румянцем, на которой лежит маленький квадратный кусочек масла с лицом.
Глиняная тарелочка с гончарного мастер-класса
Два рождественских пряника на деревянном столе: снежинка с белой и голубой глазурью и ёлка с зелёной глазурью, украшенная конфетти и фигурками.
Пряники со школьного мастер-класса, часть мы уже съели, сфотографировал остатки

2 комментария

Счёт в «Сбере»

Для продажи квартиры, из которой мы переехали в новую, пришлось завести счёт в «Сбере» — ипотечному банку покупателя так удобнее. Я обычно старательно избегаю связываться с этим банком, хотя в прошлом у меня был там счёт и даже сберкнижка сохранилась.

В комментариях к посту, где я выкладывал сберкнижку, читатели порекомендовали сходить в «Сбер», посмотреть не остались ли у меня там счёта, но я махнул на это рукой — если что-то и могло остаться, то с какой-нибудь незначительной суммой.

Тем более на сайте налоговой недавно появился раздел со всеми счетами гражданина и в моём личном кабинете счёта «Сбера» не оказалось. Зато до сих пор висит счёт «Росбанка», который я уже два раз пытался закрыть дистанционно.

В общем, после посещения «Сбера» оказалась, что налоговая знает не обо всех моих счетах. При проверке документов «всплыл» счёт 2004-го года, на котором лежала баснословная сумма в 4,47 рублей, — все мои проценты за двадцать лет.

Выписка по вкладу Степанищева Е.В. в Сбербанке: универсальный на 5 лет, ставка 0,01%, срок 1827 дней, валюта рубль РФ, остаток 4,47 руб. на 17.01.2024.

11 комментариев

Казань завалило

На днях в Казани выпало какое-то необычайное количество снега. Несмотря на усилия коммунальных служб, его всё равно столько, что местами ходить приходится где-то на уровне крыш полностью засыпанных машин. Бедные автовладельцы сегодня целый день пробираются к своим машинам с лопатой в руках.

В рабочих чатах причитают ребята с загородной недвижимостью, а у Евы отменили занятия в школе — всё из-за погоды.

Обычно я не люблю зиму, но оказалось, что именно такая зима — многоснежная, тёплая мне нравится. С удовольствием смотрю на неё как через окно, так и безо всякой преграды. Собака тоже рада — прыгает по сугробам, как кролик.

Короче, если бы так было все три зимних месяца, я был бы рад, но коммунальщикам пришлось бы несладко.

Большая снежная куча на переднем плане, за ней — многоэтажный жилой дом и голые деревья под пасмурным небом.
Коммунальные службы — молодцы, но их усилий явно недостаточно

Оставить комментарий

«Виселица» в магазине приложений

Я долго не знал как выглядит наша с дочкой игра «Виселица» в магазине приложений «Флиппера Зеро» — смартфон-то у меня «Хуавей», а под него нужного приложения нет.

А на днях вспомнил, что походный-то смартфон у меня с обычным «Андроидом»! В общем посмотрел, даже скриншот снял на память. Надо бы, кстати, выпустить новую версию — у меня там есть досадная опечатка в английской локализации — loose, вместо lose.

Скриншот страницы приложения Hangman для Flipper: версия 1.4, размер 92,11 КБ, кнопка INSTALL, описание игры и changelog — добавлены испанский и татарский языки, исправлены ошибки.

Честно сказать, необходимость постоянно использовать какие-то дополнительные приседания, чтобы поставить часть приложений на «Хуавей» меня сильно утомила. Думал, что смогу с этим жить, но нет. Продержался более трёх лет, но сил моих больше нет. Кажется буду переходить. Вот только на что ещё не решил.

20 комментариев

Оpанжевое небо, оpанжевое моpе…

Похоже многие думают, что оранжевый — мой любимый цвет. На прошлой неделе в очередной раз об этом спросили.

Причина есть — уже не первую зиму хожу в оранжевой куртке, в оранжевой же шапке, с рюкзаком с оранжевыми вставками и даже чехол на «Флиппер Зеро» купил тоже оранжевый.

Вроде никакой особой слабости именно к этому цвету я не питаю, как-то случайно так получилось. Купил куртку (не из-за цвета), а к ней подбирал уже всё остальное. С «Флиппером» у меня тоже оправдание есть — он сам по себе бело-оранжевый.

А вот какой цвет у меня любимый я сказать затрудняюсь, раньше были какие-то предпочтения, но со временем стёрлись. Сейчас не могу сказать, что я какой-то один цвет выделяю больше других.

Оранжевая стёганая куртка Tretorn с капюшоном, оранжевая шапка KUSTO и чёрная сумка с оранжевым устройством на деревянном полу.
Вроде ничего оранжевого у меня больше нет

4 комментария

С новым, 1952 годом

В прошлом году на чердаке одного из казанских домов, куда меня пустили осмотреться, нашёл стопку новогодних писем, датированных 1950-ми годами. Часть сложена треугольничком, на манер писем времён Великой Отечественной войны, все они написаны детской рукой и адресованы некой Людмиле Романенко от подружек. Я забрал их с собой — дом давно расселён, новым хозяевам они не нужны.

В тот момент у меня возникла идея публиковать каждый день нового года по письму, благо в них нет ничего личного. Но в праздники пришлось работать, я заболел, кроме того наложилась покупка новой машины, поэтому мне было совсем не до этого.

Время я упустил, теперь никак не могу решить — опубликовать их сейчас или потерпеть до нового Нового года. Идея их выложить сюда на даёт мне покоя, но кажется привязать это к праздникам было бы интереснее.

Шесть старых новогодних открыток и записок 1952–1953 гг. с рукописными поздравлениями, рисунками ёлок и надписями «С Новым годом!» на деревянном столе.

8 комментариев

Глубокая зима

У нас в Казани прям зима-зима, всё в глубоком снегу, дворники копают ходы в снегу, как в детстве, — местами в мой рост. Я уже писал, что мне такая обстановка очень нравится, — красиво, да и теплее стало, но с таким уровнем осадков свои сложности — вчера шёл с работы пешком, потому что весь центр стоял наглухо, а сегодня школьный автобус забрал дочку на двадцать пять минут позже расписания. Весь мой утренний распорядок пошёл коту под хвост.

Оставить комментарий

UTF-8 на ARM

Пока проект внедрения Юникода во «Флиппер Зеро» на паузе, — разработчики занимаются обновлением одной из важных библиотек, я вспомнил, что вообще-то в природе существуют разные способы ускорения обработки строки в кодировке UTF-8. Именно её я выбрал для хранения строк. А поскольку железо у «Флиппера» весьма ограниченное, может быть имеет смысл подумать как сэкономить ресурсы.

Например, когда-то, ещё во времена работы в «Яндексе», я сравнивал между собой различные реализации функции strlen, где ускорение достигалось за счёт векторизации.

Любопытно посмотреть как обстоят дела с ускорением таких вещей на процессоре, который установлен на «Флиппере». Правда до него у меня руки ещё не дошли, но я уже потренировался на своём «Макбуке», благо тут процессор той же архитектуры.

Идея всё та же — векторизация. За референс я взял наивную реализацию с перебором по одному байту:

size_t strlen_naive(const char* str) {
    size_t len = 0;
    char ch;
	
    while ((ch = *str++)) {
        len += (ch & 0b11000000) != 0b10000000;
    }

    return len;
}

Попробовал несколько вариантов, но лучше всех показали себя две функции: та, которую я упоминал в первом абзаце и переделанная нашими общими с братишкой усилиями реализация, найденная в недрах PHP.

После переделки она стала выглядеть так:

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 >= -64) {
            len++;
        }
    }

    return len;
}

Повторюсь, у меня пока не дошли руки попробовать это всё на «Флиппере», но на моём «Макбуке» результаты выглядят следующим образом. Это десять тысяч прогонов на русскоязычном тексте, размер которого чуть больше ста тысяч символов.

Name   Length  Time
----   ------  ----
PHP    117465   97797
Fast   117465  143780
Naïve  117465  531535

Не скажу, что я делал всё как положено, — надо бы считать среднее и отклонение, разносить по разным файлам, научиться прибивать процесс к производительным ядрам, но разница в результатах достаточно показательна (я запускал несколько десятков раз), поэтому, как мне кажется, и так нормально.

Цифры в попугаях (больше — хуже), которые выдаёт сишная функция clock(), компилировал компилятором Clang 15 с ключом -O3.

13 комментариев

Определяем границу символа в UTF-8

В Телеграме попросили рассказать как работает код, который я приводил вчера в заметке про ускорение функции, возвращающей количество символов в строке с кодировкой UTF-8.

Там действительно есть что рассказать, но рассказ придётся разбить на несколько частей. Я постараюсь по возможности не погружаться в дебри. В этой части начну с того, что расскажу чем вообще необычна эта кодировка.

Все кодировки условно можно разделить на две части: кодирующие символ фиксированным или переменным количеством байт. К первым можно отнести, например, CP1251, когда-то широко используемую в ОС «Виндоуз» — там символ кодировался одним байтом, ко вторым — UTF-8, где один символ может занимать от одного до четырёх байт.

Справедливости ради, есть и другие виды кодирования, но нам их рассматривать ни к чему.

Тут важно то, что для строки в UTF-8, нельзя получить её длину, подсчитав количество байт и разделив их на коэффициент хранения. Для каждого байта нам надо понять что он кодирует и считать только те байты, которые отвечают за начало символа. Как это сделать?

Посмотрим на картинку из «Википедии», которая показывает как устроена эта кодировка:

Таблица с тремя столбцами: «Количество октетов» (1–4), «Значащих бит» (7, 11, 16, 21) и «Шаблон» — бинарные маски вида 0xxxxxxx, 110xxxxx 10xxxxxx и т.д.

Тут нам интересна только колонка «шаблон», где видно, что все «внутренние» байты символов начинаются с одной и той же сигнатуры — старший бит установлен, младшие — сброшены.

То есть, байты в диапазоне от 10000000 до 10111111 (в бинарном представлении) — внутренние байты, остальные — начало символа. Опять же, согласно таблице начала попадают в диапазоны 00000000-01111111 и от 11000000 до 11011111.

Умные люди заметили одну закономерность, сейчас мы её тоже увидим. Давайте напишем небольшую программу:

#include <stdio.h>

int main() {
    const signed char arr[] = {
        0b10000000, 0b10111111, 0b00000000, 0b01111111, 0b11000000, 0b11011111
    };

    for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
        for (int b = 128; b; b >>= 1) {
            printf("%d", (arr[b] & i) > 0);
        }

        printf(" % d\n", arr[i]);
    }
}

Вот что она выводит (диапазон, в котором находятся внутренние байты, я выделил другим цветом):

Скриншот терминала: вывод программы experiment.c, скомпилированной gcc, показывающий пары двоичных чисел и их десятичные значения.

Закономерность в том, что все внутренние байты в знаковом представлении по значению меньше −64. Это довольно дешёвая проверка с точки зрения машинного кода, что очень хорошо, так как наша цель — производительность.

Про остальное — в следующий раз.

Оставить комментарий

Надёжность устройств «умного дома»

Недавно приятель в разговоре про «умный» дом (он тоже потихоньку докупает себе всякие компоненты, но ещё не подключал их друг другу) спросил у меня про надёжность различных компонентов — то есть насколько часто у меня что-то выходит из строя.

У меня около семидесяти устройств, это довольно много, но с выходом чего-либо из строя я почти не сталкивался. Всё что могу вспомнить — года полтора назад вышел из строя датчик утечки воды и недавно один за другим вышли из строя два акаровских выключателя, один сам по себе, второй после попытки перепривязать его к другому хабу.

Как будто это не так много.

P. S. про Юникод продолжу завтра. По крайней мере так планирую.

7 комментариев

Разбор быстрого подсчёта длины строки в UTF-8

Давайте попробуем всё-таки разобраться как работает быстрое вычисление длины строки в кодировке UTF-8. В прошлый раз мы узнали, что для этого нам надо подсчитать все байты, которые будут больше или равны −64.

Напомню как выглядел код:

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 >= -64) {
            len++;
        }
    }

    return len;
}

Для ускорения подсчёта в алгоритме используется векторизация, — это когда мы работаем с пачкой чисел, делая над каждым из них какое-то действие за одну операцию. В данном случае используется вектор 8×16 — шестнадцать значений по восемь бит (типы uint8x16_t и int8x16_t).

Вектор загружается функцией vld1q_s8, где коды символов считываются по адресу, записанному в указателе p. В дальнейшем мы будем его сдвигать на размер вектора, чтобы забирать следующую пачку данных.

Ниже используется функция vminvq_u8, которая вычисляет минимальное значение в векторе, рассматривая его как набор байтов без знака. Если там ноль, значит строка кончилась и в нашем векторе — хвост, который надо досчитать обычным способом, без вектора. Тут можно было бы проверить на какой позиции слева находится признак конца строки, если на самой последней, то строка была кратна вектору. Но я не стал заморачиваться. Но такая проверка оказалась медленнее подсчёта длины хвоста обычным способом.

Дальше функция vcltq_s8 сравнивает каждый байт в векторе со значением −64  — это значение загружается в каждый элемент вектора для сравнения функцией vdupq_n_s8.

Результирующий вектор заполняется значениями 0 или 255, в зависимости от результата сравнения. Функция vandq_u8 производит операцию «И» с единицей, после чего у нас в векторе ноль остаётся неизменным, а 255 превращается в единицу. Эти единицы мы суммируем функцией vaddvq_u8.

Теперь у нас получился вектор, в котором подсчитаны все внутренние байты символов, а чтобы подсчитать внешние, надо вычесть это число из длины вектора. Правильнее было бы инвертировать сравнение, до этого в разгаре экспериментов просто не дошли руки.

Полученное число мы добавляем к вычисляемой длине и сдвигаем указатель. В конце досчитываем хвост обычным циклом. Конец алгоритма.

Оставить комментарий

Чуть более быстрый подсчёт длины строки в UTF-8

Сегодня очень плохо спал — всё время просыпался, потом долго ворочался, не мог уснуть. Утром оказалось мозг никак не мог успокоиться после вчерашней заметки про разбор быстрого алгоритма для подсчёта длины строки в UTF-8 при помощи векторизации для процессоров ARM.

Вчера я остановился на том, что у разбираемого способа есть две очевидные недоработки — ненужное вычисление, которое решается инвертированием условия и подсчёт «хвоста», который всегда вычисляется «классическим» способом — без векторизации, хотя если строка у нас кратна вектору, можно было бы этого избежать.

Первый недостаток исправлялся очень просто, а хорошая реализация второй проверки мне вчера в голову не пришла.

Зато, когда я проснулся, она уже была у меня в голове. Всего три операции — первой получаем вектор, где на позициях с ненулевым байтом записывается 255, потом делается операция «И» с номерами позиций и весь вектор суммируется.

В итоге, если ноль стоит в векторе только на крайней правой позиции, у нас получается сумма арифметической прогрессии без последнего элемента.

По замерам такой вариант чуть быстрее.

size_t strlen_utf8(unsigned char * p) {
    size_t len = 0;

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

    for(;;) {
        int8x16_t operand = vld1q_s8((const int8_t * ) p);
        if (vminvq_u8(operand) == 0) {
            uint8x16_t pos = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
            uint8_t sum = vaddvq_u8(vandq_u8(vtstq_u8(operand, operand), pos));

            // арифметическая прогрессия без последнего члена
            if (sum == 16*(16+1) / 2 - 16) {
                uint8x16_t gt = vcgtq_s8(operand, threshold);
                return len + vaddvq_u8(vandq_u8(gt, delta)) - 1;
            } else {
                break;
            }
        }

        uint8x16_t gt = vcgtq_s8(operand, threshold);
        len += vaddvq_u8(vandq_u8(gt, delta));
        p += sizeof(uint8x16_t);
    }

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

    return len;
}

2 комментария

Дискета на 3,5 дюйма

Добавлено: разоблачения не произошло. Дискета действительно 90 миллиметров, у меня просто линейка кривая.

Прочитал в «Википедии», что дискеты 3,5 дюйма, якобы, не такого размера:

Дискета имеет метрический размер (90 мм в ширину и 94 в длину), но запомнилась именно как «трёхдюймовая» (3,5″ — это чуть меньше, 88,9 мм).

Нашёл дома одну-единственную дискету, которую всё никак не могу выкинуть, просто потому что не знаю что на ней.

Померил — около 89 миллиметров, не знаю точно ли 88,9, по линейке особо не прикинешь, но не 90 — точно. Заказал на одном из интернет-базаров ещё одну дискету. Померил — тоже около 89.

В «Википедии» опять кто-то неправ.

Добавлено: в ЖЖ, куда у меня транслируется мой бложек, высказали предположение, что у меня, возможно, что-то не так с точностью линейки. Надо подумать где взять штангенциркуль.

Две чёрные 3,5-дюймовые дискеты на деревянном столе: левая с этикеткой «Driver & Utility» и списком моделей видеокарт (SIS 6202, S3 64, RTVGA и др.), правая — без надписей.
Нашёл одну дискету дома, вторую купил

17 комментариев

Лайфхак: как надеть ботинок

От чего мои читатели, кажется, были до сих пор избавлены, так это от моих ценных лайфхаков. Тем не менее, этот мне нравится настолько, что хочу поделиться им широкой общественностью. Это знание слишком ценно, чтобы им владел я один.

Если вам приходится надевать ботинок с жёстким задником где-то, где нет ложки, засуньте под пятку что угодно тонкое и прочное — идеально подойдёт небольшой пакет или бахила. Можно даже подложить край брюк или джинс, правда для этого придётся их приспустить, что не всегда удобно.

После этого потихоньку вдавливаем пятку в обувь, а то, что подложили, равномерно и медленно вытягиваем вверх вдоль задней поверхности ноги. Обычно получается почти сразу.

Чёрные лакированные ботинки с жёлтой вышивкой в виде короны и дракона, зелёные носки с узором из красных и синих элементов, джинсы на сером ковролине.
Картинка моего ботинка, чтобы было проще визуализировать этот способ надевания

2 комментария

← сюда туда →