Обновить
256K+

C++ *

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

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

Как убрать virtual и не сойти с ума: велосипедные генераторы через type loopholes

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

В C++ уже есть корутины. Есть диапазоны. Есть готовые библиотеки.

Но это не мешает взять гаечный ключ и начать собирать генератор вручную.

В предыдущей статье макросы внезапно начинают изображать из себя язык: DO, LET, IS управляют препроцессорным ритуалом и создают DSL. Это синтаксис. Это оболочка. Это фронтенд.

(чтение предыдущей статьи необязательно для понимания этой)

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

В этой статье я строю велосипедный генератор. Самый честный.

Читать далее

Как разработать устройство с нуля. Прибор измерения ёмкости конденсаторов

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

В статье проектируется с нуля мобильное устройство для измерение емкости на микроконтроллере ATmega8.

Читать далее

C3D PolyShaper: современные возможности и перспективы развития

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

Александр Лонин, руководитель группы полигонального моделирования, C3D Labs, рассказывает о функциональности и перспективах развития модуля C3D PolyShaper. Рассматриваются методы создания и обработки полигональных объектов, новые алгоритмы сшивки и улучшения в триангуляции, а также диагностика и исправление дефектов сеток. Автор делится планами по реверс-инжинирингу органических форм, работе с неявными поверхностями и учету неманифолдности в булевых операциях.

Мы консолидировали все наработки по полигональному моделированию, результатом чего стал новый модуль в составе C3D Toolkit — C3D PolyShaper. Этот модуль официально зарегистрирован в реестре отечественного программного обеспечения. Он представляет собой набор классов и функций для работы с полигональными объектами и топологией. Рассмотрим текущую функциональность модуля, направления разработки и перспективы дальнейшего развития.

Полигональный объект с топологией может быть получен несколькими способами: путем конвертации из ранее существовавшего объекта MbMesh, считыванием данных из файлов форматов JT, STL и OBJ, созданием на основе параметрической оболочки или построением вручную. При чтении данных из файла необходимо восстановить топологическую информацию — другими словами, выполнить сшивку модели. Алгоритм сшивки был усовершенствован и теперь способен обрабатывать случаи с совпадающими треугольниками, что особенно актуально при работе с моделями строительных конструкций.

Читать далее

Делаем интернет-радиоприемник на базе ESP32-S3 за один вечер

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

Всем привет, дорогие читатели! Расскажу вам о том как сделать интернет-радио на «скорую руку» без особых хлопот.

Читать далее

Использование OPC UA на нативном приложении в технологии MFC MS Visual C++

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

Ключевые аспекты проектирования и реализации SCADA-систем в автоматизированных системах управления технологическими процессами (АСУТП). Основное внимание уделяется интеграции с базами данных, такими как SQL Server, и использованию протокола OPC UA для взаимодействия с контроллерами.

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

Читать далее

Процессор в вашем компьютере угадывает будущее. И ошибается в 5% случаев

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

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

Потому что ответ звучит безумно: процессор внутри вашего ноутбука постоянно пытается предсказать будущее. Буквально. Он гадает, какая ветка if выполнится ещё до того, как условие будет вычислено. И на отсортированных данных ему угадывать проще.

Ну, давайте разбираться.

Читать далее

Сколько на самом деле стоит LOG_INFO(): benchmark библиотек логирования C++

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

Логирование есть практически в каждом C++ проекте. Почти любой сервис, демон или библиотека рано или поздно обрастает строками вроде LOG_INFO(...) или logger.debug(...).

Чаще всего библиотека выбирается по привычке или популярности — spdlog, quill, easylogging++ и т.п. При этом редко кто проверяет, какую цену приложение платит за логирование.

В высоконагруженных системах логирование может выполняться:

Читать далее

Умножение матриц: пример использования расширения ARM SME2 в Apple M4 Pro

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

В конце 2020 года я купил MacBook Pro 13 на процессоре Apple M1, очень хотелось испытать процессоры на архитектуре ARM. Почти сразу на чипе Apple M1 был найден вычислительный блок для матричных операций Apple AMX. Для Apple AMX не было документации, он не использовался в Apple Accelerate, но несколько энтузиастов занимались реверс-инжинирингом и анализом производительности ("https://github.com/corsix/amx"). 

В 2024 году вышли компьютеры на базе семейства процессоров Apple M4, у которых блок AMX задействован для выполнения инструкций из Scalable Matrix Extension 2 (сайт ARM недоступен в РФ) (ARM SME2). 

В статье рассмотрим использование расширения ARM SME2 на примере умножения заполненных матриц. Увидим, как выжать максимум из процессора и получить прирост производительности в десятки раз.

Читать далее

Черная магия unsafe в Go: практические примеры и ошибки использования. Часть 2

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

Привет, Хабр! Я — Владимир Балун, и это — вторая часть материала о пакете с отпугивающим названием «unsafe» в Go и том, чем он может быть реально полезен. В первой части мы рассмотрели его содержимое, особенности и нюансы, оптимизации кода с использованием unsafe — все это вы можете освежить в памяти по ссылке.

