CG & C++ blog
57 subscribers
13 photos
2 files
129 links
Краткий обзор публикаций, презентаций, докладов по графике и C++
Download Telegram
(video) CppCon 2017 - atomics, from basic to advanced
Подробное объяснение как работают атомики.
Интересно что результаты бенчмарков в докладе и у меня сильно различаются, так что похоже надо тестировать все на разном железе.
#cpp #atomics
(video) CppCon 2016 - The speed of concurrency
Про оптимизацию lock-free контейнеров. Рассматриваются случаи, когда lock-free оказывается медленее блокирующих алгоритмов и как это исправить.

(video) CppCon 2015 - Live Lock-Free or Deadlock: part 1, part 2
И еще лекции от Fedor Pikus.
#cpp #lockfree #threading
(video) CppCon 2019: Miro Knejp “Non-conforming C++: the Secrets the Committee Is Hiding From You”
10:51 - инициализация массива по указаному индексу вида:
char* arr[10] = { [5] = "a" };

21:16 - для placement new для массива по стандарту невозможно рассчитать размер памяти.
31:18 - интересный трюк с goto, оказывается можно делать массив указателей на лейблы (jump tables).
#cpp
Список тэгов

Программирование
#cpp - C++
#cpu_opt - оптимизации для ЦП
#atomics - атомарные операции, работа с кэшем
#threading - многопоточка
#lockfree - Lock free, wait free алгоритмы
#backend - сервера
#ecs - entity component system
#dod - data oriented design, низкоуровневая оптимизация

Графические API, работа на низком уровне
#gpu_opt - оптимизации для ГПУ
#gapi - все графические API
#vulkan #vk - Vulkan API
#metal - Apple Metal
#opengl #gl - OpenGL
#dx - DirectX 11, 12

Рендеринг
#cg - все что связано с компьютерной графикой
#proc_gen - процедурная генерация
#games - обзор технологий из игр

Другое
#news - новости по теме
#blog - новости по моим разработкам
#hw - все что связано с компьютерным железом
#desktop #win #mac #linux - относится к ПК, ноутбуки
#mobile #android #ios - относится к мобильным платфомам
#vr - VR, виртуальная реальность
GDC2018: Shadow of War: performance & memory optimization
Рассказывают про организацию потоков, выделение памяти через large pages, стриминг мипуровней.
Одна из немногих презентация про применение sparse memory.
#cpu_opt #threading #gpu_opt #sparse_mem
GDC2015: Destiny's multithreaded rendering architecture
Почти все про организацию системы тасков в движке под загрузку, подготовку, проверку видимости и рендеринг.
Слайды 60-66 - предлагают использовать системы:
object system
,
rendering
,
visibility
.
Компонент
visibility
отвечает за тест видимости и вычисление детализации, таким образом для rendering компонента будут подгружаться только необходимые данные.
#cpu_opt #ecs #threading
Breaking down barriers
Статья из 6 частей, расказывается как работает GPU, как происходят синхронизации.
В 5й части рассказывают про работу драйвера windows на разных версиях ОС.
В 6й части есть примеры с async compute.
#gpu_sync #dx #vk
Command queues
Моя статья по асинхронным очередям на GPU.
Показаны async compute, ascync transfer очереди для дискретных GPU и только async compute для мобильных.
Демо позволяет покрутить ползунки и увидеть как меняется производительность.
Особенности на Mac M1:
* на Metal получается более +25% при использовании Double buffering, без него не параллелится.
* на MoltenVk async compute наоборот дает потерю до 10%.
Intel GPU на dx12 поддерживает async compute несмотря на то, что он не поддерживается в железе, и дает до +50%, а на Vulkan разницы нет, похоже что драйвер на dx12 хорошо эмулирует очереди.
На Android девайсах так и не получилось распараллелить, хотя для Mali GPU есть примеры, где получается до +10%.
#gpu_sync #vk #dx #metal
Recursive Tile-based architecture
Альтернативный вариант трассировки лучей, оптимизированный под мобильную архитектуру.
Здесь предлагается сделать ускоряющую структуру (primitive provider), которая возвращает видимые треугольники по конусу.
Весь рендеринг идет через запросы к ускоряющей структуре, сначала для рисования тайла, потом поверх рисуются отражения. Это хорошо работает для когерентных лучей.
#tbdr #raytracing #mobile #rus
Обнаружил такую особенность видеокарт AMD:


sh
a
derUniformBufferArrayNonUniformIndexingNative:   false,
shaderSampledImageArrayNonUniformIndexingNative: false,
shaderStorageBufferArrayNonUniformIndexingNative: false,
shaderStorageImageArrayNonUniformIndexingNative: false,
shaderInputAttachmentArrayNonUniformIndexingNative: false,


Из до
кументации Vulkan API:

shaderUniformBufferArrayNonUniformIndexingNative is a boolean value indicating whether uniform buffer descriptors natively support nonuniform indexing. If this is VK_FALSE, then a single dynamic instance of an instruction that nonuniformly indexes an array of uniform buffers may execute multiple times in order to access all the descriptors.


