Обновить
64K+

C *

Типизированный язык программирования

145,94
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

Прошивка Arduino под капотом

Уровень сложностиПростой
Время на прочтение11 мин
Охват и читатели11K

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

Читать далее

Make STL Cringe Again: Как я динамические строки на C создавал

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели10K

Привет, Хабр! Однажды я подумал, что вот не умеют разработчики жить. В каждом из языков есть свои напасти (от которых, в принципе, спасаются разве что разработчики-полиглоты). Возьмем хотя бы C++ — даже без его шаблонов, исключений, и т.д., там все еще много мраков. Возьмем хотя бы iostream — он, блин, весит 2 МБ в последней версии GCC при компиляции под Windows! Или, вот, std::string — динамическая строка. Звучит интересно на бумаге, учитывая, что язык не из добрейших, но на практике...

Читать далее

Пять месяцев на игровой движок, месяц на игру. Зачем я написал собственный движок на C

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели15K

Пять месяцев назад я начал делать игровой движок Neotolis Engine на C17. Хотел глубже погрузиться в рендер и собрать для себя движок, с которым мне было бы легко и приятно работать. Сейчас в нём уже достаточно фич, чтобы делать игру. Я делаю 3D-инкременталку про проблему вагонетки Not a Trolley Problem.

В статье рассказываю, какие принципы я заложил в движок, как использую Claude и Codex и почему важно делать игры, а не только движок.

Читать далее

С++20 и асинхронный ввод-вывод для обработки крашей приложения

Уровень сложностиСредний
Время на прочтение23 мин
Охват и читатели7.1K

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

Читать далее

Драйвер шагового двигателя с векторным управлением

Уровень сложностиСложный
Время на прочтение27 мин
Охват и читатели17K

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

Вращать магнитное поле

Как создать 3D-рендерер для Playdate и не выбросить консоль в окно

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели16K

Playdate – крошечная консоль с жёлтым корпусом и процессором, который в эпоху гигагерцев кажется игрушечным. Разрешение – 400x240, один бит, без оттенков серого. Видеочипа нет: всё, что видите, считает скромный ARM-процессор. Казалось бы, какое тут 3D?

Но Кристина Рамос решила проверить, где проходит граница возможного. Начала с рейкастера, а закончила софтверным рендерером, который читает BSP-карты.

Игры Return of the Obra Dinn и Jet Set Radio вдохновили Кристину на монохромный селшейдинг с жирными контурами. В статье она рассказывает, как 1-битный экран Playdate заставил отказаться от фотореалистичных текстур и найти уникальный визуальный стиль для 3D-игры.

Читать далее

Микроядро SME2 sgemm: 1024 умножения-сложения за проход

Уровень сложностиСложный
Время на прочтение8 мин
Охват и читатели7K

В этой части мы возьмём первый из пропусков BLIS — микроядро sgemm; сначала зафиксируем форму аккумулятора 32×32 в четырёх тайлах ZA, затем разберём горячий цикл по K, потом эпилог с alpha, beta и ловушкой NaN, а в конце посмотрим, какие числа производительности даёт именно это ядро. Следующая часть оставит структуру почти той же, но заменит геометрию тайла и условия существования ядра.

Читать далее

Count-Min Sketch: как посчитать частоту миллиарда событий в 10 килобайт

Уровень сложностиСложный
Время на прочтение12 мин
Охват и читатели9.5K

Представьте: через ваш сервер проходит 10 миллионов запросов в минуту. Каждый запрос содержит метку (например, ID пользователя, IP-адрес или поисковый запрос). Руководство просит: «А давайте посмотрим, кто из пользователей самый активный?». Задача выглядит простой, пока вы не осознаете, что хранить HashMap из 10 миллионов ключей в оперативной памяти — это сотни мегабайт, а если ключи — длинные строки, то и гигабайты.

Вероятностные структуры данных решают такие задачи без гигантских кластеров. В прошлых статьях мы разобрали, как с помощью HyperLogLog считать количество уникальных элементов, а с помощью Фильтра Блума — проверять наличие элемента. Сегодня мы закроем триаду и поговорим об алгоритме, который отвечает на вопрос «А сколько раз этот элемент встречался?» с фиксированной памятью в пару килобайт и строгой вероятностной гарантией.

И это — Count-Min Sketch! Структура, которая лежит в основе анализа потоков в базах данных (от ClickHouse до BigQuery) и сетевых протоколов. Мы разберем её математику, реализуем на чистом C с использованием MurmurHash3 и проведем бенчмарки.

Читать далее

Нельзя просто взять и прочитать 64-битный SysTick на CH32V203

Уровень сложностиСредний
Время на прочтение9 мин
Охват и читатели9.1K

Когда я начал работать с CH32V203G6U6 и обнаружил, что там есть 64-битный аппаратный таймер, то подумал: ух, это же отлично, раз таймер аппаратный, то и о чтении/записи заботится сам микроконтроллер. И какое-то время это не вызывало вопросов. А потом…

Читать далее

BLIS: недостающую среднюю ступеньку построили тридцать лет назад

Время на прочтение8 мин
Охват и читатели7.9K

В этой части мы начнём с тупика, в который приводит голый цикл FMOPA; затем покажем, какую часть GEMM BLIS уже построил за нас; после этого разберём пять циклов BLIS и место микроядра внутри них. Финал главы должен сделать дальнейший план конкретным: что именно нужно добавить для Apple SME, а что уже относится к готовой «мебели» фреймворка.

Читать далее

Добавили потоков, стало медленнее: разбираемся с ложным разделением кеш‑линии

Уровень сложностиСложный
Время на прочтение10 мин
Охват и читатели9.2K

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