Сегодня перейдем непосредственно к той самой «магии»: трюки, хаки, советы и лучшие практики с моей стороны.

Читать далее

Превращаем MIDI клавиатуру в синтезатор. Часть 2. MINI-JV880pi

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

Итак, я решил довести до реально работающего проекта превосходный эмулятор синтезатора Roland JV880. Это рэковый модуль (без клавиатурный), сделанный на базе синтезатора JV80. Соответственно он поддерживает все карты расширения этого синтезатора и почти все MIDI команды.

Подробнее

Нескучное программирование. Обобщения (ч.2)

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

Это не отдельная статья, а продолжение статьи про теорию объектов в с++, почему объекты в плюсах такие какие есть. Все завершенные главы я также выкладываю на github'e в английском и русском варианте. Продолжаем разбираться в теории С++...

Отдельного разговора заслуживает идентичность объектов, потому что в реальном мире конкретные сущности обладают идентичностью и Сократ останется Сократом независимо от того, перекрасил ли он волосы, сменил адрес или умер, а государство остаётся тем же государством, даже если меняет флаг, конституцию или размер населения. 

Чтобы отразить это в программе, объекты, представляющие конкретные сущности, нуждаются в своём определении идентичности, которая отделена от текущего состояния. Удобный способ ввести такую идентичность будет сделать некий токен идентичности, уникальное значение, которое выражает "кто это", а не "в каком он сейчас состоянии". Таким токеном может быть, например, адрес объекта в памяти, индекс в массиве, или табельный номер сотрудника в кадровой системе и проверяя равенство токенов идентичности, мы фактически проверяем тождественность объектов: один и тот же объект или разные. 

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

Читать далее

Множество Мандельброта. Суперсэмплинг 2x2 (4 прохода). DwmFlush — синхронизация с монитором 60 fps

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

Множество Мандельброта. 80-бит FPU x87. OpenMP - параллельным программированием на уровне многопоточности. Синий, зеленый и красный - синусоидальными и косинусоидальными волнами: 127 + 127 cos(2 PI a / 255) и 127 + 127 sin(2 PI a / 255). DwmFlush - синхронизация с монитором 60 fps. Суперсэмплинг 2x2 (4 прохода). Делал я. Посмотрите - движется! Я сделал на g++. Свободно распространяемого компилятора языка C++. Скачайте и посмотрите! Это экзешник, в ГитХаб.

github: Download Latest Version Windows And Source code

Самое полезное - это увеличиваем / уменьшаем и центрируем. Вы на экран любое из множество Мандельброта. Какое вам нравится? Какое интересное? Вы можете все! И потом запишется в файл Mandelbrot.txt - три строки из файла. Вещественная часть центра и мнимая часть центра и ширина видимой области. Потом другая программа читает Mandelbrot.txt и создает Mandelbrot.bmp и уже не суперсэмплинг 2x2 (4 прохода) а 8x8 (64 прохода)!

Читать далее

Как я написал Qt-приложение, почти не написав код

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

Всё началось с эксперимента. На основной работе руководство довольно настойчиво рекомендовало использовать ИИ в разработке. В какой-то момент мне стало интересно, насколько далеко можно зайти в этом направлении. Можно ли написать реальное десктопное приложение так, чтобы основную часть кода писал ИИ?

Не в смысле «иногда подсказать синтаксис» или «помочь найти ошибку». А именно в буквальном смысле — чтобы код писал ИИ, а человек формулировал задачи и проверял результат.

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

В итоге кандидатов оказалось два.

Первый вариант — написать утилиту для расчёта коэффициентов цифровых фильтров. Такие инструменты используются для расчёта фильтров с заданными характеристиками — например, с нужной формой АЧХ, ограниченной задержкой и длиной фильтра.

Задача инженерная и интересная.

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

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

Про саму голову я уже писал на Хабре:

https://habr.com/ru/articles/1007864/

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

Читать далее

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

Как я делал эконом-вариант датчика качества воздуха для своего Home Assistant и что из этого вышло

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

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

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

Читать далее

Рефлексия в Unreal Engine или как движок знает о вашем коде всё

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

UHT сгенерировал 4294 строки кода из одного моего заголовочного файла. Имена свойств, смещения в памяти, флаги сериализации, exec thunks для каждой функции - всё, чтобы движок в runtime знал о классе то, что C++ забывает после компиляции. Это третья и последняя статья в серии про внутренности Unreal Engine: K2Node → Blueprint VM → рефлексия. Разбираем, что внутри этих четырёх тысяч строк, зачем каждая из них, и как ими пользуются Details panel, GC, репликация и сама Blueprint VM.

Читать далее

Множество Мандельброта. Суперсэмплинг 8x8 (64 прохода) — впервые в мире

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