То есть в пределах одного варпа доступ к массиву ресурсов (буферы, текстуры и тд) может быть неоптимальным.
Эта фича часто используется в трассировке лучей и полностью поддерживается на NV RTX.
Мобильные GPU на Android и iOS в основном имеют нативную поддержку, получается только AMD отстает.
#amd_gpu #vk
(playlist) Arm Mali GPU Training Series
В видео собрано много полезного для разработки под Mali GPU.
От расчета тепловыделения и особенностей разных поколений ГП до рекомендаций по оптимизации контента.
#tbdr #mali
PerfTest
Много тестов на производительность разных GPU при чтении разных типов данных.
Например на NVidia последовательное чтение из константного буфера может привести к большим потерям производительности, тогда как на AMD наоборот, это лучше случайного доступа.
Из этого можно сделать вывод, что под каждую модель ГП нужны специфичные оптимизации.
#gpu_opt
Handles are the better pointers
Большая статья, где приводится альтернатива shared_ptr и weak_ptr.
В 2018 я также перешел на подобную модель.
Вместо указателя используется ID { uint index; uint generation; } индекс указывает на память, а поколение используется для проверки валидности этого ID.
Если добавить счетчик ссылок в данные объекта по индексу, то как раз получится замена shader_ptr:

Object
{
uint generation;
uint refCounter;
Data data; // все что угодно
}
array<Object, 1024> pool;

if ( id.index < pool.size() )
if ( pool[id.index].generation == id.generation )
pool[id.index].data ... // id валиден, можно использовать
Когда refCounter == 0 объект удаляется и увеличивается счетчик поколений:

pool[id.index].data.~Data();
pool[id.index].generation++;
Таким образом все копии ID становятся невалидными.
#cpp #cpu_opt
(video) CppCon 2014: Mike Acton "Data-Oriented Design and C++"
Старая презентация, но все еще актуальная.
Автор периодически стебется над Ogre.
#cpp #cpu_opt #dod
Книга 3D Graphics Rendering Cookbook
Материал по OpenGL и Vulkan для продвинутых начинающих.
Зато для сцены используется Data oriented design, что не часто встречается, стоит ознакомиться.
#gl #vk #ecs #dod
(video) CppCon 2018: Stoyan Nikolov “OOP Is Dead, Long Live Data-oriented Design”
Еще презентация по DOD.
На этот раз критика Chromium.
#cpp #cpu_opt #dod
Запись в блоге про Job System 2.0: -1-, -2-, -3-, -4-, -5-
Используется классический алгоритм work stealing, но написано интересно.
#cpu_opt #threading
(video) Taskflow: A Parallel and Heterogeneous Task Programming System Using Modern C++
Исходники Taskflow
Taskflow - это очередная реализация job system, использующая все тот же work stealing алгоритм.
В видео сравнивается taskflow с популярными аналогами: TBB, OpenMP.

Мое мнение - сам подход устарел, здесь и в аналогах используется главный поток, который отправляет таски в другие потоки и ждет их завершения. Более правильный подход - когда весь код состоит из тасков.
Также многие библиотеки считают все потоки одинаковыми, тогда как на мобилках давно уже 2 или 3 типа ядер, и на ПК уже появились 2 типа ядер. Для более тонкой оптимизации нужно различать потоки с гипертредингом.
#cpp #threading
(video) CppCon 2020 - A Fully Asynchronous OS Based on Modern C++
Будущее за асинхронными ОС.
В C++ добавили корутины и таски, но ОС, поверх которого это сделано, имеет ограниченную поддержку асинхронщины, что снижает выигрыш от многопоточности.
#cpp #threading
Особенность выравнивания типов в шейдерных языках.

float3

GLSL: размер 12, выравнивание 16.
Metal: размер 16, выравнивание 16.
Metal packed_float3: размер 12, выравнивание 4.

float2x2

GLSL std140: размер 32, выравнивание 16, совпадает с float4x2.
GLSL std430: размер 16, выравнивание 8.
Metal: размер 16, выравнивание 8.

float3x3

GLSL std140: размер 48, выравнивание 16, совпадает с float4x3.
GLSL std430: размер 48, выравнивание 16, совпадает с float4x3.
Metal: размер 48, выравнивание 16, совпадает с float4x3.
HLSL (Vk): размер 48, выравнивание 16, совпадает с float4x3.
HLSL (DX): размер 32, выравнивание 4.

Массивы

GLSL std140: минимальное выравнивание 16
GLSL std430: выравнивание совпадает с типом данных
Metal: выравнивание совпадает с типом данных

В некоторых случаях даже использование HLSL для всех GAPI не помогает и размер данных различается.
Чтобы справиться с плавающим смещением пришлось написать свой генератор структур, где на вход дается структура на одном из языков, а на выход генерируется C++, GLSL, MSL с одинаковыми смещениями.
#vk #metal #blog