C++95
ban.png
#cringe #books
На данном скриншоте - последствие того, как автор поста на два дня положил систему для практикума форк-бомбой.
Но не стоит за него волноваться - он только получил отстранение от занятий на три недели, потом успешно выпустился из учебного заведения с дипломомбаландёра бакалавра и забыл его как страшный сон.
Обзор книги "Введение в язык Си++" (2012/2020 г.) 📚🤪
Jeder lacht, jeder lacht — ja
Все смеются, все смеются, да
Jeder lacht über dich
Все смеются над тобой
В #books есть обзоры на хорошие книги, но не хватает обзоров на примеры, каких книг не стоит писать. Я решил, что надо обзирать какой-нибудь университетский учебник, потому что его эффект более разлагающий.
Под руку попалось творчество уже знакомого нам Столярика. Уважаемый телезритель может засомневаться - нет ли у меня предвзятого отношения к нему? Нет - просто других методичек почти нет, и они слишком плохи, чтобы быть интересными.
Третья редакция опуса от 2012 года находится тут, мы будем кринжевать с нее. Ради справедливости, уже есть пятая редакция 2020 года (тут), но она слабо отличается от третьей - убрана часть фактических ошибок и добавленыновые ошибки рандомные факты, а про rvalue и фичи стандартов не рассказали (потому что Столяров не признает стандарты).
Книжка намеренно небольшая, потому что рассчитана на 6-8 лекций. За 4 года бакалавриата на C++ больше времени не находится, ведь так в учебный план не поместятся философия, урматы и основы экономики.
А ведь плюсы это такая глыба, что полный справочник позволяет Столярову обороняться от своих многочисленных врагов...🔫 👀 🔫
😈
Языки упорно называются "Си" и "Си++", одобряем патриотический перевод👍
В главе
На примере показывается полезность инкапсуляции в C++. К сожалению, не описана типичная Сишная идиома для инкапсуляции opaque data type, что было бы к месту для тех, кто переучивается с С на C++.
В главе про
Там же рекомендуется передача переменной через константную ссылку:
ПРОДОЛЖЕНИЕ В КОММЕНТАРИИ
На данном скриншоте - последствие того, как автор поста на два дня положил систему для практикума форк-бомбой.
Но не стоит за него волноваться - он только получил отстранение от занятий на три недели, потом успешно выпустился из учебного заведения с дипломом
Обзор книги "Введение в язык Си++" (2012/2020 г.) 📚
Jeder lacht, jeder lacht — ja
Все смеются, все смеются, да
Jeder lacht über dich
Все смеются над тобой
В #books есть обзоры на хорошие книги, но не хватает обзоров на примеры, каких книг не стоит писать. Я решил, что надо обзирать какой-нибудь университетский учебник, потому что его эффект более разлагающий.
Под руку попалось творчество уже знакомого нам Столярика. Уважаемый телезритель может засомневаться - нет ли у меня предвзятого отношения к нему? Нет - просто других методичек почти нет, и они слишком плохи, чтобы быть интересными.
Третья редакция опуса от 2012 года находится тут, мы будем кринжевать с нее. Ради справедливости, уже есть пятая редакция 2020 года (тут), но она слабо отличается от третьей - убрана часть фактических ошибок и добавлены
Книжка намеренно небольшая, потому что рассчитана на 6-8 лекций. За 4 года бакалавриата на C++ больше времени не находится, ведь так в учебный план не поместятся философия, урматы и основы экономики.
А ведь плюсы это такая глыба, что полный справочник позволяет Столярову обороняться от своих многочисленных врагов...
Полное описание всех возможностей языка и его стандартной библиотеки представляет собой книгу такого объёма, что ею вполне можно при желании воспользоваться в качестве оружия против врагов (в смысле чисто физическом).Предполагается, что читатель уже знает язык C и с него переучивается на C++, там описывается разница между языками
Для изучения базовых средств языка Си++ вам потребуется уверенное владение языком СиЗвучит аналогично тому, чтобы изучить французский язык, надо сначала выучить латынь (откуда le français произошел), а потом выучить дифф между латынью и французским
Языки упорно называются "Си" и "Си++", одобряем патриотический перевод
В главе
Язык Си++ и его совместимость с Си
нет ни слова про действительную совместимость языков через extern "C"
.В языке Си++ введен механизм **защиты**, который позволяет запретить доступ к некоторым частям структурыИнтересно, как "инкапсуляцию" перевели как "защиту"... Еще можно переводить "полиморфизм" как "превентивный удар", а "наследование" как "хлопо́к". Там много такого надмозгового перевода.
Мы могли бы написать и так:Фразу "unnamed object" из Стандарта лучше перевести как "безымянный объект". Но лучше бы были рассмотрены категории выражений (
double mod = str_complex(2.7, 3.8).modulo();
В последнем случае мы создали временную **анонимную переменную** типа `str_complex`
lvalue/rvalue
и их подвиды) и их поведение, вместо этого всё объясняется "на пальцах" и размыто, а про move-семантику нет ни слова.На примере показывается полезность инкапсуляции в C++. К сожалению, не описана типичная Сишная идиома для инкапсуляции opaque data type, что было бы к месту для тех, кто переучивается с С на C++.
В главе про
const
ничего не сказано про ключевые слова constexpr
и (!) mutable
, что плохо, потому что не складывается понимание что это слово про логическую константность, а не физическую.Там же рекомендуется передача переменной через константную ссылку:
Так, если в описанном ранее классе `Complex` вместоПо крайней мере для 16-байтовых типов это неверно - их на x86-64 выгоднее передавать через копию. В проектах можно использовать чекер clang-tidy: пример проверки на godbolt.
Complex operator+(Complex op2) { ... }
написать
Complex operator+(const Complex &op2) { ... }
семантика кода не изменится, но физически вместо копирования двух полей `double` будет происходить передача адреса ...
ПРОДОЛЖЕНИЕ В КОММЕНТАРИИ
Please open Telegram to view this post
VIEW IN TELEGRAM
#opensource
Обзор на TeX📖
Ist doch so gut gewürzt und so schön flambiert
Так хорошо приправлено и красиво обжарено
Und so liebevoll auf Porzellan serviert
И с любовью подано на фарфоре
Dazu ein guter Wein und zarter Kerzenschein
Под хорошее вино и нежный свет свечей
Ja, da lass ich mir Zeit, etwas Kultur muss sein
Да, я не тороплюсь, капля культуры должна быть!
В опенсорсе самым 𝓪𝓮𝓼𝓽𝓱𝓮𝓽𝓲𝓬𝓪𝓵 проектом является скорее всего TeX от Дональда Кнута. Это система для создания красивых документов, особенно для научных работ и технических книг📖 Многие хотя бы раз его использовали, например для описания математических формул.
Про него есть много информации, но почти вся поверхностная. Стало интересно, что там внутри.
Можно смотреть "снизу вверх":
1️⃣ Шрифты - набор изображений символов (обычно векторных), сейчас популярен формат TrueType.
Векторные изображения переводятся в пиксельные на мониторе с приколами наподобии хинтинга и ClearType.
Многие стандартные шрифты имеют разное начертание для разных размеров, чтобы выглядело красивее. То есть буквы в 10м кегле (10pt) это не то же самое, что увеличенные в два раза буквы из 5pt🤵
Есть шрифты, где записаны математические значки или другие символы в векторном виде, например знак ⚠️, это удобнее чем вставлять картинки.
Это обширная тема, в линуксе даже есть мемчик "шрифты говно"💩
2️⃣ Формат файлов DVI - выходной файл TeX. Чтобы "прочитать" этот файл, надо хранить состояние из нескольких переменных и выполнять "команды" из файла побайтово. Например, команда
Этот файл не содержит в себе шрифтов, а только "ссылается" на них, и знает из шрифта высоту/длину/глубину символов. На картинки он тоже только ссылается, и дефолтные DVI-просмотрщики не показывают их.
Смысл этого формата - получать один и тот же документ на любом компьютере🖥
3️⃣ TeX - сам набор программ и язык разметки.
Самая подробная информация есть в книге от автора The TeXbook в 400+ страниц, можно пропускать слишком подробные куски🔍
В других книгах как обычно выкинут 80% информации и еще неправильно переведут (например, "инкапсуляцию" как "защиту").
У ванильного TeX примерно 900 команд, но только ~300 команд являются базовыми. Например, команда
📄
В The TeXbook описано, как текст из .tex-файла переводится в токены, какие есть категории токенов (глава 8)
В отличие от WYSIWYG-редакторов, TeX работает на уровне абзаца, а не строки, и распределяет слова по отдельным строкам так, чтобы минимизировать метрику badness.
В TeX есть понятие "клей" (glue) - это объект-отступ между разными сущностями TeX🔺 "Клей" после запятой растягивается в 1.25 раз больше, чем "клей" между соседними словами, а "клей" после точки/знака
"Клей" может быть бесконечно растяжимым/сжимаемым, например команда
Есть огромная куча костылей, чтобы менять любое правило.
Например, чтобы написать в документе
Чтобы было нельзя перенести
Можно поставить одинаковый glue stretching (после слов, запятых и точек) командой
Можно сформировать длины строк в форме полукруга (в The TeXbook есть примеры) командой
ПРОДОЛЖЕНИЕ В КОММЕНТАРИИ
Обзор на TeX
Ist doch so gut gewürzt und so schön flambiert
Так хорошо приправлено и красиво обжарено
Und so liebevoll auf Porzellan serviert
И с любовью подано на фарфоре
Dazu ein guter Wein und zarter Kerzenschein
Под хорошее вино и нежный свет свечей
Ja, da lass ich mir Zeit, etwas Kultur muss sein
Да, я не тороплюсь, капля культуры должна быть!
В опенсорсе самым 𝓪𝓮𝓼𝓽𝓱𝓮𝓽𝓲𝓬𝓪𝓵 проектом является скорее всего TeX от Дональда Кнута. Это система для создания красивых документов, особенно для научных работ и технических книг
Про него есть много информации, но почти вся поверхностная. Стало интересно, что там внутри.
Можно смотреть "снизу вверх":
Векторные изображения переводятся в пиксельные на мониторе с приколами наподобии хинтинга и ClearType.
Многие стандартные шрифты имеют разное начертание для разных размеров, чтобы выглядело красивее. То есть буквы в 10м кегле (10pt) это не то же самое, что увеличенные в два раза буквы из 5pt
Есть шрифты, где записаны математические значки или другие символы в векторном виде, например знак ⚠️, это удобнее чем вставлять картинки.
Это обширная тема, в линуксе даже есть мемчик "шрифты говно"
set_char_a
как бы "печатает" в текущем месте один символ a
и сдвигает курсор вправо на ширину символа a
.Этот файл не содержит в себе шрифтов, а только "ссылается" на них, и знает из шрифта высоту/длину/глубину символов. На картинки он тоже только ссылается, и дефолтные DVI-просмотрщики не показывают их.
Смысл этого формата - получать один и тот же документ на любом компьютере
Самая подробная информация есть в книге от автора The TeXbook в 400+ страниц, можно пропускать слишком подробные куски
В других книгах как обычно выкинут 80% информации и еще неправильно переведут (например, "инкапсуляцию" как "защиту").
У ванильного TeX примерно 900 команд, но только ~300 команд являются базовыми. Например, команда
\TeX
для вывода лого TeX является макросом для такой последовательности:T\kern -.1667em\lower .5ex\hbox {E}\kern -.125emXТо есть печатается символ
T
, потом печатается E
со сдвигом от изначального места немного вниз и влево, потом печатается X
со сдвигом влево В The TeXbook описано, как текст из .tex-файла переводится в токены, какие есть категории токенов (глава 8)
В отличие от WYSIWYG-редакторов, TeX работает на уровне абзаца, а не строки, и распределяет слова по отдельным строкам так, чтобы минимизировать метрику badness.
В TeX есть понятие "клей" (glue) - это объект-отступ между разными сущностями TeX
!
/знака ?
соответственно в 3 раза больше."Клей" может быть бесконечно растяжимым/сжимаемым, например команда
\centerline
это макрос\line {\hss #1\hss }Команда hss ставит бесконечный "клей", и TeX располагает параметр макроса (то есть
#1
) ровно в центр строки.Есть огромная куча костылей, чтобы менять любое правило.
Например, чтобы написать в документе
Mr. Evil
с отступом как между соседними словами (а не с х3 отступом как для нового предложения) надо писать Mr.\ Evil
.Чтобы было нельзя перенести
Evil
на следующую строку без Mr.
, надо писать Mr.~Evil
(~
это тот же пробел).Можно поставить одинаковый glue stretching (после слов, запятых и точек) командой
\frenchspacing
.Можно сформировать длины строк в форме полукруга (в The TeXbook есть примеры) командой
\parshape
, и так далее...ПРОДОЛЖЕНИЕ В КОММЕНТАРИИ
Please open Telegram to view this post
VIEW IN TELEGRAM
#story
Как проходит отбор к межнару по информатике🚬
Я подумал, о чем бы написать в канал, чтобы он не пустовал, и решил, что эта тема сойдет😁 Про C++ тоже будет.
🅰️ 🅰️ 🅰️ 🅰️ 🅰️ 🫥 1️⃣
КалибровкаDota MMR рейтинга Codeforces
Однажды я как обычно отсиживал время в своей школе, и кто-то сказал что бывают некие "олимпиады", с помощью которых можно поступить в любой вуз без экзаменов, но это не точно👦
Я был не уверен, что мне особо нужен "топовый" (будто бы) вуз, что я вывезу если там сложно учиться и так далее🚬 Но идти в рандомный ПТУ из-за слитых экзаменов тоже не хотелось.
Отнесся скептически, слово "олимпиады" ассоциировались со скучным занятием для ботанов🤓 Стало просто интересно, за что дают ход в любой вуз.
Узнал, что в этом олимпиаде есть несколько этапов (школа/город/область/финал). Открыл Codeforces, который в интернете советовали для подготовки. Порешал там что-то (🔍 первый день).
Спустя какое-то время пару раз поучаствовал на Codeforces в "раундах" (их правила), по их результатам перерасчитывается твой рейтинг.
После этого я стал поехавшим на теме Codeforces🤪
Cледующие два года я постоянно решал на нем задачи, на уроках с телефона читал разборы раундов и алгоритмов, прорешивал старые задачи, и не мог дождаться нового раунда.
Прикол в том, что Codeforces превращает решение обычных алгоритмических задач в рейтинговую игру🎮
В стандартном раунде дается 5 задач на 2 часа.
В самом начале задачи стоят 500-1000-1500-2000-2500 баллов, они отсортированы по сложности: первую решают почти все, последнюю единицы (из многих тысяч участников)⌨️ Чем позже решишь задачу, тем меньше баллов она будет стоить, за неудачную попытку от задачи отнимается 50 баллов.
Во время раунда отосланное решение задачи проверяется на "претестах", то есть каком-то наборе из ~10-15 тестов, и только после раунда на всех ~100-150 тестах. Это значит, что статус "претесты пройдены" не означает полного решения и задача может упасть во время полного тестирования🚬 Если кажется, что решение было неправильным, то можно в течение раунда перепослать решение, тогда от задачи также отнимается 50 баллов.
Если 100% кажется, что твое решение правильное, можно "заблокировать" задачу - тогда больше нельзя перепосылать решение, зато можно смотреть решения этой же задачи у других участников в твоей "комнате" (рандомные ~50 участников раунда) и попытаться "взломать" их решения⌨️ То есть подбирать такой тестовый кейс, на котором чужое решение работает неправильно. Успешный взлом +100 баллов, неуспешный -50 баллов.
Это всё и еще ряд правил делают каждый раунд непохожим друг на друга. Есть несколько стратегий по разгрому раунда, самые необычные/сложные такие:
1️⃣ "Стальные Яйца" - первым делом решать 3-ю или 4-ю задачу. Так как более "весомые" задачи теряют больше баллов со временем, то выгоднее решать их быстрее всего (в разумных пределах) и потом уже 1-ю и 2-ю.
Это самый рискованный путь, и если задачу решить не удастся, то урон рейтингу будет мощным.
2️⃣ "Крутой Какер" - после решения первых задач (сколько можешь - 2 или 3) не пытаться решать оставшиеся, а "заблокировать" решения и бросить все силы на "взлом" чужих решений. Для этого усиленно ищутся крайние случаи и прокачивается навык скорочтения говнокода.
Можно пойти на такую хитрость - так как многие другие участники изредка мониторят "комнату" и сразу же блокируют свои решения после первых взломов (далеко не все задачи "взломабельные") и тоже пытаются ломать кого-то, лучше не ломать никого сразу, а накопить список лохов и потом грохнуть сразу пятерых и получить +500 баллов👊
(Самые жесткие вариации стратегии дополнительно предполагают засылку хренового решения по сложной задаче, лишь бы пройти претесты, а потом прочитать чье-то нормальное решение в комнате и также ломать)
Codeforces давал жесткую дозу адреналина, на которую подсаживаешься и побочно прокачиваешь навык решения алгоритмических задач. Это работает, есть такой вайб заходит (далеко не всем).
ПРОДОЛЖЕНИЕ В КОММЕНТАРИЯХ
Как проходит отбор к межнару по информатике
Я подумал, о чем бы написать в канал, чтобы он не пустовал, и решил, что эта тема сойдет
Калибровка
Однажды я как обычно отсиживал время в своей школе, и кто-то сказал что бывают некие "олимпиады", с помощью которых можно поступить в любой вуз без экзаменов, но это не точно
Я был не уверен, что мне особо нужен "топовый" (будто бы) вуз, что я вывезу если там сложно учиться и так далее
Отнесся скептически, слово "олимпиады" ассоциировались со скучным занятием для ботанов
Узнал, что в этом олимпиаде есть несколько этапов (школа/город/область/финал). Открыл Codeforces, который в интернете советовали для подготовки. Порешал там что-то (
Спустя какое-то время пару раз поучаствовал на Codeforces в "раундах" (их правила), по их результатам перерасчитывается твой рейтинг.
После этого я стал поехавшим на теме Codeforces
Cледующие два года я постоянно решал на нем задачи, на уроках с телефона читал разборы раундов и алгоритмов, прорешивал старые задачи, и не мог дождаться нового раунда.
Прикол в том, что Codeforces превращает решение обычных алгоритмических задач в рейтинговую игру
В стандартном раунде дается 5 задач на 2 часа.
В самом начале задачи стоят 500-1000-1500-2000-2500 баллов, они отсортированы по сложности: первую решают почти все, последнюю единицы (из многих тысяч участников)
Во время раунда отосланное решение задачи проверяется на "претестах", то есть каком-то наборе из ~10-15 тестов, и только после раунда на всех ~100-150 тестах. Это значит, что статус "претесты пройдены" не означает полного решения и задача может упасть во время полного тестирования
Если 100% кажется, что твое решение правильное, можно "заблокировать" задачу - тогда больше нельзя перепосылать решение, зато можно смотреть решения этой же задачи у других участников в твоей "комнате" (рандомные ~50 участников раунда) и попытаться "взломать" их решения
Это всё и еще ряд правил делают каждый раунд непохожим друг на друга. Есть несколько стратегий по разгрому раунда, самые необычные/сложные такие:
Это самый рискованный путь, и если задачу решить не удастся, то урон рейтингу будет мощным.
Можно пойти на такую хитрость - так как многие другие участники изредка мониторят "комнату" и сразу же блокируют свои решения после первых взломов (далеко не все задачи "взломабельные") и тоже пытаются ломать кого-то, лучше не ломать никого сразу, а накопить список лохов и потом грохнуть сразу пятерых и получить +500 баллов
(Самые жесткие вариации стратегии дополнительно предполагают засылку хренового решения по сложной задаче, лишь бы пройти претесты, а потом прочитать чье-то нормальное решение в комнате и также ломать)
Codeforces давал жесткую дозу адреналина, на которую подсаживаешься и побочно прокачиваешь навык решения алгоритмических задач. Это работает, есть такой вайб заходит (далеко не всем).
ПРОДОЛЖЕНИЕ В КОММЕНТАРИЯХ
Please open Telegram to view this post
VIEW IN TELEGRAM
C++95
GIF
#retro #story
Обзор Sega Mega Drive🏃
16-битная приставка Sega Mega Drive появилась у меня в середине 00-х. Я переиграл во многие игры, потому что на городском рынке можно было брать напрокат картриджи на неделю за 15 рублей🏃♂️
Хотя тогда было уже поздно для таких приставок, в провинции время идет с отставанием (обыграно в "Жмурках", снятом в то время), я помню даже оранжевые картриджи для совсем отсталой 8-битной Dendy на том же рынке🎮
Mega Drive породил новый культурный пласт и сподвиг людей на такие увлечения:
1️⃣ Sonic 😈 - вырос из игры 1991 года, которая выжала максимум из тогдашнего железа (обзор только физики значителен).
После успеха оригинальной игры вышло овер 9000 других игр про Соника, мультфильмов, комиксов и прочего хлама для школьников.
Известный деятель sndk также вырос на нем - даже пробовал сделать свою игру, и в параллельной вселенной он стал бы обычным программистом, но куда лучше у него получалась треш-озвучка, что стало его карьерой.
Даже профессиональные издатели игр выпускали закосы под Соника🦔
2️⃣ PixelArt 😊 - старые игры были вынуждены иметь пиксельную графику, но с эволюцией железа это почти сразу стало андеграундом. До сих пор живы ценители такого стиля.
В этой сфере популярно рисовать со всякими ограничениями, например "не больше 8 цветов на картинку".
3️⃣ RetroGaming 🎮 - любовь к старому железу и играм, анализ их архитектур и так далее. Играть можно на эмуляторах, хотя есть ценители которые приобретают старые оригинальные девайсы.
У некоторых приставок (у той же Mega Drive) есть новодельные реплики, можно их купить на алиэкспресс😁
Еще, например, есть дистрибутив Raspberry Pi специально под ретро, и у всех версий RaspPi есть композитный видеовыход, способный работать со старыми телевизорами, что нужно для аутентичности.
4️⃣ Reversing ⚙️ - реверс и изменение старых игр.
Изменение старых игр называется "ромхакинг", про это тоже есть куча ресурсов.
Есть деятели, которые проводят лютые стримы по ромхакингу.
Есть даже ежегодный конкурс на лучший ромхак Соника.
5️⃣ Sega - отдельные ценители следят именно за компанией Sega, например выкладывают на форумах всякие найденные сомнительной ценности материалы, наподобии "финансовый отчет Sega за 1986 год" 😁 Это показывает, насколько приставка повлияла на культуру, что даже такие увлечения есть.
Архитектура Mega Drive выглядит так🔍 , то есть состоит из нескольких главных кусков:
1️⃣ Motorola 68000 - главный процессор, о нем писал тут. Игры программировались на его ассемблере.
Любое обращение к памяти в ассемблере выполнялось шиной (на картинке 68000 bus), которая преобразовывала адреса в разные места: ROM картриджа (объем 4Mb), RAM процессора (объем 64Kb), контрольные порты и так далее, подробнее описано тут.
В общем, больше сказать нечего😁 Это обычный процессор для игровой логики, достаточно дешевый и популярный на момент создания Mega Drive.
2️⃣ VDP (Video Display Processor) - асик разработки самой Sega, чип видеоконтроллера. Полностью про его работу описано на этом крутейшем сайте (это лучшее, что я читал технического за год), ниже будет пересказ 😉
Этот процессор работает так - у него 24 регистра, которые отвечают за всякую хреновню, а также 64Kb собственного RAM (называется VRAM - Video RAM), куда нужно совать информацию о графике.
Данные во VRAM засовывает процессор 68000 (он же может менять регистры), и VDP просто отрисовывает на телевизор картинку согласно присланным данным и всё, больше ничего не делает.
В VDP достаточно навороченная система со цветами.
В любой момент времени активно 4 палитры, в каждой палитре находится 16 цветов, каждый цвет занимает 9 бит (то есть по 3 бита на R/G/B, суммарно доступно 512 уникальных цветов).
Первый цвет палитры всегда прозрачный, то есть по факту в палитре доступно 15 цветов плюс "прозрачность".
ПРОДОЛЖЕНИЕ В КОММЕНТАРИЯХ
Обзор Sega Mega Drive
16-битная приставка Sega Mega Drive появилась у меня в середине 00-х. Я переиграл во многие игры, потому что на городском рынке можно было брать напрокат картриджи на неделю за 15 рублей
Хотя тогда было уже поздно для таких приставок, в провинции время идет с отставанием (обыграно в "Жмурках", снятом в то время), я помню даже оранжевые картриджи для совсем отсталой 8-битной Dendy на том же рынке
Mega Drive породил новый культурный пласт и сподвиг людей на такие увлечения:
После успеха оригинальной игры вышло овер 9000 других игр про Соника, мультфильмов, комиксов и прочего хлама для школьников.
Известный деятель sndk также вырос на нем - даже пробовал сделать свою игру, и в параллельной вселенной он стал бы обычным программистом, но куда лучше у него получалась треш-озвучка, что стало его карьерой.
Даже профессиональные издатели игр выпускали закосы под Соника
В этой сфере популярно рисовать со всякими ограничениями, например "не больше 8 цветов на картинку".
У некоторых приставок (у той же Mega Drive) есть новодельные реплики, можно их купить на алиэкспресс
Еще, например, есть дистрибутив Raspberry Pi специально под ретро, и у всех версий RaspPi есть композитный видеовыход, способный работать со старыми телевизорами, что нужно для аутентичности.
Изменение старых игр называется "ромхакинг", про это тоже есть куча ресурсов.
Есть деятели, которые проводят лютые стримы по ромхакингу.
Есть даже ежегодный конкурс на лучший ромхак Соника.
Архитектура Mega Drive выглядит так
Любое обращение к памяти в ассемблере выполнялось шиной (на картинке 68000 bus), которая преобразовывала адреса в разные места: ROM картриджа (объем 4Mb), RAM процессора (объем 64Kb), контрольные порты и так далее, подробнее описано тут.
В общем, больше сказать нечего
Этот процессор работает так - у него 24 регистра, которые отвечают за всякую хреновню, а также 64Kb собственного RAM (называется VRAM - Video RAM), куда нужно совать информацию о графике.
Данные во VRAM засовывает процессор 68000 (он же может менять регистры), и VDP просто отрисовывает на телевизор картинку согласно присланным данным и всё, больше ничего не делает.
В VDP достаточно навороченная система со цветами.
В любой момент времени активно 4 палитры, в каждой палитре находится 16 цветов, каждый цвет занимает 9 бит (то есть по 3 бита на R/G/B, суммарно доступно 512 уникальных цветов).
Первый цвет палитры всегда прозрачный, то есть по факту в палитре доступно 15 цветов плюс "прозрачность".
ПРОДОЛЖЕНИЕ В КОММЕНТАРИЯХ
Please open Telegram to view this post
VIEW IN TELEGRAM
C++95
old2.png
#compiler
На фото типичная задняя обложка журнала или тетради в нулевые годы. Сейчас такого не увидишь (закон не позволяет или устарело?), но в то время я выбирал тетради с самым забитым задником, чтобы было на что посмотреть в школе🔍
На кнопочном телефоне у меня было не так много Java-игр, плюс товарищи могли что-то передать по ИК-порту. Но однажды мне купили ШНУР по которому можно было с компа перекинуть все, и я стал "устанавливать все игры"🖥
Ломая глаза об экран 240x320, я прошел все популярные игры, а для Gravity Defied я прошел все моды и даже пытался менять в⌨️
Обзор байткода Java👩💻
Язык👩💻 Java появился в 1995 году и прошел большую эволюцию. Сначала он использовался для апплетов, выполняющихся в браузере. Потом для приложений Nokia и прочих кнопочников (подмножество J2ME).
Эти направления давно умерли, но язык живет - он популярен для разработки в Android, в финтехе и бэкенде (лучший в мире фреймворк для бэкенда👩💻 Spring), есть много проектов (Kafka, ZooKeeper, etc.), появились интероперабельные языки - 👩💻 Kotlin, 👩💻 Scala, Closure.
Есть несколько реализаций компилятора Java и виртуальных машин.
Язык довольно простой, потому что на него наложена куча ограничений:
Весь код должен находиться внутри классов.
Тело функции надо писать сразу (нельзя как в C++ только "объявить" функцию).
Принцип "1 класс = 1файл" - в файле
Все типы, кроме примитивных (int, double, и пр.), неявно наследуются от класса
Генерики в языке - просто развод, их по факту нет. Они добавлены аж в 2004 году как синтаксический сахар🍫
Все ссылки на объекты указывают на
То есть запись🔍
Чтобы примитивные типы можно было использовать в контейнерах, для них сделаны типы-"обертки", наследующиеся от
Нельзя сделать
Можно оценить оверхед - если🍔
Хотя в Java это нормально - он не задумывался как супер вычислительный язык.
После компиляции каждый
В начале
Потом в файле находятся функции класса, скомпилированные в байткод.
В супер понятной официальной спеке можно увидеть примерный вывод компилятора в разных случаях, формат
Байткод очень простой - каждая команда состоит из 1 байта, называется "опкод", после него может быть 1-2 байта дополнительной инфы, если надо.
Команды разбиты на ~20 групп из почти одинаковых опкодов, список тут. Многие высокоуровневые, например опкод
Компилятор (который переводит язык в
Где😁
Если это метод
Виртуальная машина должна сама все отрезольвить и подставить адрес метода.
ПРОДОЛЖЕНИЕ В КОММЕНТАРИИ
На фото типичная задняя обложка журнала или тетради в нулевые годы. Сейчас такого не увидишь (закон не позволяет или устарело?), но в то время я выбирал тетради с самым забитым задником, чтобы было на что посмотреть в школе
На кнопочном телефоне у меня было не так много Java-игр, плюс товарищи могли что-то передать по ИК-порту. Но однажды мне купили ШНУР по которому можно было с компа перекинуть все, и я стал "устанавливать все игры"
Ломая глаза об экран 240x320, я прошел все популярные игры, а для Gravity Defied я прошел все моды и даже пытался менять в
.jar
-файле что-то сам, получилось поставить картинку на фон и поменять окраску мотыка Обзор байткода Java
Язык
Эти направления давно умерли, но язык живет - он популярен для разработки в Android, в финтехе и бэкенде (лучший в мире фреймворк для бэкенда
Есть несколько реализаций компилятора Java и виртуальных машин.
Язык довольно простой, потому что на него наложена куча ограничений:
Весь код должен находиться внутри классов.
Тело функции надо писать сразу (нельзя как в C++ только "объявить" функцию).
Принцип "1 класс = 1файл" - в файле
Foo.java
должно находиться определение ровно одного класса с именем Foo
.Все типы, кроме примитивных (int, double, и пр.), неявно наследуются от класса
java.lang.Object
. Все методы виртуальные (кроме статических методов).Генерики в языке - просто развод, их по факту нет. Они добавлены аж в 2004 году как синтаксический сахар
Все ссылки на объекты указывают на
java.lang.Object
, а в коде делается неявное приведение к типу.То есть запись
ArrayList<Foo>
это самообман - в действительности хранятся ссылки не на Foo
, а на java.lang.Object
, просто есть неявное приведение к Foo
и компилятор чекнет что в твоем коде нигде нет некорректных приведений Чтобы примитивные типы можно было использовать в контейнерах, для них сделаны типы-"обертки", наследующиеся от
java.lang.Object
. Для int
это Integer
, для double
это Double
, и так далее.Нельзя сделать
ArrayList<int>
, можно сделать ArrayList<Integer>
.Можно оценить оверхед - если
std::vector<int>
из 128 элементов это 4*128 последовательных байт в памяти, то ArrayList<Integer>
из тех же элементов это 128 объектов (которые находятся хрен знает где в куче), каждый является оберткой над int
-ом Хотя в Java это нормально - он не задумывался как супер вычислительный язык.
После компиляции каждый
Foo.java
преобразуется в Foo.class
, потом они все попадают в "исполняемый" .jar
-файл, который является просто zip-архивом 📦В начале
.class
-файла находится "constant pool", это константы (строки, длинные числа, и прочее).Потом в файле находятся функции класса, скомпилированные в байткод.
В супер понятной официальной спеке можно увидеть примерный вывод компилятора в разных случаях, формат
.class
-файла, что должна делать виртуальная машина, и прочее.Байткод очень простой - каждая команда состоит из 1 байта, называется "опкод", после него может быть 1-2 байта дополнительной инфы, если надо.
Команды разбиты на ~20 групп из почти одинаковых опкодов, список тут. Многие высокоуровневые, например опкод
arraylength
который положит на стек размер массива.Компилятор (который переводит язык в
.class
-файлы) не делает никаких предположений о memory layout объекта, поэтому вызов метода выглядит так:invokevirtual #4 // каждый метод (кроме статических) является виртуальным
Где
#4
это 4-й объект в "constant pool", являет собой "символическую ссылку", то есть тупо строку Если это метод
int addtwo(int a, int b)
в классе Example
, то ссылка такая: Example.addtwo(II)I
Виртуальная машина должна сама все отрезольвить и подставить адрес метода.
ПРОДОЛЖЕНИЕ В КОММЕНТАРИИ
Please open Telegram to view this post
VIEW IN TELEGRAM
C++95
img.png
#story
Психоакустика и Bluetooth🎧
(Вступление)
Heute treff ich einen Herrn,
Сегодня встречаюсь с одним господином,
Der hat mich zum Fressen gern.
Который охотно меня съест.
Weiche Teile und auch Harte,
Нежное филе, да и твердые куски
Stehen auf der Speisekarte.
Входят в меню!
На фото господин, чей голос я почти каждый день слушаю уже давно.
Особенно круто было в 12-13 лет. Представьте - на улице среди панелек мрак и холод, в дворовой школе безвкусно одетые учителя талдонят про деепричастия, на перемене порамсил с иностранным специалистом (и его 100500 братьев хотят с тобой поговорить), на обед вчерашние макароны.
Но вот ты за компьютером, включаешь эту музыку, и все проблемы тают как майский снег, ты становишься "Богом, входящим в Вальгаллу". Всегда есть что посмотреть - например клип из 1995 (вдохновленный романом "Парфюмер"), клип из 1998 (нарезанный из фильма "Олимпия" 1938 года), запись концерта 1998 года Live Aus Berlin (море огня)🔥
Самый базовый формат цифрового звука это PCM, он представляет собой просто значения амплитуд (это громкость звука).
Например, формат WAV это заголовок из 44 байт, после которого идут байты PCM.
Несжатый звук длительностью в 1 секунду, с частотой 48kHz, стерео (то есть два канала), с двумя байтами на каждое значение амплитуды занимает примерно 1.5 Мбит.
Звук передается мне через Bluetooth🤙 Но в таком случае его приходится сжимать.
Рекламируется, что пропускная способность Bluetooth составляет 3 Мбит/с, но по факту доступно в разы меньше и вышеуказанный звук нельзя передать несжатым.
Например, под "3 Мбит/с" подразумевается, что идут две одновременные передачи битов от девайса A к девайсу Б, и наоборот от девайса Б к девайсу А, обе 1.5 Мбит/c (направление меняется каждые 625 микросекунд). Кроме этого, много места занимают служебные заголовки, и бывает снижение битрейта из-за расстояния и интерференции😔
Звук можно сжимать без потерь (lossless кодеки), там применяется много приколов и есть много кодеков (например FLAC), но толку мало - сжатие получается примерно в два раза. Этого недостаточно, чтобы нормально передавать звук по Bluetooth. Еще такие алгоритмы обычно вычислительно сложные👎
Звук можно сжимать с потерями (lossy кодеки). Всего кодеков в Bluetooth с десяток, но единственный, который должен поддерживаться каждым девайсом это SBC (sub-band coding)🤷♂️
Этот кодек сжимает по отдельности небольшие куски стрима. Например, для 16-битного стерео это 512 байт, то есть 128 значений амплитуд, что при частоте 44.1kHz соответствует 2.9мс. В кодеке можно поставить разные настройки (о них "договариваются" девайсы при коннекте через специальные пакеты), при High Quality на такой кусок выходит пакет в 119 байт, что соответствует битрейту 328 Кбит/с.
Чтобы так сильно сжать звук, используются познания психоакустики👁 Эта наука изучает обработку звука мозгом. Если есть какой-то громкий звук в определенной частоте, то остальные звуки в других частотах мозг как бы "не слышит".
В SBC используется примитивная психоакустическая модель. Частоты разделяется на несколько равных диапазонов (называются "band", в SBC их максимум 8 штук, а в MP3 аж 32), и чем "громче" диапазон, тем больше битов выделяется на его кодировку, а информацию о "тихих" диапазонах можно и вовсе выбросить.
Информация упаковывается в фрейм, получателю остается вычислительно куда менее трудоемкая задача - распаковать фрейм, восстановить подпорченный сжатием звук и воспроизвести его🎧
За мощность сжатия в SBC отвечает параметр bitpool. Чем он больше, тем меньше сжимается аудио. К сожалению, абсолютное большинство производителей девайсов и софта (даже Windows и Linux) ограничили его сверху значением 53, что дает этот самый битрейт 328 кбит/с.
ПРОДОЛЖЕНИЕ В КОММЕНТАРИИ
Психоакустика и Bluetooth
(Вступление)
Heute treff ich einen Herrn,
Сегодня встречаюсь с одним господином,
Der hat mich zum Fressen gern.
Который охотно меня съест.
Weiche Teile und auch Harte,
Нежное филе, да и твердые куски
Stehen auf der Speisekarte.
Входят в меню!
На фото господин, чей голос я почти каждый день слушаю уже давно.
Особенно круто было в 12-13 лет. Представьте - на улице среди панелек мрак и холод, в дворовой школе безвкусно одетые учителя талдонят про деепричастия, на перемене порамсил с иностранным специалистом (и его 100500 братьев хотят с тобой поговорить), на обед вчерашние макароны.
Но вот ты за компьютером, включаешь эту музыку, и все проблемы тают как майский снег, ты становишься "Богом, входящим в Вальгаллу". Всегда есть что посмотреть - например клип из 1995 (вдохновленный романом "Парфюмер"), клип из 1998 (нарезанный из фильма "Олимпия" 1938 года), запись концерта 1998 года Live Aus Berlin (море огня)
Самый базовый формат цифрового звука это PCM, он представляет собой просто значения амплитуд (это громкость звука).
Например, формат WAV это заголовок из 44 байт, после которого идут байты PCM.
Несжатый звук длительностью в 1 секунду, с частотой 48kHz, стерео (то есть два канала), с двумя байтами на каждое значение амплитуды занимает примерно 1.5 Мбит.
Звук передается мне через Bluetooth
Рекламируется, что пропускная способность Bluetooth составляет 3 Мбит/с, но по факту доступно в разы меньше и вышеуказанный звук нельзя передать несжатым.
Например, под "3 Мбит/с" подразумевается, что идут две одновременные передачи битов от девайса A к девайсу Б, и наоборот от девайса Б к девайсу А, обе 1.5 Мбит/c (направление меняется каждые 625 микросекунд). Кроме этого, много места занимают служебные заголовки, и бывает снижение битрейта из-за расстояния и интерференции
Звук можно сжимать без потерь (lossless кодеки), там применяется много приколов и есть много кодеков (например FLAC), но толку мало - сжатие получается примерно в два раза. Этого недостаточно, чтобы нормально передавать звук по Bluetooth. Еще такие алгоритмы обычно вычислительно сложные
Звук можно сжимать с потерями (lossy кодеки). Всего кодеков в Bluetooth с десяток, но единственный, который должен поддерживаться каждым девайсом это SBC (sub-band coding)
Этот кодек сжимает по отдельности небольшие куски стрима. Например, для 16-битного стерео это 512 байт, то есть 128 значений амплитуд, что при частоте 44.1kHz соответствует 2.9мс. В кодеке можно поставить разные настройки (о них "договариваются" девайсы при коннекте через специальные пакеты), при High Quality на такой кусок выходит пакет в 119 байт, что соответствует битрейту 328 Кбит/с.
Чтобы так сильно сжать звук, используются познания психоакустики
В SBC используется примитивная психоакустическая модель. Частоты разделяется на несколько равных диапазонов (называются "band", в SBC их максимум 8 штук, а в MP3 аж 32), и чем "громче" диапазон, тем больше битов выделяется на его кодировку, а информацию о "тихих" диапазонах можно и вовсе выбросить.
Информация упаковывается в фрейм, получателю остается вычислительно куда менее трудоемкая задача - распаковать фрейм, восстановить подпорченный сжатием звук и воспроизвести его
За мощность сжатия в SBC отвечает параметр bitpool. Чем он больше, тем меньше сжимается аудио. К сожалению, абсолютное большинство производителей девайсов и софта (даже Windows и Linux) ограничили его сверху значением 53, что дает этот самый битрейт 328 кбит/с.
ПРОДОЛЖЕНИЕ В КОММЕНТАРИИ
Please open Telegram to view this post
VIEW IN TELEGRAM
#opensource
Обзор опенсорсных программ и конкурсов Google🕸
Я в Google никогда не работал, но имел честь поучаствовать во многих его программах. В этом плане Google уникален, потому что единственный из компаний своего уровня тратит так много на фактически благотворительность для повышения своего престижа.
Это может быть актуально для других крупных компаний. Я перечислю только те программы, где участвовал сам, а так их разных несколько десятков.
1️⃣ Google Code-In 👦
Это уже закрытая программа, она проходила каждый год с 2010 до 2019.
Суть была такова - с одной стороны заявлялись разные опенсорсные организации (как KDE, Fedora, Tensorflow и прочие), которые готовили кучу задачек чуть сложнее чем "добавить виджет в панель", то есть довольно лайтовые.
С другой стороны заявлялись микрочелики 13-17 лет (включительно), которые их выполняли в течении нескольких недель. Бесплатно, за опыт😁 Но в конце каждая организация выбирала двух жостиков, и они на халяву езжали в США 🇺🇸
Я поучаствовал пару раз, во второй мне подфартило и я на пару недель на халяву съездил в Bay Area (несколько "официальных" дней полностью за счет Google, остальные дни оплачивали отель на свои💳 )
Примерно как это было можно посмотреть в более древнем фотоотчете этого хлопца.
В целом, было интересно после глубинки белгородской области, побывал во многих местах, которые потом снял пизДудь в своей рекламе. Из минусов были конские цены на всё и засилье бомжей сидящих на крэке, но это общеизвестные факты насчет Bay Area.
2️⃣ Google Summer of Code 🏝
Тоже программа про опенсорс как предыдущая, есть разница:
1️⃣ Длится три месяца
2️⃣ Участвуют только студенты
3️⃣ Опенсорсных организаций намного больше - практически все известные там есть
4️⃣ Сделать надо какую-то серьезную задачу для организации, вот список для LLVM. Студент должен предоставить план ("пропозал"), как он собирается делать эту задачу. Некоторые организации требуют наличие коммитов в проекте, или сдать тест на C++, или еще как-то доказать достойность. Но многие организации "легкие" и там проекты полная халява.
Последний5️⃣ факт - Google платит за работу студентам. Раньше всем за лето платили 5000$ независимо от страны, расы, гендера и прочая, и прочая 💰
Потом решили, что слишком много участников из бантустанов, им такое бабло будет жирно. Поэтому ввели какой-то индекс гамбургера. Студенты из России и ее любимых соседей получают по 3000$ (минимум по шкале), из США по 6000$ (почти максимум) и так далее💸
Поэтому я там никогда не участвовал, потому что на стажировке и то больше платили, только немного помог знакомым в менторстве одной из таких задач.
От них я узнал разные приколюхи - например что подавляющее большинство студентов пропадают с концами после выполнения задачи и возвращаются на следующее лето😁 Ну хоть как-то опенсорс развивается.
3️⃣ Google Code Jam 🍯
Легендарный контест по решению задачек, с лайв-стримами и прочим⌨️
К сожалению, уже закрытый, проходил каждый год с 2003 до 2020 года.
Там была "воронка" из нескольких раундов:
На квалификацию записывались десятки тысяч людей, до финала доходило по ~26 человек из топа
Я до финала никогда не доходил - пик был в 2019, когда в🧐 И потом мне на почте не отдали футболку за участие в 3м раунде, потому что паспорт находился на замене по причине наступления 20 лет 🕺
А мой подписчик @bminaiev был в финалах неоднократно😎 Подписывайтесь на его блог - @bminaiev_blog 😉
4️⃣ Google Hash Code #️⃣
Самый бомжацкий из конкурсов (тоже отменен, с 2023) - надо зарегистрировать команду из 2-4 человек и решать задачу оптимизации чего-нибудь несколько часов онлайн.
В случае успеха наступал "финальный" этап, который заключался в том, что можно было приехать за свои средства к одному из офисов гугла (например в Дублин), тебя туда впустят и ты можешь там внутри что-то порешать.
Обзор опенсорсных программ и конкурсов Google
Я в Google никогда не работал, но имел честь поучаствовать во многих его программах. В этом плане Google уникален, потому что единственный из компаний своего уровня тратит так много на фактически благотворительность для повышения своего престижа.
Это может быть актуально для других крупных компаний. Я перечислю только те программы, где участвовал сам, а так их разных несколько десятков.
Это уже закрытая программа, она проходила каждый год с 2010 до 2019.
Суть была такова - с одной стороны заявлялись разные опенсорсные организации (как KDE, Fedora, Tensorflow и прочие), которые готовили кучу задачек чуть сложнее чем "добавить виджет в панель", то есть довольно лайтовые.
С другой стороны заявлялись микрочелики 13-17 лет (включительно), которые их выполняли в течении нескольких недель. Бесплатно, за опыт
Я поучаствовал пару раз, во второй мне подфартило и я на пару недель на халяву съездил в Bay Area (несколько "официальных" дней полностью за счет Google, остальные дни оплачивали отель на свои
Примерно как это было можно посмотреть в более древнем фотоотчете этого хлопца.
В целом, было интересно после глубинки белгородской области, побывал во многих местах, которые потом снял пизДудь в своей рекламе. Из минусов были конские цены на всё и засилье бомжей сидящих на крэке, но это общеизвестные факты насчет Bay Area.
Тоже программа про опенсорс как предыдущая, есть разница:
Последний
Потом решили, что слишком много участников из бантустанов, им такое бабло будет жирно. Поэтому ввели какой-то индекс гамбургера. Студенты из России и ее любимых соседей получают по 3000$ (минимум по шкале), из США по 6000$ (почти максимум) и так далее
Поэтому я там никогда не участвовал, потому что на стажировке и то больше платили, только немного помог знакомым в менторстве одной из таких задач.
От них я узнал разные приколюхи - например что подавляющее большинство студентов пропадают с концами после выполнения задачи и возвращаются на следующее лето
Легендарный контест по решению задачек, с лайв-стримами и прочим
К сожалению, уже закрытый, проходил каждый год с 2003 до 2020 года.
Там была "воронка" из нескольких раундов:
Qualification
, Round 1
, Round 2
, Round 3
, Final
- с возрастающей сложностью.На квалификацию записывались десятки тысяч людей, до финала доходило по ~26 человек из топа
Round 3
(стата по годам).Я до финала никогда не доходил - пик был в 2019, когда в
Round 3
получил 171 место А мой подписчик @bminaiev был в финалах неоднократно
Самый бомжацкий из конкурсов (тоже отменен, с 2023) - надо зарегистрировать команду из 2-4 человек и решать задачу оптимизации чего-нибудь несколько часов онлайн.
В случае успеха наступал "финальный" этап, который заключался в том, что можно было приехать за свои средства к одному из офисов гугла (например в Дублин), тебя туда впустят и ты можешь там внутри что-то порешать.
Please open Telegram to view this post
VIEW IN TELEGRAM
#books
Обзор книги "Modern Parallel Programming with C++ and Assembly Language" (2022 г.) 📚
(можно скачать PDF тут)
Как можно понять, книга посвящена "параллельному программированию".
Но тут имеется в виду не та параллельность когда есть много CPU (и используются мьютексы, etc.), а параллельность внутри одного CPU, а если точнее, то вся книга про SIMD (single instruction, multiple data)🏃
Сейчас стандартные типы данных имеют размер 8/16/32/64 бит (соответственно это🤡
Но в процессорах часто есть регистры на 128, 256 и даже 512 бит (соответственно это😎 В эти регистры "упаковываются" значения стандартного размера и над ними затем делаются групповые операции.
Проще показать на примере - пусть мы суммируем
То SIMD-версия на 256-битных регистрах могла бы выглядеть так (с поправкой на конкретный компилятор, т.к. эти интринсики не специфицированы в Стандарте С++):
Код выше работает быстро, решительно, в разы быстрее "наивного" варианта.
Общий flow такой - в "длинный" регистр выгружается мини-массив чисел (в примере выше массив из 8
Так как процессоры сейчас гига сложные (я наклал кирпичей даже когда делал эмулятор m68k 45-летней давности!), то таких "групповых операций" наделали много. Можно, например, вычислять еще
Книга посвящена только архитектуре x86 (архитектуры как ARM не рассматриваются).
SIMD-расширений в x86 есть несколько. Сначала в 1997 году появился MMX от Intel, потом в 1998 году 3DNow от AMD, и так далее, многие давно устарели и не выпускаются.
Книга посвящена только сравнительно новым SIMD-расширениям AVX (2011 год), AVX2 (2013 год) и AVX-512 (2017 год).
Глава1️⃣ описывает базу SIMD.
В главах2️⃣ ➖ 8️⃣ по одному шаблону описываются фичи AVX / AVX2 / AVX-512:
1️⃣ Описывается какая-нибудь платиновая задача - найти минимум/среднее в массиве, перемножить матрицы, применить свёртку, etc.
2️⃣ Приводится портянка кода на C++: "наивная реализация" vs "реализация на SIMD", с нудным описанием что откуда идёт.
3️⃣ Приводится бенчмарк, наивная реализация проигрывает SIMD в среднем в 10-15 раз.
В главе9️⃣ описывается как можно было бы сделать портабельную SIMD-программу - для этого в x86 есть опкод
В главе1️⃣ 0️⃣ неплохо описывается боян архитектура процессора x86-64 вместе с этими SIMD-регистрами в 256/512 бит.
В главах1️⃣ 1️⃣ ➖ 1️⃣ 8️⃣ описывается то же, что в главах 2-8, но на ассемблере... Я это не читал 😁
В главе1️⃣ 9️⃣ описывается здравый смысл, то есть гайд по SIMD-оптимизациям, общая тема - оптимизировать надо не всё подряд, а только то что видно в профайлере, потому что SIMD-код понимать трудно и легко ошибиться.
В аппендиксах есть инфа как ставить вижуэл студио и ссылки на доки...🔍
В целом полезная книга, можно почитать для общего развития. Только нужно иметь в виду:
1️⃣ Некоторые задачи лучше решаются через GPU, а не через SIMD на CPU (который ускорит лишь в единицы раз, а не в сотни).
2️⃣ Современный компилятор может сам сгенерировать SIMD-код (но это бабка надвое сказала).
3️⃣ Сначала профайлер, потом оптимизации.
Обзор книги "Modern Parallel Programming with C++ and Assembly Language" (2022 г.) 📚
(можно скачать PDF тут)
Как можно понять, книга посвящена "параллельному программированию".
Но тут имеется в виду не та параллельность когда есть много CPU (и используются мьютексы, etc.), а параллельность внутри одного CPU, а если точнее, то вся книга про SIMD (single instruction, multiple data)
Сейчас стандартные типы данных имеют размер 8/16/32/64 бит (соответственно это
byte/word/dword/qword
), они "нативно" поддерживаются потому что сами регистры общего назначения у процессора имеют размер 64 бита Но в процессорах часто есть регистры на 128, 256 и даже 512 бит (соответственно это
xmmword/ymmword/zmmword
в x86) Проще показать на примере - пусть мы суммируем
float
'ы:// float* z, const float* x, const float* y, size_t n
for (size_t i = 0; i < n; i++)
z[i] = x[i] + y[i];
То SIMD-версия на 256-битных регистрах могла бы выглядеть так (с поправкой на конкретный компилятор, т.к. эти интринсики не специфицированы в Стандарте С++):
// представим что `n` делится на 8
for (size_t i = 0; i < n; i += 8) {
__m256 x_vals = _mm256_loadu_ps(&x[i]); // грузим x[i..i+8] в один регистр
__m256 y_vals = _mm256_loadu_ps(&y[i]); // грузим y[i..i+8] в другой регистр
__m256 z_vals = _mm256_add_ps(x_vals, y_vals); // вычисляем z[i..i+8] в третьем
_mm256_storeu_ps(&z[i], z_vals); // выгружаем z[i..i+8] в память
}
Код выше работает быстро, решительно, в разы быстрее "наивного" варианта.
Общий flow такой - в "длинный" регистр выгружается мини-массив чисел (в примере выше массив из 8
float
'ов), и ускорение достигается за счет того, что процессор не тратит время на чтение одних и те же опкодов, а сразу делает нужную операцию.Так как процессоры сейчас гига сложные (я наклал кирпичей даже когда делал эмулятор m68k 45-летней давности!), то таких "групповых операций" наделали много. Можно, например, вычислять еще
z[i] = min(x[i], y[i])
, или y[i] = x[2*i] + x[2*i+1]
, или даже быстро переставить элементы z[i] = x[y[i]]
, и так далее.Книга посвящена только архитектуре x86 (архитектуры как ARM не рассматриваются).
SIMD-расширений в x86 есть несколько. Сначала в 1997 году появился MMX от Intel, потом в 1998 году 3DNow от AMD, и так далее, многие давно устарели и не выпускаются.
Книга посвящена только сравнительно новым SIMD-расширениям AVX (2011 год), AVX2 (2013 год) и AVX-512 (2017 год).
Глава
В главах
В главе
cpuid
, по которому можно узнать поддерживаемые SIMD-расширения и еще много что.В главе
В главах
В главе
В аппендиксах есть инфа как ставить вижуэл студио и ссылки на доки...
В целом полезная книга, можно почитать для общего развития. Только нужно иметь в виду:
Please open Telegram to view this post
VIEW IN TELEGRAM
C++95
Channel photo updated
#jostik
Обзор жостиков C++😱 (номер
(Предисловие)
Эту картинку я сделал месяц назад, и хотел отправить в WG21 (Working Group 21, он же Комитет C++) как предложение для логотипа🎨 Это буква "С" и два плюса.
Но вспомнив комитетские приколы, решил не делать🦆
Какой-нибудь товарищ комиссар Рабочей Группы по многообразию не принял бы ее, аргументировав что для репрезентации нужна широкая цветовая палитра, а вместо одного из крестов, например, символ зороастризма🤲 Зачем это делать, если он сам не живет так, как говорил Заратустра - непонятно. Слишком многим людям форма важнее содержания.
Поэтому это будет новая ава😐
1️⃣ Strong-типы 🙂
Теория о них тут, реализация на гитхабе.
Strong-типы это обертки над базовыми типами (
Например, вместо такого конструктора:
Можно сделать такой:
Где✋
Strong-типам можно придавать разные "скиллы" - например Addable, Comparable, Hashable и прочие, чтобы соответственно работали операции сложения, сравнения или можно было положить тип в хэшмапу.
Эти типы "бесплатные" для рантайма - компилятор выбрасывает шелуху и работает с базовым типом🕶
Раньше я их не принимал (если ты путаешься в параметрах, то вместо 15 параметров нужен builder pattern🛑 ), но сейчас наоборот, без них жить сложнее - это неплохая вещь.
2️⃣ Упакованные типы 📦
Как известно, у типов есть выравнивание:
Но во время парсинга пакетов всяких протоколов это может мешать, потому что никаких padding'ов между полями не предусмотрено. Также во время работы с сетью супер важно оптимизировать память. Тогда надо убирать выравнивание (alignment)🎩
Это можно сделать разными способами, самый удобный такой:
(Этот pragma pack выглядит странно, потому что у него есть типа внутренний стек)
Команда
Менее удобный способ (потому что надо ставить каждому классу вручную) это вешать на структуру
Это немного по-другому работает внутри компилятора, но итог один - alignment равный единице.
Способ, который не работает - спецификатор alignas, он может только увеличить дефолтный alignment. Оно используется для подгона структуры под кэш-линию (64 байта) или SIMD-инструкции (16/32/64 байта).
А как это работает на уровне ассемблера?🤔 Компилятор не будет генерировать дичь с переносами байтов (как для bitfield), там формируется честный unaligned access.
Как оказывается, на x86 никаких сюрпризов нет. Оно всегда поддерживало unaligned access (работающий медленнее чем aligned).
А на других архитектурах может произойти треш - надо беречься🤔
ПРОДОЛЖЕНИЕ В КОММЕНТАРИЯХ👀
Обзор жостиков C++
sizeof(char)
)(Предисловие)
Эту картинку я сделал месяц назад, и хотел отправить в WG21 (Working Group 21, он же Комитет C++) как предложение для логотипа
Но вспомнив комитетские приколы, решил не делать
Какой-нибудь товарищ комиссар Рабочей Группы по многообразию не принял бы ее, аргументировав что для репрезентации нужна широкая цветовая палитра, а вместо одного из крестов, например, символ зороастризма
Поэтому это будет новая ава
Теория о них тут, реализация на гитхабе.
Strong-типы это обертки над базовыми типами (
int
, double
и пр.), которые не могут конвертироваться в другие типы. Это полезно, чтобы не путать аргументы и понимать цель значения из имени типа.Например, вместо такого конструктора:
Rectangle(double width, double height);
Можно сделать такой:
Rectangle(Width width, Height height);
Где
Width
и Height
- обертки над double
, и их нельзя перепутать Strong-типам можно придавать разные "скиллы" - например Addable, Comparable, Hashable и прочие, чтобы соответственно работали операции сложения, сравнения или можно было положить тип в хэшмапу.
Эти типы "бесплатные" для рантайма - компилятор выбрасывает шелуху и работает с базовым типом
Раньше я их не принимал (если ты путаешься в параметрах, то вместо 15 параметров нужен builder pattern
Как известно, у типов есть выравнивание:
struct Biba {
uint16_t a; /* 2 bytes */
/* padding 6 bytes */
uint64_t b; /* 8 bytes */
};
static_assert(sizeof(Biba) == 16);
static_assert(alignof(Biba) == 8);
Но во время парсинга пакетов всяких протоколов это может мешать, потому что никаких padding'ов между полями не предусмотрено. Также во время работы с сетью супер важно оптимизировать память. Тогда надо убирать выравнивание (alignment)
Это можно сделать разными способами, самый удобный такой:
#pragma pack(push, 1)
struct Boba {
uint16_t a; /* 2 bytes */
uint64_t b; /* 8 bytes */
};
#pragma pack(pop)
static_assert(sizeof(Boba) == 10);
static_assert(alignof(Boba) == 1);
(Этот pragma pack выглядит странно, потому что у него есть типа внутренний стек)
Команда
pack(push, N)
значит что все типы будут иметь alignment максимум N
байт, а pack(pop)
убирает это.Менее удобный способ (потому что надо ставить каждому классу вручную) это вешать на структуру
__attribute__((packed))
.Это немного по-другому работает внутри компилятора, но итог один - alignment равный единице.
Способ, который не работает - спецификатор alignas, он может только увеличить дефолтный alignment. Оно используется для подгона структуры под кэш-линию (64 байта) или SIMD-инструкции (16/32/64 байта).
А как это работает на уровне ассемблера?
Как оказывается, на x86 никаких сюрпризов нет. Оно всегда поддерживало unaligned access (работающий медленнее чем aligned).
А на других архитектурах может произойти треш - надо беречься
ПРОДОЛЖЕНИЕ В КОММЕНТАРИЯХ
Please open Telegram to view this post
VIEW IN TELEGRAM
#compiler
День, когда умер CRTP🫡
По исходникам проектов на C++ можно определять, примерно в какое время был написан код👨🦳 В истории C++ был революционный стандарт C++11, еще чуть менее революционный C++20 (по убыванию используемости - concepts, ranges, coroutines, modules), и проходные между ними (C++14, C++17).
В C++23 есть единственная крупная фича, ради которой стоило его ждать - deducing this😳 Единственное место, где нужно про него читать - пропозал в стандарт, там есть всё - мотивация, обоснование всех тонкостей дизайна, примеры использования, разбор всех корнер кейсов, и прочее. Все другие объяснения из интернета принципиально менее полны 📖 Я сюда не буду копипастить примеры, они есть в пропозале.
Long story short, в каждом методе используется неявный "нулевой" параметр😎
Конечно, у deducing this есть ряд drawbacks🤷♂️
1️⃣ Есть ряд спецэффектов по типу shadowing'а переменной базового класса (в пропозале они разобраны)
2️⃣ Методы становятся шаблонными со всеми вытекающими - Clang известен тем, что в отличие от MSVC не особо проверяет код шаблона до инстанциации
3️⃣ В коде начинается треш с категориями значений, нужно понимать разницу между
Реализация deducing this наконец-то появилась в LLVM/Clang 18, который зарелизился 6 марта😮 К сожалению, релиз получился всратым, и баги не пофикшены до сих пор 🚬 Поэтому его пока никто не использует.
Но уже сейчас можно изучать вопрос - как лучше всего подготовиться к использованию этой фичи и гарантировать, что все перестанут писать "по-старому"?👦
В этом нам поможет🔍 ), и отлавливать устаревший код.
Первым делом нужно, чтобы в проекте генерировался
Его создание поддерживается в CMake, для этого в корневом
Потом надо поставить пакеты из этого поста🔍 Код всего теста можно посмотреть тут, дальше я опишу что он делает.
ПРОДОЛЖЕНИЕ В КОММЕНТАРИЯХ🏃
День, когда умер CRTP
По исходникам проектов на C++ можно определять, примерно в какое время был написан код
В C++23 есть единственная крупная фича, ради которой стоило его ждать - deducing this
Long story short, в каждом методе используется неявный "нулевой" параметр
this
, эта фича добавляет возможность явно указать этот параметр, причем необязательно с исходным типом (можно заиспользовать шаблон). Это оказалось очень нужным - уменьшает дублирование методов, убирает необходимость в CRTP, позволяет удобнее рекурсивные лямбды, и прочее Конечно, у deducing this есть ряд drawbacks
auto
, auto&&
, decltype(auto)
, и специально добавили срань как std::forward_like.Реализация deducing this наконец-то появилась в LLVM/Clang 18, который зарелизился 6 марта
Но уже сейчас можно изучать вопрос - как лучше всего подготовиться к использованию этой фичи и гарантировать, что все перестанут писать "по-старому"?
В этом нам поможет
libclang
! Мы можем написать простые python-тесты на исходный код (о них писал тутПервым делом нужно, чтобы в проекте генерировался
compile_commands.json
. Это простой список команд для компилятора, его описание тут, он нужен для многих вещей, например для автокомплита.Его создание поддерживается в CMake, для этого в корневом
CMakeLists.txt
надо добавить:set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
Потом надо поставить пакеты из этого поста
ПРОДОЛЖЕНИЕ В КОММЕНТАРИЯХ
Please open Telegram to view this post
VIEW IN TELEGRAM