CG & C++ blog
56 subscribers
13 photos
2 files
128 links
Краткий обзор публикаций, презентаций, докладов по графике и C++
Download Telegram
(video) CppCon 2017: Louis Brandy “Curiously Recurring C++ Bugs
Разбор багов в fb и немного юмора.
#cpp #fun
(video) Артём Быковец: IT Stand-Up | SE2015
IT стэндап весьма редкое явление.
#fun #rus
(video) Tune CPU job scheduling for Apple silicon games
Рассказывают как устроен мобильный ЦП, как ОС распределяет работу по потокам.
В начале полезно для новичнов и чтобы освежить знания.
21:48 - рассказывают как организовать менеджер тасков с учетом E и P ядер и типа задач.
#cpu_opt #apple_cpu #threading
В CMake есть проблема с зависимостями между проектом с динамически загружаемой библиотекой (DLL) и проектом, который эту DLL использует.
При изменении только CPP файла в DLL проекте, перестраивается только один проект, а зависящие от него скрипты, например копирование DLL, не срабатывают и остальные проекты продолжат использовать старую DLL.

Решение есть, хоть и не самое удобное:
* код создает пустой CPP файл при компиляции "DllProject".

set( DllProject.trigger "DllProject.trigger.cpp" CACHE INTERNAL "" FORCE )
add_custom_command( TARGET "DllProject" POST_BUILD COMMAND ${CMAKE_COMMAND} -E touch "${DllProject.trigger}" )

* добавляем СPP файл в проект, который использует DLL

add_dependencies( "ExeProject" "DllProject" )
target_sources( "ExeProject" PRIVATE "${DllProject.trigger}" )
set_property( SOURCE "${DllProject.trigger}" PROPERTY GENERATED 1 )

Теперь при компиляции "DllProject" будет принудительно компилироваться "ExeProject" и запустятся все связаные с ним скрипты сборки.
Так как меняется только один CPP файл, то скорость сборки замедляется незначительно.
#cmake #snippets
Authoring Efficient Shaders for Optimal Mobile Performance
1..8 - описание дебагера и профайлера под Mali GPU и офлайн профайлера шейдеров.
9..16 - как разработчики игр используют тулзы от ARM для оптимизации.
17..19 - детали Valhall архитектуры
20.. - пример оптимизации шейдера
#mali #gpu_opt
Doom 2016. Комбинация light probes и screen space reflections приводит к таким двойным отражениям, когда light probe находится в стороне от источника освещения.
#cg #SSR
Cyberpunk 2077. Разница между screen space reflections и трассировкой лучей. Для оптимизации SSR применяется везде, где возможно и только за пределами экрана включается RT. Результат сильно различается.
#raytracing #SSR #cg
Screen space reflections неправильно обрабатывают двойное отражение, так как отражение зависит от того, под каким углом приходит луч. То же самое относится и к кэшированию освещения при трассировке.
#cg #raytracing #SSR #blog
Какая должна быть многопоточность в ОС
Сейчас ОС управляет потоками, у кого выше приоритет, тот получает больше времени ядра ЦП. ОС может остановить поток в любой момент и запустить другой поток на этом ядре, может перекинуть поток на другое ядро.
Переключение между потоками очень дорогое (более 1мс), что не позволяет выделить по одному потоку на задачу, а несколько параллельно запущенных приложений могут начать конкуренцию за ЦП с большими потерями на переключение потоков.

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

Проблема решается заменой потоков на систему тасков в ОС, но это потребует переделать или отказаться от контекста потока.

Дальше можно оптимизировать доступ к памяти - делать загрузку из ОЗУ в кэш до запуска таска, чтобы сам таск выполнялся максимально быстро, например для модели типа ECS/DOD, где доступ к данным полностью предсказуем.
#threading #blog
Подборка интервью с Jim Keller

Jim Keller: Moore's Law, Microprocessors, and First Principles
3:43 - Граф зависимостей в ЦП.
12:08 - Предсказание ветвлений.
22:41 - каждые 5 лет архитектура ЦП переделывается с нуля.

Jim Keller: The Future of Computing, AI, Life, and Consciousness
7:33 - Javascript
11:40 - RISC vs CISC
17:09 - Intel vs ARM
37:18 - Модульный дизайн ЦП позволил упростить тестирование, прям как в софте.
49:50 - Специализированное железо для машинного обучения.

