Вывод с учётом переменной частоты (HDMI VRR / G-Sync / FreeSync). Плеер согласует показ кадров с переменной частотой монитора и ТВ, поэтому стандартные 24 fps фильмы воспроизводятся идеально плавно и без тиринга.
Нейросетевая генерация промежуточных кадров:
NVIDIA Video Frame Generation (VFG): аппаратная нейросетевая интерполяция для видеокарт GeForce RTX 40 / 50. (rtx 20 / 30 экспериментально)
RIFE и Micro Riffe: универсальная нейросетевая интерполяция и облегчённый шейдерный вариант для менее производительных видеокарт.
Упреждающее определение склеек сцен: собственный алгоритм на векторах движения (NVIDIA Optical Flow / Compute Shaders) отслеживает склейки, исключая появление артефактов и желе на стыках кадров.
HDR и Dolby Vision: Воспроизведение контента Dolby Vision через HDR10-вывод с учётом динамических метаданных (RPU). Динамический тонмаппинг (DTM) адаптирует яркость под возможности конкретного HDR-монитора.
Двойной аудиовыход и пространственный звук: Одновременный вывод двух разных аудиодорожек на разные устройства (например, кино в колонках и наушниках). Бинауральный пространственный звук для стереонаушников на базе движка Valve Steam Audio или нативный Windows Spatial Audio.
Умная работа с субтитрами и дорожками: Автоматический поиск и подхват внешних аудиодорожек и субтитров в подпапках с настраиваемой глубиной поиска.
Автообрезка чёрных полос (Crop), полезно под экраны Ultrawide,
История и система меток (Marks): Наглядная история(отключаемая) просмотров с сохранением позиций и генерацией миниатюр кадров. Возможность расстановки собственных меток и комментариев прямо на таймлайне (ПКМ по полосе воспроизведения).
Быстрый запуск и экономия памяти: Модули и библиотеки подгружаются лениво только при обращении к соответствующему функционалу.
Плеер бесплатный и портативный: распаковываете zip и запускаете delta-player.exe. Устанавливать ничего не нужно. F2 открывает настройки, F1 - раскладка кнопок, если удалить файл portable.ini , то плеер будет хранить свои файлы в папке пользователя, так же можно сделать ассоциацию с видеофайлами, через настройки.
Русский язык можно в настройках выставить.
оверлеи RTSS или MSI Afterburner, могут вызвать сбои.
требования: Windows 10/11 x64, Direct3D 12 (FL12_1 / Shader Model 6.6)
Индустрия программного обеспечения сегодня стоит на пороге масштабного очищения. Годы засилья агрессивного маркетинга онлайн-школ превратили некогда элитарную инженерную дисциплину в проходной двор для дилетантов. Однако появление генеративных нейросетей неожиданно запустило обратный процесс. Автоматизация не просто заменяет людей, она возвращает разработку к ее истокам. Чтобы понять, почему этот тектонический сдвиг выгоден всем, кроме самих вчерашних «курсантов», необходимо детально препарировать три ключевые эпохи развития ИТ-сферы.
Первая эпоха: золотой век нативной инженерии.
В самом начале программирование было уделом людей с глубоким профильным высшим образованием. За плечами этих специалистов стояла фундаментальная теоретическая база: высшая и дискретная математика, математический анализ, глубокое понимание системных архитектур и классических алгоритмов.
Программы создавались на языках системного уровня — благословенных Си и С++. Разработчик был обязан вручную управлять выделением памяти в куче, следить за утечками, оптимизировать алгоритмы под конкретные процессорные архитектуры и четко понимать, во что его исходный код превратится после компиляции в машинные инструкции. Это была эпоха прагматичного благоденствия, подарившая миру операционные системы, работающие десятилетиями, и софт, который мгновенно откликался на действия пользователя, не требуя под капотом виртуальных машин и тяжелых интерпретаторов.
Вторая эпоха: засилье вкатунов и деградация кода.
Коллапс начался с появлением агрессивных онлайн-школ. Обещая легкие деньги и быстрый «войти в айти», они заманили в профессию колоссальную массу дилетантов. Индустрию наводнили так называемые вкатуны, не имеющие даже базового технического бэкграунда. Эти люди начали открыто отрицать необходимость знания алгоритмов и структур данных, посчитав, что годовых курсов по Python достаточно для звания инженера.
Результатом стала тотальная деградация пользовательского софта. Python -- это прекрасный инструмент для быстрого прототипирования, написания легковесных скриптов автоматизации или узкоспециализированных программ, которые используют ученые для математических вычислений. Но вкатуны, не знающие ничего другого, начали пихать его повсюду. Рынок и репозитории GitHub оказались завалены неповоротливыми, перегруженными «пед-проектами», созданными исключительно ради галочки в резюме.
Ситуацию усугубил союз питонистов и так называемых DevOps-ов, чья квалификация часто ограничивалась банальным копированием готовых скриптов и манифестов разметки YAML. Сформировав агрессивное большинство, эта каста начала продвигать абсурдный тезис: якобы разработка тяжелых пользовательских приложений на Python и монструозных веб-костылях вроде Electron — это не просто нормально, а имеет преимущества перед нативным кодом. Компьютеры пользователей превратились в полигон для тестирования неоптимизированного софта, сжирающего гигабайты памяти ради банального текстового интерфейса.
Третья эпоха: демократизация и триумф машин
Приход генеративных нейросетей навсегда закрыл этот затянувшийся карнавал дилетантства. ИИ научился писать код. И если до уровня глубокого архитектора систем машина еще не доросла, то низкоквалифицированных питонистов и веб-разработчиков после онлайн-курсов она превзошла мгновенно и бесповоротно.
Программирование окончательно демократизировалось. Зачастую бизнесу для решения прикладных задач вообще не нужно привлекать классический штат кодеров. Любой сотрудник, понимающий логику процессов, может составить краткий запрос из двух-трех предложений. Нейросеть на его основе мгновенно развернет подробнейшее техническое задание на 40–50 листов документа Word и сама реализует рабочую программу по всем пунктам.
И самое главное: автоматике чужды мода и хайп. В отличие от ленивых вкатунов, нейросеть без проблем работает с низкоуровневым кодом. Благодаря ИИ индустрия получила возможность снова массово и быстро компилировать софт на благословенных Си и С++, возвращая приложениям былую скорость, оптимизацию и нативную легкость без виртуальных машин и тяжелых интерпретаторов.
Кто боится прогресса, а кто празднует победу.
Главными и самыми яростными хейтерами нейросетей закономерно оказались те самые низкоквалифицированные питонисты. Они панически боятся автоматизации, потому что подсознательно понимают: их увольняют и заменяют роботами в первую очередь. У них нет фундаментального багажа знаний, чтобы предложить рынку что-то, кроме шаблонного копирования чужих библиотек.
Настоящий программист с профильным образованием и багажом знаний за спиной не испытывает страха перед нейросетью. Напротив, он использует ИИ как эффективный инструмент, освобождающий его от рутины и ускоряющий разработку в разы.
Более того, программисты по своей натуре в большинстве своем являются интровертами и мизантропами. Огромная часть профессионального сообщества встретила новости об автоматизации с искренней, глубокой радостью. Грамотные специалисты наконец-то избавлены от необходимости тратить свои душевные силы на то, чтобы нянчиться в командах с инфантильными дилетантами из онлайн-школ, напрочь лишенными способностей к профессии. Гораздо приятнее давать четкие, логичные указания машине и моментально получать предсказуемый, чистый результат.
Но главным бенефициаром этой технологической революции станет конечный пользователь. За годы сытого тепличного пузыря инфантильные программисты напрочь забыли, что всё ИТ-предприятие существует ради решения практических задач человека, сидящего за монитором, а не ради удовлетворения тщеславия и амбиций капризных «вайтишников». Нейросетевой конвейер безжалостно срезает эти лишние издержки, возвращая софту его истинную утилитарную функцию.
Предысторию разработки собственного рантайма, IDE, поддержка 61131-3 смотрите в моем блоге - ссылка в конце статьи.
В целом была идея, разработать отечественный рантайм для ПЛК и IDE к нему, которые были бы шустры, легки и производительны. Пока, как мне кажется, это удается. Скомпилированный бинарник IDE сейчас занимает около 1 мб. Запущенный рантайм, в текущей реализации, занимает около 5 мб ОЗУ и несколько процентов цпу ( до 5%) на Распберри 4, на нескольких одновременно работающих конфигурациях. В общем, понемногу движемся в правильном направлении, товарищи. Сегодня, хотел бы показать дальнейшую эволюцию этой идеи.
Немного про стек разработки. Напомню, что IDE и рантайм для ПЛК у меня разработаны под Линукс. Пишу на C++, собираю под Cmake как под x86-64, так и под ARM. В качестве внутренней коммуникации реализовал свой бинарный протокол, на базе ZeroMQ и FlatBuffers. Транслятор с промышленного языка — ANTLR. Из промышленных протоколов коммуникации, пока поддержка - Modbus. Планирую добавить в дальнейшем OPCUA. IDE — написан на чистом C++ и Qt Рантайм — чистый C++ IDE с рантаймом общаются по собственному бинарному асинхронному протоколу, о котором писал выше.
IDE поддерживает два типа логики IL и ST. Зачем IL спросите вы? Исторически, случилось так, что рантайм начался с этого языка. И это не совсем IL — это полный аналог языка устройства Tesys T. Сами разработчики писали о нем как об structural text языке. Короче, я собирался реализовать рантайм, и чтобы он полностью поддерживал программы, которые были написаны для Tesys. Также мне понравилась как он был реализован. Вот так с тех пор он и остался, и благополучно работает.
Дерево элементов конфигураций ПЛК.
Фокус на элементе логики на IL
Фокус на элементе логики ST
Один элемент конфигурации — это 1 логика своего типа (IL или ST). Он же, отдельный выделенный поток для исполнения данной логики. Каждый поток, работает независимо и в параллель. Сколько элементов — столько и параллельно работающих потоков, исполнителей логики.
Компиляция. Для компиляции ST 61131-3 я написал свой транслятор на базе ANTLR. Перед загрузкой, логика компилируется в IDE и проверяется на ошибки. Успешно или нет логика скомпилирована, информация выводится в панель снизу.
Ошибочная компиляция программы на ST
Компиляция успешна!
Сохранение и открытие. Теперь конфигурации можно открыть и сохранить из IDE. И да, это банальный элемент, но без этого никуда. Что кстати требует довольно приличного времени на проектирование, разработку итд.
Настройки подключения и проверка связи.
Подключаем к ПЛК очень просто. Нужно на вкладке настроек подключения вбить настройки IP адреса и кнопку «Подключиться».
Настройки подключения
Если подключение успешно, в статус панели значок подключения сменит цвет на зеленый. Если связи нет, или был обрыв — иконка сменит цвет на красный.
Есть связь с ПЛК! Кнопка подключения сверху - как кнопка питания.
Связи нет.
Завел кнопку для запроса у работающего ПЛК перечень конфигураций в работе.
Перечень конфигураций в работе на ПЛК.
На ПЛК летит команда, с запросом. Список конфигураций высвечивается в нижней панели.
Три конфигурации - логики активны, и работают в параллель на ПЛК
Набор кнопок, с разным функционалом.
Кнопка отправить все конфигурации на ПЛК
Спокойно, загружаем и выгружаем через IDE с ПЛК конфигурации.
Автозапуск. Загрузив через IDE в рантайм 1 раз конфигурации, которые он благополучно сохранит и при его перезагрузке стартует снова с ними же.
В одной из прошлых статей, писал про разработку программного осциллографа, чтобы писать аварийные события в формате COMTRADE. Это больше для устройств РЗА, конечно, но скажем в устройстве Tesys T осциллографа сильно не хватало. Короче он также может запускаться в составе рантайма, хотя его можно и отключать. В той прошлой статье, я писал про него подробно. У него крутая возможность — с его помощью можно генерировать самые разные осциллограммы, причем можно создавать различные аварийные режимы.
Отладка.
Код на ST 61131-3 у меня в IDE можно отлаживать на «живом» рантайме ПЛК. Завел кнопку Отладка.
Кнопка с жуком - это отладка.
Когда у нас фокус на какой либо конфигурации и мы на связи с ПЛК, после нажатия на Отладку, на ПЛК летит команда — перезапустить поток в специальном отладочном режиме. Это в принципе такой же рабочий режим, все сигналы всё то же самое, что у нормального, но у него имеют некоторые существенные отличия от нормального режима. В общем, поток с логикой перезапускается в отладочный режим и мы можем ставить точки останова.
Отладка переменных - пока всё по нулям
Ставим точку останова, там где программа заходит в участки кода на ST. Может и не зайти, если там есть условия итд. Наблюдаем в окне имена и значения переменных в зоне видимости участка кода программы.
Тут логика активирована сигналом - переменные со значениями.
15 лет назад работал я в одном стартапе, который занимался ad-media trading. Так вот, в качестве базы для наших серверов использовался исходный код тогдашнего nginx.
Что вообще такое ad-media trading?
Представьте любой крупный новостной сайт, на который вы заходите. Обычно там сверху и по бокам находятся рекламные баннеры. Если сравнивать один день с другим, то баннеры меняются. Иногда в течение дня. Иногда несколько раз. Как это работает?
Существуют электронные биржи рекламы. Крупнейшими являются Google Ads, Yahoo7 и AppNexus/Xandr, принадлежащая Microsoft.
Размер электронной рекламной биржи определяется количеством сайтов с большим потоком посетителей в сутки, с которыми у этой биржи есть договор на размещение её рекламы. Если на главной странице такого сайта было 3 баннера, то в HTML странице на их месте вставлялись ссылки на сервер электронной биржи с информацией о геометрии баннера.
Далее media trading агентство, типа того стартапа, в котором работал я, заключает контракт с такой биржей, на показ своей рекламы. Оно, в свою очередь, заключает контракты уже с рекламодателями. Например крупными банками или производителями товаров. Агентство получает от рекламодателей собственно баннеры для показа, деньги на рекламную кампанию и описание целевой аудитории, на которую эта рекламная кампания рассчитана.
Далее media trading агентство загружает свои баннеры в систему электронной рекламной биржи и та подтверждает, что баннеры не содержат 18+ контента и подходят под описание рекламируемого продукта или услуги.
Когда Вы заходите на вебсайт, на котором есть подобные рекламные места для баннеров, то, при начале загрузки страницы в Вашем браузере, сработают те самые ссылки на месте баннеров, которые отправят запросы на сервер биржи. Кроме зашитой геометрии баннера сервер извлечёт из запроса:
Ваш IP-адрес
Язык браузера по умолчанию
Если это Google Ads, то также Ваш возраст и пол
Всю собранную информацию + название исходного веб-сайта биржа рассылает в виде запроса всем своим ad-media trading агентствам - делайте ставки! С этого момента включился таймер!
Со стороны ad-media trading агентства находится сервер. В нашем случае он был сделан на основе nginx. Инженеры, в числе которых был и я, писали на C++ код к nginx, который выполнял распаковку запроса, вычисление местоположения по IP-адресу, заполнение запроса к внутренней базе данных, прогонку входной информации о зашедшем на сайт пользователе через цепочку фильтров рекламодателя, проверку бюджета рекламной кампании и вычисление размера bid - ставки, которую мы готовы сделать и заплатить в случае выигрыша торгов за рекламный баннер. В итоге мы подготавливаем ответ бирже - сумма ставки и идентификатор баннера для показа. Ответ должен быть отправлен в течение 10 миллисекунд с момента отправки запроса биржей!!! Отправлять ответ "pass"/пропускаю нет никакого смысла - достаточно не отвечать 10 мс! Дальше биржа сравнивает полученные ставки, выбирает победителя, извлекает его баннер из своей базы и отправляет его на веб-страницу, на которую Вы зашли.
По своему опыту скажу, что средний размер ставки за показ одного баннера колеблется в районе 1-2 цента. Процент выигранных нами бидов на Yahoo7 и AppNexus/Xandr был в районе 25%, а на Google Ads - 10%. На Google Ads конкуренция гораздо выше из-за того, что у них было гораздо больше биддеров вроде нас. Средний бюджет от рекламодателя на рекламную кампанию - 2 миллиона долларов. Некоторые популярные веб-страницы, на которые Вы заходите, собираются из примерно 15 источников перед тем как быть Вам показанными...
Наши сервера располагались в облачных датацентрах в Европе, Азии и США, чтобы быть как можно ближе к серверам электронных рекламных бирж и иметь минимальную задержку на коммуникацию.
nginx позволял на своей базе сделать быстрый, масштабируемый сервер с расширяемым функционалом.
P.S.: После работы в этом стартапе мне довелось поработать ещё и c другим легковесным веб-сервером - Lighttpd. Это было уже в проекте разработки firmware для семейства Интернет-маршрутизаторов. Как-нибудь расскажу, если кому будет интересно.
Всем привет! С момента прошлого поста прошло прилично времени. Я не забросил проект, руки не опустил и всё ещё продолжаю пилить-пиить-пилить :).
Сразу дисклеймер: 5000 онлайна — это синтетические боты. Не живые игроки. Но это честные боты, которые подключаются по реальным WebSocket-сокетам, перемещаются по геодате 25 зон острова, собирают лут, применяют скиллы, пишут в чат и нагружают Spatial Grid сервера точно так же, как живые люди.
Городская площадь Деревни поющей стали: толпа ботов у фонтана и NPC, живой чат и стабильные 50 FPS при 5001 онлайне
1. С чего всё началось:
Cамый главный вопрос - сколько людей сервер потянет до того, как сгорит процессор). На 100–300 игроках всё летает. На 1000 - начинаются первые проблемы. Но хотелось проверить планку в 3000-5000 одновременных подключений (CCU) на скромном сервере (2 vCPU, 2 ГБ RAM на базе Яндекс Облака).
Я попросил ИИ написать генератор нагрузки на Node.js и запустил его со своего домашнего компьютера прямо в боевой сервер.
План был простой: заспавнить 3000 сокетов батчами по 20 штук и посмотреть на тик ядра.
Где-то на отметке в 2200–2400 ботов дома внезапно наглухо лёг интернет. Браузер перестал открывать страницы, а в консоли посыпались тайм-ауты сокетов.
Сначала я подумал, что лёг VPS. Захожу с мобильного интернета - сервер живой, тик 0.5 мс, всё спокойно. А домашний роутер просто завис.
Причина оказалась банальной: Обычные домашние роутеры и Wi-Fi-коробочки от провайдеров не рассчитаны на то, что с одной машины в квартире откроется 3000 одновременных TCP/WebSocket соединений. На роутере кончилась таблица NAT-трансляций (SNAT порты), память забилась, и он просто ушел в глубокий нокдаун.
Стало ясно: стресс-тестировать тысячи сокетов с домашнего ПК больше нельзя.
2. Переезд на распределенный кластер GitHub Actions
Чтобы не вешать домашнюю сеть и не арендовать отдельную пачку серверов только ради тестов, пришла идея: использовать раннеры GitHub Actions Matrix.
Восточный полигон: боты распределены по полям, на счетчике 5001 онлайн, рендер 7.6 мс, сеть 0.8 мс
Но тут возникла вторая засада. Если запустить один раннер Ubuntu в GitHub Actions на 5000 сокетов, он упирается в лимит Azure NAT Gateway - для одной виртуальной машины выделяется всего около 2048 эфемерных портов на внешний IP. Всё, что выше, начинает отваливаться с ETIMEDOUT и ECONNRESET.
Решение - матричный запуск:
Раннер #1 (Runner 1): 1700 ботов (смещение ID от 0 до 1699, часть ботов в городе, часть в полях);
Раннер #2 (Runner 2): 1700 ботов (смещение ID от 1700 до 3399);
Раннер #3 (Runner 3): 1600 ботов (смещение ID от 3400 до 4999);
Четвертый агрегатор: собирает метрики, перцентили RTT и формирует итоговый отчет.
Каждый раннер запускается на изолированной виртуальной машине со своим независимым публичным IP-адресом. Проблема с исчерпанием портов исчезла.
3. «Запустил... и нагрузил ровно 49 ботов»
Казалось бы, всё готово. Жму кнопку запуска в GitHub Actions, захожу в игру и вижу: Онлайн: 49.
Запрашивали 5000, а зашло 49. В консолях раннеров - сотни ошибок: Connect error: Unexpected server response: 429
Полез в логи разбираться:
Раннер 1 подключил ровно 16 ботов.
Раннер 2 подключил ровно 16 ботов.
Раннер 3 подключил ровно 16 ботов.
$16 \times 3 = 48$ ботов + я в клиенте = ровно 49.
Оказалось, сработала защита от DoS-атак! В сетевом транспорте стоял лимит: не более 16 активных сокетов с одного внешнего IP-адреса. Для реальных игроков это имело смысл (хотя даже для CGNAT мобильных операторов 16 маловато), но для нагрузочных раннеров это стало железобетонной стеной. Сервер честно отвечал: HTTP 429 Too Many Requests.
Мы с ИИ добавили авторизованный заголовок x-stress-key, подняли базовый порог для игроков до 64, передеплоили ядро на VPS и перезапустили тест.
4. Итог: 5001 онлайн в реальном времени
После фикса все три раннера залетели на сервер на полной скорости.
Холмы Астарда: боты фармят автоматонов и бешеных кофемашин
Вот реальные цифры из консоли и игрового оверлея:
Запрошено ботов: 5000
Успешно подключено: 5000 из 5000 (100%)
Ошибок рукопожатия: 0
Онлайн в игре: 5001 CCU (5000 ботов + 1 GM персонаж)
FPS клиента в браузере: 50–59 FPS (WebGL Three.js)
Время тика игрового сервера: 1.0 мс (EMA: 0.3 мс при норме тика в 100 мс / 10 Hz)
Event Loop Lag Node.js: 11.88 мс (полное отсутствие блокировок главного потока)
Обработано входящих пакетов: свыше 4.7 млн пакетов за тестовую сессию
Трафик: благодаря дельта-сжатию AOI сервер отфильтровал 61.5% лишних обновлений координат
Что позволило серверу не умереть под 5000 сокетами:
uWebSockets.js (C++ Zero-GC транспорт): забыли про стандартный ws из npm для 5000 сокетов на 2GB RAM. Нативный C++ транспорт держит соединения без давления на сборщик мусора V8.
C++ SIMD (AVX2) для расчёта дистанций и коллизий: модуль project_steam_native.node считает AOI и радиусы агро мобов векторными инструкциями процессора за микросекунды.
Worker Threads для сохранения в базу: вся работа с диском и состоянием игроков вынесена на отдельный поток vCPU, поэтому запись профилей никак не задерживает тик игры.
Проект жив, пилится дальше. Впереди ещё огромная гора работы.
Спасибо всем, кто следит и поддерживает! На бумаге все выглядит шикарно, как будет в реальной жизни? Время покажет))
Добавлена функция пересчета координат для дальних объектов
Переписан бэк кубокоординат
Комментарий
Джемени меня все-таки обманул (весь день сегодня (вернее уже вчера)) искал косяк в теории - нашел два (плюс один свой уже в реализации). Один в расчете этих самых кубокоординат; второй в подсчете дистанций между объектами по этим кубокоординатам (там же еще и я сам косякнул). Что вылилось в переписывание почти всей VBS/HS. Но за то теперь точно работает.
Доделана т.н. Far считалка для больших далеких объектов, который с локальной сцены перемещает объекты на 10км орбиту вокруг камеры с правильным скейлом. Ради этого вытащил весь этот комбайн поближе к GameWorld классу, т.к. оттуда удобнее получать доступ к камере. Получается, что теперь SceneUnit больше интерфейс к системе VBS/HS чем самостоятельная сущность, ну и для сохранения привычной древовидной структуры объектов, а сама магия плейсмента ушла почти целиком в GameWorld.
В общем, с CPU частью системы, думается мне, с горем пополам, можно сказать закончили. Ну может полернуть еще пару моментов. Теперь нужно править рендер, чтобы правильно эти объекты рисовал и приниматься наконец за объемный источник света. А вам на сравнение два сэмпла. Один с большим кубом, поставленным классическим образом (в 20км), а другой, с этим же кубом, но через метод пересчета для удаленных объектов (в 10км). В остальном (ну кроме ракурса) все полностью идентично.
А с нейронками надо завязывать. Пойду завтра (сегодня) советский учебник по тригонометрии заберу со второй квартиры. Он полезнее будет. Вот такие дела.