cpportal | Unsorted

Telegram-канал cpportal - С/С++ Portal | Программирование

16270

Присоединяйтесь к нашему каналу и погрузитесь в мир для C/C++-разработчика Связь: @devmangx РКН: https://clck.ru/3Foc4d

Subscribe to a channel

С/С++ Portal | Программирование

Ты знал, что в IP-адресе можно «выкидывать» нули, и он всё равно будет работать?

Например:

10.20.0.2 → 10.20.2
10.0.0.68 → 10.68

В обоих случаях ты попадёшь на тот же самый хост.

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

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Классический пример pass by value и pass by reference.

Допустим, нам нужно поменять местами значения x и y.

swap(int a, int b);


^^
Значения x и y передаются по значению, то есть копируются в переменные-параметры, которые живут на стеке. Обмен происходит между этими параметрами. Когда функция возвращается, стек для swap() уничтожается, и исходные значения x и y остаются без изменений.

swap(int *a, int *b);


^^
a и b это указатели, которым передаются адреса x и y. При обмене используются эти адреса, чтобы поменять значения. В результате меняются значения, сохранённые по адресам x и y. После выхода из функции значения x и y уже будут выглядеть как поменянные местами (благодаря обмену на уровне адресов).

Допущения: 32-битная машина

- int занимает 4 байта
- указатели тоже 4 байта

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Чип на 8 КБ. Написано на C. И этого оказалось достаточно, чтобы разблокировать этот телефон.

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Как двоичные данные транслируются в инструкции ассемблера

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Dive into Systems – топовая бесплатная книга по системному программированию на C

Разбирают:

- как работает компьютер на низком уровне
- основы C для системного программирования
- оптимизацию кода
- ассемблер под разные архитектуры (x86, ARM и др.)

Плюсом попробуй ASM-визуализатор – пишешь C-код → сразу видишь, во что он превращается на ассемблере

Чекай тут → diveintosystems.org/book

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Разработчик представил собственный C++ inference-движок для LLM, который полностью работает на CPU и уже выдает около 60 токенов в секунду.

В текущей версии реализованы GPT-2, byte pair encoding, KV-кеш, greedy и temperature-сэмплирование, а также SIMD-оптимизации через NEON-интринсики. В планах разработчика добавить flash attention, operator fusion, многопоточность, квантизацию с бенчмарками, поддержку новых архитектур и перейти к GPU-вычислениям через CUDA C++.

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Изоляция процессов в Linux держится на двух вещах:

1. Виртуальная память

2. Приватные адресные пространства

Процесс A не может трогать данные процесса B.

Если только не использовать shmget (системный вызов №29 на x86_64).

Он буквально пробивает дыру в этой изоляции и позволяет процессам шарить один и тот же участок физической RAM.

Большинство IPC (pipes, сокеты и прочее) заставляет ядро копировать данные.

Процесс A пишет в ядро -> ядро копирует данные процессу B.

Shared memory этого избегает.

Разница примерно такая же, как пересылать Excel-файл туда-сюда по почте против совместного редактирования Google Sheet в реальном времени.

Вот полностью рабочий пример. Дочерний процесс меняет данные в shared memory, родитель видит изменения — доказательство того, что оба PID работают с одним и тем же физическим адресным пространством.

#include <sys/shm.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main() {
int id = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0666);
char *mem = shmat(id, NULL, 0);
strcpy(mem, "Hello!");

if (fork() == 0) {
// Child: read, modify, exit
printf("Child [%d] sees: %s\n", getpid(), mem);
strcpy(mem, "Changed by child!");
} else {
wait(NULL);
// Parent: see child's modification
printf("Parent [%d] sees: %s\n", getpid(), mem);
shmctl(id, IPC_RMID, NULL);
}
return 0;
}


Вывод:

Child [12346] sees: Hello!
Parent [12345] sees: Changed by child!


Кто это использует?

Например, Oracle традиционно использует System V shared memory (через shmget) для System Global Area (SGA) — области, которую шарят все процессы базы.

