Все потоки
Поиск
Написать публикацию
Обновить
175.37

C++ *

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

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

Улучшаем компиляторы. Не сами, но без нас никак

Уровень сложностиПростой
Время на прочтение3 мин
Количество просмотров2K

Ведущий инженер-разработчик Postgres Professional Николай Шаплов столкнулся с неожиданной проблемой при тестировании: коллизии хэшей в clang ломали метрики покрытия. Расскажем, как удалось решить эту задачу и что это меняет для всего сообщества.

Читать далее

DIY-проект: гусеничная платформа с ИК-управлением на Arduino

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

В статье расскажу, как собрать гусеничную платформу, управляемую ИК-пультом. Платформа будет принимать команды с пульта через ИК-датчик, которые будут обрабатываться платой Iskra mini (российским аналогом Arduino mini).

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

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

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

Читать далее

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

Время на прочтение16 мин
Количество просмотров14K

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

Читать далее

Три теоремы о сортировках

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

Я знаю многих программистов и руководителей в IT компаниях, которые недолюбливают математиков и в частности считают их далёкими от жизни идиотами из-за их утверждений в духе "нельзя отсортировать последовательность быстрее, чем за nlogn" -- ведь это очевидным образом неверно, есть же сортировка подсчетом и radix sort. Нюанс в том, что описанное выше -- это распространённая некорректная трактовка одной из ключевых теорем об алгоритмах сортировок, корректное утверждение выглядит так: "не существует алгоритма, который бы гарантированно находил перестановку n элементов, приводящую к возрастающему порядку, быстрее чем за nlogn используя только операции попарного сравнения". В этом утверждении больше слов, оно более сложно в плане когнитивного восприятия, ключевой момент обозначил жирным шрифтом, чувствуете разницу?

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

Если я ещё не убедил Вас прочитать статью, то вот моя последняя попытка: в статье объясню почему пузырёк -- это бесполезная фигня, но внезапно практически также работающая сортировка вставками -- это супер важная сортировка, являющаяся частью std::sort в MSVC, GCC и Clang. Расскажу, каким интересным свойством оптимальности обладает сортировка выбором, являющаяся в теории такой же неэффективной как пузырёк.

Читать далее

Разгон Мандельброта: SIMD с бубнами, OpenMP и CUDA

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

Построение множества Мандельброта — классический пример чрезвычайно параллельной задачи (embarrassingly parallel problem).

На первом курсе я впервые столкнулся с такой проблемой: тогда мы изучали SIMD-инструкции в курсе архитектур вычислительных систем. Эта тема сразу меня увлекла, и я захотел углубиться в дальнейшие оптимизации, но в течение семестра мне не хватало ни времени, ни знаний. Спустя год я решил восполнить этот пробел.

Вначале мы разберем наивную реализацию, поиграемся с интринсиками (intrinsics) и, не теряя переносимости, заставим компилятор генерировать нам SIMD-инструкции. Далее добавим многопоточность и в заключение обесценим все наши старания несколькими строчками на CUDA.

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

Читать далее

Можно ли навсегда избавиться от утечек памяти из-за циклических ссылок?

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


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


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


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


Но мне кажется, что есть очень простой способ устранить циклические ссылки в программе, который можно реализовать практически в любом типизированном языке программирования, конечно, если при этом не использовать все разрешающее ключевое слово unsafe для Rust или оператор reinterpret_cast в случае С++.

Читать дальше →

FFI: как создать мост между Rust и C/C++

Время на прочтение12 мин
Количество просмотров4.4K

Привет, Хабр!

Сегодня мы рассмотрим, как создать безопасные FFI-интерфейсы в Rust для интеграции с C/C++ библиотеками