Вот так. Впервые в мире. Суперсэмплинг (SSAA) — ресурсоемкий метод сглаживания, увеличивающий число выборок на пиксель для повышения качества изображения. При значении 8x (N=8) сцена рендерится в разрешении, в 8 раз превышающем целевое, по обеим осям, создавая 64 (или 8 х 8) выборки на пиксель. Изображение просчитывается в более высоком разрешении, а затем принудительно уменьшается до разрешения дисплея, устраняя лесенки и улучшая чёткость. Это очень высокая нагрузка! Это не 1920 на 1080 пикселя а в 8x8 больше - 15360 на 8640 пикселя! Такое никто, кроме меня, делает в мире. Для множество Мандельброта.

Это маленькая утилита из командной строке. Которая либо читает Mandelbrot.txt три строки из файла - клавиша 7. И создает Mandelbrot.bmp
Либо клавиша 1-6 - это одно из шести разных мест множество Мандельброта и создает Mandelbrot.bmp
Скачайте и посмотрите. Это экзешник, в ГитХаб
Скачать последнюю версию (Windows и Linux)

Читать далее

Введение в высокопроизводительные вычисления на С++ для CPU

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

"Поскольку вы программист на C++, вероятность того, что вы слегка одержимы производительностью, выше среднего. А если нет, то вы, вероятно, по крайней мере с пониманием относитесь к такой точке зрения. (Если производительность вас совсем не интересует, аудитория Python разработчиков дальше по коридору)"
— Из пункта 42 книги С. Майерса “Effective Modern C++”, 2015.

Эта заметка описывает мой личный взгляд на то, как писать эффективный и надежный код для CPU. Статья ориентируется на С++, но значительная часть обсуждения CPU, кэшей, паттернов доступа к памяти и профилирования применима к Rust, Go и другим компилируемым языкам. Статья задумана как краткое введение и больше всего подходит студентам, имеющим опыт программирования на занятиях, но не в реальных проектах. Для профессионалов статья может быть полезной в качестве референса, чтобы не пугать новичков чем-то в духе Что каждый программист должен знать о памяти.

В статье опишу "набор новичка": godbolt.org, профилирование, бенчмарки, особенности CPU и его взаимодействия с памятью, когда есть смысл от асимптотических оптимизаций и почему важно при этом пользоваться санитайзерами, отслеживать coverage и вообще более трепетно относится к надёжности.

Читать далее

Что больнее OT или CRDT в совместном редактировании? И почему до сих пор нет идеала?

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

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

Меня зовут Антон Леонтьев, я старший разработчик в команде ядра редакторов МойОфис. Мы создаём офисные приложения, которыми ежедневно пользуются более 12 500 организаций, и совместное редактирование — одна из ключевых возможностей наших продуктов.

И знаете, что самое обидное в этой теме? За 35 лет исследований были опубликованы сотни научных работ. Google Docs работает с 2006 года. У Figma, Notion и Linear свои реализации. Казалось бы, задача давно решена, но стоит копнуть глубже, и становится понятно: универсального решения нет.

В Google Drive и Dropbox до сих пор всплывают баги с одновременным перемещением папок. В Notion при параллельном редактировании одного и того же абзаца можно потерять часть изменений. Даже Yjs — самая популярная CRDT-библиотека — не хранит полную историю документа в привычном для нас виде.

В этой статье разберём теорию, узнаем, какие проблемы решают Operational Transformation (OT) и Conflict-free Replicated Data Types (CRDT), на каких математических идеях они основаны, чем отличаются архитектурно и какие компромиссы неизбежно возникают в каждом подходе.

Интересно узнать, почему даже Google не смог сделать идеальное решение? Детали под катом.

Читать далее

Безумие препроцессора: внедряем do-нотацию для монад из Haskell в C++

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

Добро пожаловать в чистилище препроцессора — место, где здравый смысл уступает место макросам. Сегодня мы заставим C++ притвориться Haskell-ем и внедрим do-нотацию, за которую любой адепт «чистого языка» предаст нас анафеме.

Программисты на C++ делятся на два типа: те, кто боится препроцессора, и те, кто познал сие древнее чудо с сишных времён.

Сегодня мы перейдем черту. Функциональное программирование манит своими абстракциями, но когда дело доходит до цепочек вычислений в монадах, C++ встречает нас бесконечными лямбдами и вложенностью, от которой рябит в глазах. В Haskell эта проблема решена элегантным do-синтаксисом. А что, если я скажу, что мы можем получить то же самое в C++, используя лишь тёмную магию макросов, простые шаблоны и полное пренебрежение здравым смыслом?

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

Запустить конвейер безумия

Jami в России: почему гениальный P2P-мессенджер не работает и как это исправить

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

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

В процессе стало очевидно две вещи:

· У Jami огромный технический потенциал.
· В реальных сетевых условиях (особенно в мобильных сетях России) он работает значительно хуже, чем мог бы.

Эта статья — попытка разобрать проблему с инженерной точки зрения и предложить возможные направления развития.

Если вы разработчик, знакомый с C++, сетевыми протоколами, ICE или распределёнными системами — возможно, этот разбор будет вам интересен.

Читать далее