Разберём, как воспроизвести такую просадку, найти её через perf c2c и исправить без лишнего раздувания структур.

Читать далее

DPI для любопытствующих

Уровень сложностиСредний
Время на прочтение15 мин
Охват и читатели16K

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

Получилось ~500 строк кода, 95.6% распознавания протоколов и отличная возможность разобраться, как работает Deep Packet Inspection изнутри.

Без фреймворков, без зависимостей — только C, libpcap и алгоритм Ахо‑Корасик.

Читать далее

АКПП Voith не включается выше второй передачи: разбираемся в J1939

Уровень сложностиСредний
Время на прочтение3 мин
Охват и читатели92K

Изучаю шину CAN J1939 через написание самописных утилит. Целенаправленно отключал датчик наддува для проверки своих программ.

И здесь случай: Идёт выпуск машин на маршрут. На одном из автобусов АКПП не включается выше второй передачи. Сканера нет читать нечем. Но есть C, Linux, CANable, map_id_j1939, viz_j1939.

Читать далее

Ближайшие события

Графический фреймворк «Арго»

Уровень сложностиСредний
Время на прочтение26 мин
Охват и читатели9.3K

Данная статья содержит обзор графического фреймворка “Арго”, предназначенного для быстрой разработки полноценного пользовательского интерфейса для управления приложениями. Это кроссплатформенное решение, которое может работать на различных операционных системах и аппаратных платформах, и, прежде всего, на устройствах в условиях очень ограниченных ресурсов по быстродействию процессора и оперативной памяти. Это полностью отечественная разработка, практически независимая от зарубежных продуктов и Open Source разработок.

Читать далее

proxy_pass и fastcgi_pass — одна машина

Уровень сложностиСложный
Время на прочтение11 мин
Охват и читатели9.7K

У директив proxy_* и fastcgi_* совпадает 46 опций из 53 — буферизация, таймауты, кеш, next_upstream, с точностью до префикса и вплоть до значений по умолчанию. Два независимо написанных модуля так не сходятся.

Они и не независимы. Всё, чем proxy_pass отличается от fastcgi_pass, — девять указателей на функции в ngx_http_upstream_t. Соединение, таймауты, повторы, буферизация и отдача клиенту лежат в общих 7352 строках ngx_http_upstream.c, и восемь модулей — от proxy до свежего tunnel — дёргают один и тот же код.

Только контракт из этих девяти указателей врёт в обе стороны. Один из них, abort_request, ставят все восемь модулей — а машинерия не вызывает его ни разу: ноль вызовов во всём дереве и ни одного коммита с вызовом за всю публичную историю, с импорта 0.1.14 в январе 2005-го. Другой, pipe->input_filter, в контракте не объявлен вовсе — но обязателен, как только включена буферизация, и вызывается без проверки на NULL.

Разбираем по тегу release-1.31.3 со ссылками файл:строка: все места вызова каждого колбэка, включая тот, который разбирает заголовок не из сокета, а из файла кеша; матрица «кто какие указатели ставит» по всем восьми модулям; два сценария падения с разными стек-трейсами. Плюс свой рабочий upstream-модуль на 335 строк, собранный и проверенный curl'ом, и tunnel — самый маленький из восьми, приехавший в open source в апреле.

Читать далее

Как PVS-Studio улучшает качество embedded-проектов

Уровень сложностиПростой
Время на прочтение16 мин
Охват и читатели11K

Embedded-разработка отличается множеством уникальных настроек, компиляторов и систем сборки. А при использовании стандартных методов анализа могут возникать сложности. Для решения этой проблемы PVS-Studio предоставляет специально разработанный механизм. Давайте узнаем о нём больше и посмотрим, как его можно применять на практике.

Читать далее

Попробуйте найти примеры кода для SME — я подожду

Уровень сложностиСложный
Время на прочтение9 мин
Охват и читатели7.6K

В этой части мы проверим, есть ли у SME учебная дорога, сравнимая с той, которую получили тензорные ядра GPU; затем разберём два реально полезных источника: Arm Learning Path и KleidiAI; после этого отделим то, чему они действительно учат, от того, где они останавливаются. К концу главы станет видно, какая именно «середина лестницы» отсутствует и почему следующая часть неизбежно приводит к BLIS.

Читать далее

В nginx один алгоритм балансировки

Уровень сложностиСложный
Время на прочтение17 мин
Охват и читатели17K

server a.internal weight=10 max_fails=2; — десять к одному. Ночью бэкенд на пару секунд отвалился, к утру давно жив и из ротации не выведен. А первые полсотни запросов рабочего дня распределяются не 10:1, и среди них есть места, где два запроса подряд уходят на сосед с весом единица.

Ни один лог об этом не скажет, в документации по upstream такого объяснения нет. Есть — в двух строках ngx_http_upstream_round_robin.c.

Разбираем по тегу release-1.31.3, со ссылками файл:строка: smooth weighted round-robin и его восемь копий в исходниках; effective_weight, которого нет в документации, и то, как max_fails втихую им управляет; почему least_conn сравнивает не число соединений; почему ip_hash не работает на unix-сокетах. Плюс sticky и least_time, приехавшие в open source несколько месяцев назад.

Читать далее

Добавляем надежный recovery в Xiaomi Band 10 Pro

Уровень сложностиСредний
Время на прочтение5 мин
Охват и читатели11K

В руках у меня новые часы от Xiaomi, Smart Band 10 Pro, у них есть приличный минус в системе recovery, который устранен в других часах линейки Сяоми, я расскажу об устройстве данной модели, структуре прошивки, пакета OTA и покажу какое решение решение я реализовал, чтобы улучшить механизм восстановления часов.

Читать далее

Генератор M-последовательностей

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели11K

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

Читать далее