Если говорить проще, FFI (foreign function interface — интерфейс вызова внешних функций) – это способ «позаимствовать» функциональность из другого языка. В контексте нашей статьи, с одной стороны у нас Rust, где каждый байт памяти охраняется компилятором, а на другой C++, где свобода обращения с памятью может обернуться утечками или, что еще хуже, непредсказуемым UB (англ. undefined behavior, в ряде источников непредсказуемое поведение). И наша задача – сделать так, чтобы эти два мира не конфликтовали, а работали в унисон.

Читать далее

Mask R-CNN 3D

Уровень сложностиСредний
Время на прочтение21 мин
Количество просмотров1.3K

Mask R-CNN 3D – это расширение знаменитой модели Mask R-CNN для работы с трехмерными данными (объёмными изображениями или облаками точек). Классическая Mask R-CNN предназначена для instance segmentation (сегментации отдельных объектов) на 2D-изображениях и состоит из двух основных частей: (1) сети предложений областей (Region Proposal Network, RPN) и (2) головы (Head) с несколькими выходными ветвями для классификации, регрессии ограничивающих рамок и сегментации масок . В версии 3D эта же концепция перенесена в трехмерное пространство.

Входом модели Mask R-CNN 3D обычно является объёмный данных – например, медицинский 3D снимок (CT/MRI) размером (D×H×W) или облако точек, представляющее 3D-сцену. Backbone-сеть (обычно сверточная нейросеть типа ResNet) извлекает из входных данных многомасштабные признаки. В 3D версии backbone заменяет все 2D-операции (свертки, пулинг) на 3D-аналоги, позволяя обрабатывать объёмные данные напрямую. (Если 3D-данные заданы как облако точек, возможно предварительное преобразование, например, вокселизация пространства или проекция на несколько 2D-плоскостей – об этом подробнее в разделе 6.) Backbone формирует карты признаков – объёмные тензоры с пониженным разрешением, но содержащие высокоуровневую информацию о структуре объектов в сцене.

Далее вступает Region Proposal Network (RPN) – небольшая сеть, скользящая по картам признаков и генерирующая набор предположительных объектов (region proposals) в виде ограничивающих 3D-рамок (прямоугольных параллелепипедов в координатах исходного объёма). RPN использует заранее заданные «якоря» (anchor boxes) – шаблонные 3D-боксы разных размеров и соотношений сторон, размещенные по всей карте признаков . Для каждого такого anchor RPN предсказывает два значения: объектность (есть объект/фон) и смещение рамки (на сколько нужно подвинуть и масштабировать anchor, чтобы точнее охватить объект). После этого выбираются топ-N наиболее перспективных предложений с помощью non-maximum suppression (NMS) – подавления пересекающихся рамок с меньшей оценкой.

Читать далее

Истинное предназначение пресетов в СMake

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

Система сборки CMake имеет в арсенале достаточно мощный инструмент - пресеты, шаблоны, называйте как угодно. В данной статье будет рассмотрено применение пресетов на примере модульной библиотеки реализующей функционал engine-а для OpenSSL и описано как перенести опции для кросскомпиляции в пресеты.

Читать далее

Game++. Unpacking containers

Уровень сложностиПростой
Время на прочтение40 мин
Количество просмотров4.2K

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

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

Если вы не готовы писать и поддерживать свою STL, старайтесь, использовать vector, он хотя бы предсказуем по времени на всех платформах. Так вам скажет большинство разработчиков игр на C++, но проблема в том, что vector перераспределяет хранимые объекты в памяти при вставке новых элементов, а также при удалении любого элемента, кроме последнего. Это означает, что указатели на элементы вектора становятся недействительными, и тогда все зависимости и взаимодействия между элементами перестают работать.

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

Читать далее

Передача данных от ESP32 по Bluetooth LE к Android

Уровень сложностиСредний
Время на прочтение20 мин
Количество просмотров8.9K