Когда счёт идёт на микросекунды, копирование через ядро — роскошь. Нужен прямой доступ к памяти.

Ссылка на детали: тут

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Вот так для меня звучат все эти любители «красивых высокоуровневых абстракций»

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Задачки для тех, кто хочет прокачать GPU-программирование 🔥

Если хотите разобраться, как работают GPU и параллельные вычисления, попробуйте GPU-Puzzles

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

🟡Интерактивные упражнения
🟡Фокус на понимание GPU-алгоритмов
🟡Подходит как новичкам, так и опытным разработчикам

А здесь реализация задач на C++ — тык

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Инженер представил экспериментальный 8-битный софт-кор Mrav, работающий на FPGA. На вид скромный чип, но идея за ним куда интереснее: собрать железо и софт как единую систему, без разрыва между Verilog и C/ASM.

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

Автор называет это Hermetic Engineering: никакой ручной установки тулчейнов, симуляторов или FPGA-утилит. Одна команда поднимает окружение, собирает инструменты и прогоняет симуляцию. Получается полностью воспроизводимый «компьютер в коробке».

Для тех, кто интересуется SystemVerilog, Go, Bazel или просто любит смотреть, как с нуля рождаются процессоры, проект стоит внимания. 😎

Ссылка на проект: https://popovicu.com/mrav-cpu/

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Я обычно скептически смотрю на весь шум вокруг новых проектов, которые появляются пачками, но Zig реально выглядит как крутая тема.

Не так часто встретишь инструменты, собранные настолько аккуратно.

Один чистый статически слинкованный бинарь и всё нужное уже внутри.

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Проверь z-libs, если нужен удобный high-level API без потери сырой производительности C.

Сейчас там четыре маленькие однозаголовочные C-библиотеки, которые наконец делают работу с контейнерами в C нормальной:

→ zvec.h (динамический вектор, contiguous-память, swap-remove, сортировка/поиск)
→ zstr.h (нормальная UTF-8 строка с 22-байтовым SSO, views, форматирование, split)
→ zlist.h (двусвязный список, non-intrusive, splice за O(1))
→ zmap.h (hash table с open addressing, linear probing и cache-friendly поведением)

Дополнительно:

→ Ноль зависимостей
→ C11 и выше (строго по стандарту)
→ Полная type safety
→ Поддержка кастомных аллокаторов
→ MIT-лицензия

Работает в GCC, Clang, MSVC и так далее.
Никаких build-систем, никакого void*-хаоса и никакого макро-аду.

Просто кидаешь нужный .h — и оно работает.

Смотреть тут: https://github.com/z-libs

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Объяснение race conditions простыми словами. Хорошая отправная точка, чтобы разобраться с проблемами, которые возникают при работе с конкурентностью.

https://youtu.be/FY9livorrJI

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

gRPC обычно ассоциируется с микросервисами поверх HTTP/2.

Но знаешь, что можно гонять gRPC по шине гипервизора в Linux?

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

AF_VSOCK это семейство сокетов в Linux, которое обеспечивает коммуникацию между хостом и гостевой системой. QEMU поддерживает его нативно через устройство vhost-vsock-pci.

В gRPC на C++ это почти то же самое, что TCP. Единственное отличие это адрес. Вместо 127.0.0.1:8080 ты просто пишешь vsock:3:9999.

Всё остальное на уровне транспорта берет на себя библиотека gRPC.

Сервер: статически собранный бинарник, который запускается как init внутри гостевой QEMU-машины.

Клиент: статически собранный бинарник, который работает на хосте.

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

Зачем это делать?

Безопасность: сокет не торчит в локальную сеть.

Производительность: задержка ниже, чем у loopback TCP.

Проще настройка: никакого DHCP или сетевых мостов.

Хочешь попробовать? Вот гайд, как собрать это с нуля на Bazel и C++.

