Обновить
256.05

C++ *

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

Сначала показывать
Период
Уровень сложности

Game++. run, thread, run…

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

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

В обычном программировании с блокировками, когда возникает необходимость пошарить данные, приходится использовать механизмы сериализации доступа к таким данным, чтобы операции, выполняющие работу с такими данными, были ограничены от одновременного вмешательства со стороны других потоков и возможности их поломать. В прямом смысле поломать. Даже такая простая операция, как ++count, где count имеет тип integer, требует блокировки, поскольку операция инкремента в общем случае представляет собой трехшаговую операцию (чтение, модификация, запись), которая не является атомарной. Про что-то более сложное и длительное я уже и не говорю.

За кажущейся простотой скрывается множество граблей и ловушек: взаимные блокировки (deadlock), «голодание» потоков, асинхронные ошибки. Это похоже на попытку дирижировать оркестром, где музыканты игнорируют ритм. Проще говоря, любые действия над данными могут привести к проблемам, и чтобы этого не происходило, операции над данными должны быть атомарными, это решается вводом в код примитивов синхронизации, вроде мьютексов, семафоров, спинлоков.

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

Читать далее

Автоматизация процессов в гидравлических системах

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

Проект автоматизации процесса поддержания давления в гидравлическом прессе.

Разработка позволяет производителям сыродавленного масла экономить до нескольких часов своего времени в день.

Читать далее

Анатомия performance-critical C++ кода на примере ECS

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

Всем привет! Это продолжение статей про мою ECS with Sectors в моём движке Stellar Forge!

В предыдущей статье я описал структуру памяти, что являлось подготовкой фундамента для быстрой итерации, а сейчас хочу рассказать как по этой памяти передвигаться.
Получилась общая обзорная статья о том, как заставить C++ код быть быстрее, так что устраивайтесь поудобнее :-)

Статья будет полезна всем, кто пишет performance-critical код на C++: геймдев, HFT, обработка данных, embedded.

Читать далее

Кто быстрее: исследую производительность std::format

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

Я, как и многие другие другие разработчики на C++, слышал о преимуществах нового std::format: удобство, безопасность и высокая производительность по сравнению с более старыми способами форматирования строк. 

Моя жизнь была прекрасна и полна надежд, пока я не увидел один бенчмарк, где format оказался медленнее всех. Как же так? Неужели «устаревший» std::stringstream или даже operator+ все еще лучше? Далее расскажу о своем небольшом исследовании производительности форматирования, доступного разработчикам на C++, и о необычных результатах, которые я получил.

Читать далее

Как правильно вызывать CUDA

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

Вероятно, вам уже попадались подобные руководства по CUDA: хрестоматийный пример «Hello World», в котором перемешан код для ЦП и графического процессора. Всё это сложено в один гетерогенный файл с исходниками на CUDA C++, а для запуска ядра применяется синтаксис NVCC с тройными угловыми скобками <<<>>>, который уже стал культовым:

Читать далее

Программируем SFP-модули на программаторе CH341A

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

Прошло уже более года с момента моей публикации о программаторе для CH341A под Linux - IMSProg и у меня возникло желание избавиться от еще одной программы, не дающей навсегда забыть о существовании Windows. Мой прежний программатор SFP собран на чипе FT232RL и имел софт только под Windows.

Каждый SFP-модуль имеет с своем составе стандартную микросхему 24C04 или 24C02, что натолкнуло меня на мысль использования простейшего переходника для программатора CH341 с использованием четырех проводов - земли, питания, I2C сигналов SDA и SCL. После просмотра разработок различных фирм я добавил в переходник джамперы на сигналы питания для снятия защиты от записи медных модулей - J1, J2 и J3 (контакты SFP TxPWR, RxPWR и TxEN). В результате получилась такая схема:

Читать далее

simstr — ещё одна строковая библиотека

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

Работа со строками в С++ - зачастую больная боль.

Однако за 25 лет я сумел найти лекарство от этой боли и после 13 лет разработки и испытаний готов поделиться им со всеми страждущими.

simstr — библиотека для использования строк в C++, в которой пишется легко и удобно, а выполняется быстро и оптимально.

Читать далее

Как сокращение полных путей файлов в логах влияет на производительность и размер Браузера

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

Всем привет! Меня зовут Илья Кара́псин, я работаю над производительностью Яндекс Браузера. Задачи моей команды включают не только работу над самим браузером, но и прямое улучшение используемых в нём опенсорс‑решений, например Chromium и применяемых в нём проектов (Blink, V8, Catapult), в том числе и компиляторов (LLVM Clang). Другими словами, мы вносим вклад в сообщество. При этом поиск и создание улучшений для сторонних опенсорс‑проектов может стать прямой рабочей задачей даже в ходе стажировки.

К слову, моя работа в Браузере как раз с неё и началась. При отборе положительно сказалось наличие у меня pet‑проектов: отдельного внимания заслужил проект, использующий озвучку и SFX (сноска: сокращение от англ. sound effects — звуковые эффекты) из Heroes of Might and Magic V. Так удивительно совпало, что мой будущий руководитель ранее работал в Nival Interactive как раз над этой игрой.

А в этой статье я расскажу о том, как обычное сокращение полных файловых путей в логах до имени файла (например, path/to/filename → filename) может повлиять на размер исполняемых файлов и производительность Браузера, а также внести вклад в проект LLVM Clang.

Читать далее

Как правильно готовить std::span

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

Сегодня мы поговорим про std::span и как не порезаться на острых углах C++.

Согласно определению на cppreference, шаблон класса span описывает объект, который может ссылаться на непрерывную последовательность объектов, где первый элемент последовательности находится на позиции ноль.

