пятница, 11 декабря 2020 г.

Генерация фигур


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

четверг, 23 июля 2020 г.

Volume render, часть 2. Оптимизация

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

понедельник, 6 июля 2020 г.

Профилирование шейдеров

Не так давно в Vulkan появились расширения GL_ARB_shader_clock  и   GL_EXT_shader_realtime_clock, с их помощью можно получить время работы шейдера и время работы потока в сабгруппе.

среда, 1 июля 2020 г.

Crash reporting

Что нужно для отправки и обработки крэшей:

1. С помощью google breakpad отлавливается падение приложения или необработанное исключение, далее генерируется минидамп (dmp формат) и вызывается колбэк, из которого можно отправить минидамп на сервер, самому либо средствами breakpad. У меня дополнительно отправляется лог и другие данные, поэтому отправку написал сам через CURL. Также упаковка данных с помощью brotli заметно уменьшает их размер.

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

3. Для крэшей используется dmp формат от Майкрософт (описание), формат позволяет добавлять кастомные данные, что и использует breakpad. Чтобы прочитать dmp файл нужен sym файл с информацией об исходном коде приложения, для этого на этапе сборки нужно вызвать "dump_syms.exe app.exe > app.exe.sym". Сам dump_syms.exe должен быть собран той же версией компилятора, что и приложение, поэтому dump_syms.exe из breakpad репозитория не подходит, так как собран более старой версией (vs2015). В breakpad есть парсер дампов  "minidump_stackwalk" в виде консольного приложения, но под windows он не собирается, так что пришлось написать свой парсер основываясь на их исходниках. Из минидампа извлекается информация о системе, callstack, место, адрес в памяти причина падения, например "EXCEPTION_ACCESS_VIOLATION_WRITE 0x0". Это используется для сортировки крэшей.

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

5. Дополнительно можно сохранять pdb файл, это позволит открывать минидамп в студии.

Исходники тут.

суббота, 29 февраля 2020 г.

Job system

Понемногу пишу движок, на котром обкатываю новые фичи. Среди них - планировщик задач (thread pool, job system, ...).
Какой требуется функционал:
  • Зависимости между тасками - то есть таск запускается только когда все его зависимости завершились.
  • Отмена тасков - до захвата таска потоком отмену обрабатывает сам планировщик, после - поток в котором выполняется таск.
  • Слабые и сильные зависимости - определяет что будет при отмене зависимого таска. При слабой зависимости следующий таск запустится даже при отмене зависимого таска. При сильной зависимости следующий таск также отменяется.
  • Кастомные зависимости - таким образом можно добавить зависимость между таском и GPU через VkFence, например.
  • Совместимость с другими системами - работа с сетью также сделана на тасках, многопоточный ECS и рендер тоже будет на них и тд.
  • Поддержка блокировок - для этого сделана отдельная зависимость InterlockDependency, куда передается callback, который может захватить мютекс или любой другой примитив синхронизации. Особенность в том, что захват идет через try_lock и если захватить не получилось, то таск остается в очереди до следующей проверки, если же получилось захватить, то таск отправляется на выполнение, а после выполнения вызывает функцию что бы разблокировать. Это позволяет не блокировать потоки при доступе к общим данным.
Исходники можно посмотреть тут.

четверг, 13 февраля 2020 г.

Виртуальная машина для тестирования lock-free

Я знаю, что в clang есть санитайзер для проверки lock-free (и подобных на атомиках) алгоритмов, но мне нужно было что-то более универсальное, поэтому написал свою виртуальную машину, которая подменяет атомики, мютексы и прочее на свою реализацию.

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

Что обнаруживает виртуальная машина:
  • Data race - параллельное чтение и запись в одну и ту же память.
  • Пропущенные flush / invalidate cache, когда в другом потоке произошел flush, а в текущем читают без вызова invalidate. Либо когда в память произошла запись, но не вызвался flush.
Ошибки в работе с кэшем невозможно обнаружить на x86 и x64 архитектурах из-за особенностей их работы с кэшем (CISC инструкции). Но эти проблемы проявляются на ARM (RISC инструкции), а постоянно тестировать на телефоне не так уж удобно, тем более проблемы могут очень долго не проявляться.

Исходники и примеры тут.