В нём есть нужные флаги для QEMU, Proto-файлы и процесс сборки debootstrap-образа, плюс ссылка на GitHub.

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Неправильное использование двумерных массивов может убить производительность.

Есть два простых способа создать двумерный массив int:

int**: выделять память построчно через malloc в цикле
int*: один большой непрерывный блок памяти

Разница? Первый вариант заметно медленнее.
Почему так происходит? Все упирается в cache locality.

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

Аппаратный prefetcher процессора пытается предугадать следующий адрес, но из-за разрозненности строк он промахивается. В итоге процессор простаивает, ожидая данные из оперативной памяти.

И да, RAM примерно в 100 раз медленнее L1 cache.

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

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

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Хочешь стать ниндзя в CUDA?

Начни с нового CUDA Programming Guide. Раздел 4 это твоя золотая жила.

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

Так что повысьте уровень своей игры на GPU

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

fff.nvim официально объявили самым быстрым файловым поиском

Разработчики fff.nvim показали демо поиска в реальном времени по директории на 100 000 файлов объёмом 6 ГБ из полного git-дерева ядра Linux.

По их словам, в реализации нет debounce. Поиск идёт прямо в основном UI-потоке, при этом система выдерживает до 120 поисковых запросов в секунду.

Среднее время одного запроса составляет 4,5 мс.

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

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

Вместо ручной сборки на Verilog он использует Bazel как единый источник истины. Периферия описывается один раз в конфиге, после чего билд-система автоматически генерирует SystemVerilog для шины и адресного пространства, создаёт ассемблерные библиотеки с нужными символами и вшивает прошивку прямо в RAM на уровне RTL.

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

Подробный разбор архитектуры доступен здесь

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Это... программирование как у истребительного пилота.

Одна необработанная ошибка уничтожила ракету за 500 миллионов долларов за считанные секунды.

F-35 не собирался повторять эту ошибку.

Инженеры, аккуратно «разрезая» C++, создали один из самых жестких стандартов кодинга, когда-либо написанных.

Фулл видео: смотрим

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Комьюнити, полезное для всех бекенд-разработчиков

Как работает VK изнутри? Что происходит за интерфейсами, когда миллионы пользователей одновременно отправляют сообщения, загружают фото и смотрят клипы?
В канале Backend VK Hub мы рассказываем о работе всех наших сервисах: от VK Play до Tarantool. Делимся подходами к масштабированию, оптимизации и новым архитектурным решениям. Открыто дискутируем, а также регулярно публикуем вакансии в нашу команду.

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

Читать полностью…

С/С++ Portal | Программирование

🔥3 декабря в Москве прошла OS DevConf 25 powered by GigaChat — конференция про разработку системного ПО, ядра Linux и open source

30+ докладов, 3 трека — концентрат практического опыта, знаний и инструментов, готовых к внедрению сразу по возвращению в офис.

Поговорили на такие темы:

-Инструменты и примеры отладки, виртуализации, оптимизации производительности
-Практический опыт оптимизации сетевых решений с DPDK
-Эффективные методы безопасной разработки ядра Linux
-Реальные кейсы создания драйверов на Rust
-Все про GPU, NPU, ASIC и как запускать AI на железе под Linux и не только. Как AI встраивается в современную разработку
-Современные подходы к разработке системного и embedded ПО

Много активностей, полезных докладов, и конечно же афтепати.

Уже скоро выложим видеозаписи конференции в наших соцсетях, а пока присоединяйтесь к сообществу по разработке системного ПО и Linux в России!

#реклама
О рекламодателе

Читать полностью…

С/С++ Portal | Программирование

Команда энтузиастов собрала впечатляющий набор проектов на миниатюрном ESP32C3 — микроконтроллере с 400 КБ RAM и одним RISC-V ядром. На этой скромной платформе им удалось запустить сразу несколько вполне серьезных штук:

• Space Invaders
• 3D wireframe-рендеринг в реальном времени
• распознавание жестов с помощью ML
• Wi-Fi-сканер
• систему кастомных bitmap-логотипов