Идея приложения состоит в демонстрации IoT - интеграция различных устройств, и передача данных по разным протоколам в Edge или Cloud. Допустим, наш автономный механизм работает без подключения к интернету, а нам необходимо сделать замеры поведения движений во времени. Мы подключаемся с помощью смартфона по Bluetooth LE к контроллеру механизма и в течении определенного времени делаем запись. При этом наш смартфон успешно подключается к облачному MQTT-брокеру и передает данные в IoT платформу. Платформа производит аналитику и предоставляет нам результат. А мы в это время на основании полученных данных можем внести требуемые значения характеристик механизма в контроллер по BLE.

В статье Machine learning на ESP32 мы начали разработку проекта распознавания жестов для ESP32. В данной статье продолжим реализацию подключение и отправку данных по BLE и MQTT с помощью Android-устройства. Хотя ESP 32 может напрямую подключаться к Wi-Fi и MQTT, как, например, показано в статье Платформа с web-камерой на ESP32, мы все же реализуем передачу данных по BLE, руководствуясь выше изложенными соображениями.

Читать далее

Сортировка слиянием на CUDA

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

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

В качестве тестового я возьму алгоритм сортировки слиянием (merge sort), потому что он удобно разбивает задачу на меньшие подзадачи с двумя равными половинами, что хорошо подходит для параллельных вычислений.
Читать дальше →

Учимся рефакторить код на примере багов в TDengine, часть 2: макрос, пожирающий стек

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров1.8K

Макрос пожирает стек


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

Читать дальше →

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

Пишем калькулятор на C++ с SFML

Время на прочтение11 мин
Количество просмотров12K

Привет, коллеги и доброжелательные критики! Сегодня я решил отвлечься от своей громоздкой работы, чтобы написать что-то простое, но с изюминкой — калькулятор с графическим интерфейсом на C++20 и SFML. Этот проект — не претензия на что-то грандиозное, а скорее лёгкий эксперимент, чтобы вспомнить, как приятно писать код, который сразу видно на экране. Заодно я поделюсь с вами своими мыслями, подходами и парой советов. Давайте разберём, как я это закрутил и почему выбрал именно SFML.

Читать далее

Machine learning на ESP32

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

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

В этом примере используются измерения акселерометра MPU 6050 и машинное обучение (ML) для распознавания трех жестов рукой с помощью ESP32. Данные из сенсора распознаются на микроконтроллере и результат выводится в консоль в виде названия жеста и вероятности результата. Модель ML использует TensorFlow и Keras и обучается на выборке данных, представляющей три различных жеста: "circle" (окружность), "cross" (пересечение) и "pad" (поступательное движение).

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

В следующей части рассмотрим как настроить Bluetooth LE (BLE) на ESP32 и Android устройстве. Передадим квантированный набор ускорений сенсора по BLE. Настроим Модель ML для распознания жестов на Android.

Читать далее

Быстрая свёртка множеств (алгоритм)

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

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

Статья будет интересна тем, кто интересуется нетривиальными, но красивыми алгоритмами!

Читать далее

ProxyOrmModel — ORM-подход к работе с данными в Qt

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров1.2K

Привет, Хабр! В этой статье я хочу рассказать о своём проекте — библиотеке ProxyOrmModel для Qt, которая упрощает работу с данными в моделях. Если вы когда-нибудь сталкивались с необходимостью фильтровать, сортировать, группировать или агрегировать данные в QAbstractItemModel, то, вероятно, знаете, как это может быть утомительно. Я решил создать инструмент, который делает это проще и удобнее, вдохновившись идеями ORM (Object-Relational Mapping) из мира баз данных. Здесь я поделюсь архитектурой, ключевыми классами и уроками, которые я вынес из разработки.

Читать далее

Лампа для подсветки рассады или просто таймер. Конструкция выходного дня

Уровень сложностиСредний
Время на прочтение2 мин
Количество просмотров2.8K

Контроллер Лампы для Рассады

Умный контроллер освещения на базе ESP32 с управлением через Telegram бот. Проект выходного дня для любителей растениеводства.

Читать далее

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

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

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

Линейный криптоанализ. Как работает современное шифрование. Часть 1/2

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

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

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

Читать далее

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