Ian Interviews: Jim Keller, Silicon Wizard
19:44 - Arm vs x86 vs RISC-V
1:19:48 - Intel vs AMD, Intel vs Apple
#cpu #hw
Кадр из NSight GPUTrace.
#gpu_sync #nvidia
Особенности шедулера в NVidia

1. Работает 2 очереди, зеленое - пиксельный шейдер, оранжевое - асинхроный компьют шейдер. На NVidia когда активна графическая очередь, на асинхронную компьют очередь выделяется не более 30% варпов.

2. По какой-то причине графическая очередь вытесняет компьют очередь.

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

4. Начинаются короткие рендер пассы, разделенные барьерами. При этом на компьют выделяется не более 30% варпов, даже когда часть варпов простаивает (светло-сервый).

5. При более долгом простое (полная остановка графической очереди), компьют очередь занимает более 30%.

В итоге обновление юниформ буфера между рендер пассами может вызвать простой ГП на 0.3мс и даже асинхронные очереди не заполняют простаивающие варпы.
Более правильный способ - обновлять юниформы один раз в начале кадра.
#gpu_sync #nvidia
Advanced API Performance: Async Compute and Overlap
Статья от NVidia, рассказывают как правильно использовать async compute, как профилировать.
#gpu_sync #nvidia
Advanced Shading Techniques with Pixel Local Storage
Примеры использования внутренней памяти тайла (tile/pixel local storage).
Поддерживается на OpenGLES с Mali GPU, а так же на Metal с Apple GPU.
На Adreno используется другое расширение, только для сложного блендинга.
Поддержка TLS/PLS на Vulkan добавленна только в новых версиях API и только в новых девайсах из-за невозможности обновления графических драйверов.
#cg #gl #vk #OIT #mali
(video) CPU design effects - Jakub Beránek
Детально рассказывается про предсказание ветвлений, из интересного - в GCC подсказка __builtin_expect игнорируется ЦП.
41.53 - пример, где denorm float работает в 2 раза медленее.
51:56 - false sharing, как происходит синхронизация кэшей
#cpp #cpu_opt #intel_cpu
Ошибка в системе сборки, которая сразу обнаружилась через pragma detect_mismatch

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

#ifdef MACRO
# pragma detect_mismatch( "MACRO", "1" )
#else
# pragma detect_mismatch( "MACRO", "0" )
endif
При этом во всем основном проекте макрос установлен в 1 и я долго не мог понять откуда приходит 0.
Без pragma detect_mismatch найти ошибку было бы еще сложнее.
#cpp #blog
Создание World of Tanks Blitz на базе собственного движка DAVA
Как происходит переход из OOP/сценеграфа в ECS/DOD.
И продолжение: Blitz Engine & Battle Prime: ECS и сетевой код
#cpp #ecs #dod #rus
Зачем нужен безразмерный массив юниформ в шейдере
В шейдере можно не указывать размер массива ресурсов (юниформ), но в Vulkan обязательно указывать количество дескрипторово в VkPipelineLayout.
Получается, что безразмерный массив в шейдере никак не избавляет от создания нескольких PSO под разные размеры массива.
В чем же преимущество:
1. Не нужно компилировать несколько шейдеров и хранить несколько бинарников.
2. На мобильных девайсах количество ресурсов сильно ограниченно, поэтому нельзя захардкодить массив на 1000 элементов.

Также, по документации Vulkan, нельзя оставлять дескрипторы без ресурсов, это может привести к крэшу, так как в некоторых случаях происходит неявный доступ к ресурсам, который пользователь никак не контролирует.
Фича nullDescriptor позволяет обойти эту проблему и использовать один большой массив, но может повлиять на производительность.

Новое расширение buffer_device_address дает большую гибкость - можно сделать storage buffer с динамическим массивом uint64_t/uvec2, что не требует разных VkPipelineLayout, но пока это расширение поддерживается только на десктопах и топовых мобилках.
#vk #blog
Как мы отказались от JPEG, JSON, TCP и ускорили ВКонтакте в два раза
То что новые форматы лучше и так понятно, а вот отказ от TCP в пользу UDP уже интереснее.
Рассказывают как работает сеть, ограничение скорости провайдером и тд.
#web #backend #rus
https://www.gdcvault.com/free/gdc-22/
В открытом доступе появились доклады с GDC 2022
#news