В работе использовали C++, Adafruit GFX, ручную математику матриц для 3D и Python для конвертации в RGB565.

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

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Linux-ядро обычно просто угадывает.

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

Но иногда твоё приложение знает будущее.

Тут и появляется madvise (syscall №28 на x86_64).

Вот как перестать играть в угадайку.

madvise() позволяет шепнуть подсказку напрямую менеджеру памяти ядра.

Ты передаёшь диапазон памяти и стратегию.

«Я стримлю данные.»
«Я закончил с этим блоком.»
«Это секрет.»

Данные не меняются. Меняется только то, как ОС работает с физической RAM под ними.

Работаешь с ключами шифрования? 🔑

Используй MADV_WIPEONFORK

Это говорит ядру: «Если процесс сделает fork, отдай ребёнку нули вместо копии этого диапазона.»

Это предотвращает утечку секретов в дочерние процессы. (Работает только с private anonymous memory.)

#include <sys/mman.h>

// Protect the secret
madvise(secret_key, key_len, MADV_WIPEONFORK);


Стримишь 4K-видео? 🍿

Используй MADV_SEQUENTIAL

Этот хинт говорит Linux: «Форсь полный read-ahead, я читаю последовательно.»

Ядро усиливает prefetch, а эти страницы становятся кандидатами на ранний reclaim.

Помогает не засорять page cache данными разового использования.

MADV_GUARD_INSTALL 🛡

Позволяет ставить «мины» — guard-области в памяти, которые выбрасывают SIGSEGV при доступе.

Раньше работало только для anonymous memory, теперь доступно и для file-backed mappings.

Отлично подходит для дебаггеров и тулов по анализу безопасности памяти.

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

❤️ Как не попасть в ловушку масштабирования при росте нагрузки в PostgreSQL?

В видеопроекте Road to Highload разработчик ядра Яндекс Диска Андрей Колнооченко рассказывает, как проектировать и развивать базы данных так, чтобы они оставались стабильными и быстрыми даже при росте QPS и объёма данных.

Разберём реальные примеры и обсудим типичные ошибки и подходы, которые помогают избежать проблем с производительностью и консистентностью. Особое внимание уделим согласованности кода и данных в БД для предотвращения проблем с race conditions, которые часто возникают при росте нагрузки.

Road to Highload — это цикл видео от Яндекс 360 о том, как строятся системы, которыми ежедневно пользуются миллионы людей и тысячи компаний. Здесь говорят о highload и отказоустойчивости не по учебникам, а на основе многолетнего опыта разработки.


Смотрите проект, чтобы узнать, как создаются одни из крупнейших облачных сервисов в России:

Сайт проекта
VK Видео
Ютуб

Читать полностью…

С/С++ Portal | Программирование

Memory-mapped I/O на Linux работает быстро, но у этого подхода есть неприятный момент.

Когда ты пишешь в memory-mapped файл (mmap), ты не пишешь на диск. Ты пишешь в RAM, точнее в Page Cache.

Если в этот момент пропадет питание, данные улетят в небытие.

Здесь появляется msync (системный вызов номер 26 на x86_64). Это своего рода кнопка Save для mmap.

Когда ты делаешь mmap() файла, ядро напрямую отображает блоки файла в память.

Чтение и запись происходят в памяти и не требуют read() или write(), что экономит системные вызовы.

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

msync позволяет указать диапазон памяти и заставить ядро записать его на устройство хранения.

Это мост между скоростью оперативки и безопасностью постоянного хранилища.

Пример на C:

int fd = open("db.dat", O_RDWR);
char *p = mmap(0, 4096, PROT_WRITE, MAP_SHARED, fd, 0);

// Запись в RAM
sprintf(p, "Critical Data");

// Сброс на диск
msync(p, 4096, MS_SYNC);


Обрати внимание на флаг MS_SYNC. Он говорит ядру:
блокируй выполнение и не возвращай управление, пока данные не окажутся на диске.