Вообще, с учётом того, что, начиная с С++17 мы уже знакомы с понятием string_view, можно представить, что std::span — это нечто подобное, только действующее для непрерывных участков памяти, которые ещё можно и модифицировать. Но не будем забегать вперед, обо всех свойствах по-порядку.

Читать далее

Ложные убеждения о нулевых указателях

Время на прочтение10 мин
Охват и читатели4.7K
В этой статье предполагается, что вы знаете, что такое неопределённое поведение, и почему его не следует провоцировать, в самом общем виде знаете, как работают процессоры, а также умеете принимать во внимание конкретный контекст, не злоупотребляя излишним обобщением частностей. Эти убеждения можно считать заблуждениями, так как они не применяются глобально, а не потому, что обратное от них действует глобально. Если вы не уверены в себе, то, возможно, от прочтения этого текста вы больше проиграете, тем самым подпортив себе навыки программной инженерии. Поэтому ничего страшного, если вы не будете знакомиться с постом, а просто почитаете комментарии на Reddit — там уже написали, что может пойти не так, если вы, несмотря ни на что, углубитесь в этот материал.

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

Портируем ML на RISC-V: как не потерять производительность

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

Современные ML-системы опираются на CPU и ускорители — тензорные или графические. Но их производительность часто ограничена пропускной способностью шины между CPU и GPU: данные приходится постоянно перегонять туда-сюда, и выигрыш от ускорителя нередко тает.

Что если есть архитектура, где этого узкого места нет? RISC-V предоставляет гетерогенность принципиально нового уровня, объединяя ключевые компоненты устройства на одном кристалле, что снимает одно из главные ограничений производительности в ML. Но одних процессоров здесь мало — нужна еще экосистема библиотек.

Читать далее

Визуализация горного ландшафта на C++ или велосипед для рендеринга

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

Основной целью этой работы было попытаться реализовать реалистичную сцену горного ландшафта с воздушным шаром, используя "чистый" C++ и QT только для вывода пикселей. Мне было интересно превратить код в картинку, не имея других инструментов.

Читать далее

librats: новая библиотека для распределённых P2P-приложений

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

Всем привет! Я являюсь создателем распределённого поисковика rats-search на базе DHT ( GitHub ). Его принцип работы довольно прост: поисковик собирает торренты у всех участников сети и формирует большую распределённую базу для поиска, включая метаданные (например, описания и прочую информацию).

В этой статье я хочу рассказать о своей новой библиотеке для построения распределённых приложений (p2p), где знание IP-адресов участников не обязательно, а поиск ведётся через различные протоколы — DHT, mDNS, peer-exchange и другие. Думаю, с учётом постоянных неприятностей, которые происходят вокруг, это может оказаться полезным ;-).

Читать далее

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

Барьеры и модели памяти – explained

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

Всем привет! 

Начну с предыстории.

Когда мы в Амазоне планировали переносить сервис с x86/64 на ARM, почему-то никто в нашей команде не поднял тему того, что надо уделить особое внимание работе с многопоточностью и синхронизацией, так как из-за того, что у этих двух архитектур разные модели памяти, могли случиться неожиданные проблемы.

Однако, на тот момент я тоже об этом не знал, и нам повезло, что мы изначально везде использовали модель памяти Sequential Consistency (что это – далее в статье), поэтому все прошло гладко. Теперь, зная про модели памяти и возможные последствия, боюсь представить, что было бы в противном случае.

Как родилась статья

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

Статья основана на материалах лекции Computer Science Center (CSC) с курса “Параллельные вычисления” преподавателя Калишенко Е.Л. Крайне рекомендую ознакомиться со всеми лекциями курса (более структурированного материала по теме я еще не встречал). Благо он в открытом доступе – ссылка.

Что такое барьеры памяти и зачем это все нужно?

Начнем с небольшого описания того, как устроена “условная” архитектура процессора. Почему условная? Потому что может отличаться в зависимости от конкретной реализации, но суть похожа. 

Читать далее

Обход Cloudflare. Часть I

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

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

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

А ну-ка, что там?

Компилируем Python так, чтобы он работал везде

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

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

Читать далее

Пять лет спустя: почему мы всё переписали с нуля

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

Пять лет назад на Хабре мы писали о Web Camera Pro — и казалось, что впереди только апдейты, оптимизации и новые функции. За это время изменилось многое — и не только в технологиях, но и в законодательстве.

Как мы наступили на те же грабли

Когда в 2015 году мы начинали разработку системы для видеонаблюдения, Qt 5 казался идеальным решением. На первый взгляд всё выглядело просто: берём готовые библиотеки, оборачиваем в красивый интерфейс, добавляем AI-аналитику — и готово.

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

“Один фреймворк, любая платформа” — звучало как музыка.

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

Qt позволял быстро собрать прототип, но, когда речь заходила о стабильности, о 24/7-нагрузке, о реальной работе с потоками и камерами, его недостатки становились критичны.

Читать далее

О векторном вычислении экспоненциальной функции

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

Как вычислить экспоненциальную функцию быстро и с минимальной погрешностью? Пишем векторизованный код.

Читать далее

Rust в режиме «жесть»

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

В этом посте будет разобрано, как написать приложение на Rust с применением самого минимального API, возможности которого искусственно ограничены (например, не применяется динамическое выделение памяти). Предполагается, что читатель немного знаком с языком Rust.

Читать далее

3200% нагрузки на процессор

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

Совсем недавно моя машина была в таком запущенном состоянии, что я едва мог подключиться к ней через ssh. 3200% нагрузки на CPU — полностью использовались все 32 ядра хоста! Сравните это с моим последним багом, когда использовалось всего одно ядро, то есть 100%

К счастью, я использовал среду выполнения Java 17, у которой были дампы потоков с указанием времени CPU!

Читать далее

Вклад авторов