Важно. Даже после msync данные могут остаться в write-кеше самого диска. Для реальной гарантии нужны диски, которые корректно сбрасывают кеш на питание.

Есть еще флаг MS_ASYNC — он просто помечает данные на запись и сразу возвращает управление.

Но начиная с Linux 2.6.19 ядро само настолько эффективно трекает dirty-страницы, что MS_ASYNC, по сути, бесполезен.

Есть еще MS_INVALIDATE для обновления других отображений, но из-за unified page cache в Linux это почти никогда не нужно на локальных ФС.

Если тебе нужны гарантии, MS_SYNC — единственный флаг, который реально имеет смысл.

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Лучшее, что может получить программист C++

https://agner.org/optimize/optimizing_cpp.pdf

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Наглядно как выглядит выравнивание данных в памяти

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

А что если компилятор помогал бы писать потокобезопасный C++ код?

В этой статье объясняется, как Clang использует аннотации и статический анализ, чтобы находить race conditions еще на этапе компиляции.

https://research.google.com/pubs/archive/42958.pdf

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

Тебе не обязательно настраивать сеть, чтобы коннектиться к своей Linux VM.

Ни IP-адресов. Ни SSH-ключей. Ни правил в фаерволе. Ни таблиц маршрутизации.

Если хост и виртуалка работают на одной физической машине, TCP/IP иногда просто лишний слой.

Знакомься: AF_VSOCK.

Это специальное address family в ядре Linux, рассчитанное именно на обмен данными между гипервизором и виртуальными машинами.

Можно представить это как трубу, которая проходит сквозь стену виртуалки.

Вместо IP (192.168.x.x) используется Context ID (CID). У хоста обычно CID 2. У гостя свой CID, например 3.

Дальше всё делает ядро, гоняя данные между памятью хоста и гостя.

Сервер крутится внутри виртуалки (C++). Клиент работает на хосте. А задержка? Почти нулевая.

Если тебе нравится низкоуровневая возня с Linux — ставь лайк 👍

👉 @Cpportal

Читать полностью…

С/С++ Portal | Программирование

У процесса в Linux может быть раздвоение личности. 🎭

У него сразу две идентичности:

1. Реальная (тот пользователь, который запустил процесс).

2. Эффективная (пользователь, от имени которого процесс сейчас выполняется).

На этом работает sudo. И из-за этого появляется интересная задачка с точки зрения безопасности.

Загадка такая: программа, запущенная с root правами (эффективный ID), должна понять, может ли исходный пользователь (реальный ID) получить доступ к файлу.

Как ей проверить твои права, не отказываясь от своих root-возможностей? Просто вызвать open() не получится, он смотрит только на эффективный ID, у которого полный доступ.

И вот зачем существует системный вызов access()

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

Он позволяет привилегированной программе безопасно спросить у ядра:

"Тот пользователь, который меня запустил, вообще может читать этот файл?"


Но никогда не используй access() для проверки прав перед тем, как открыть файл через open().

Вот так работает access() на практике. Этот C-код проверяет, может ли реальный пользователь читать /somefile.

Даже если на этой программе стоит setuid-бит и владельцем является root, access() вернет -1, потому что он проверяет права против ТВОЕГО реального UID, а не эффективного root UID.

#include <unistd.h>
#include <stdio.h>

int main() {
if (access("/somefile", R_OK) == 0) {
printf("Real user can read /somefile.\n");
} else {
perror("access");
}
return 0;
}


Такой подход создаёт классическую гонку TOCTOU (Time-Of-Check-To-Time-Of-Use). Злоумышленник может подменить файл между проверкой и открытием, и твоя программа попадется на удочку.

Итого = access() полезен, когда нужно проверить права от имени пользователя, но он может стать миной под ногой, если применять его как фильтр перед доступом к файлу.

Это важный элемент модели безопасности Linux.

👉 @Cpportal

Читать полностью…
Subscribe to a channel