/A\
> Наверное незачем, но где-то он все равно влезет.
еще подумал - я могу делать все в одной очереди, покуда все вмещается в один кадр по времени. А когда производительность меньше, переключаться на механизм с этими двумя очередями
almatea
Можно еще чекербординг использовать - нарезать все на тайлы по 2х2, 4х4, 8х8 и обновлять один пиксель за кадр. Надо только проверить чтоб не простаивали потоки в варпе из-за этого.
подобные задачи (не важно на CPU или GPU) почему-то вызывают у людей позывы решать их во что бы то ни стало многопоточно. но вообще-то прогресс-бары работали ещё во времена, когда о многопоточности никто и не думал толком. просто медленную задачу надо разбить на множество более простых задач и в промежутках между ними натолкать обновление того, что должно обновляться часто. например, разбить рендертаргет на тайлы и рендерить UI между ними. тайлы могут быть произвольного размера, но не слишком маленькие, чтобы видюха надёжно нагружалась, и не слишком большие, чтобы один тайл не рендерился слишком долго.
almatea
> Я только не представляю как их потом блендить вместе, в ДХ вроде проще использовать 2 девайса, а в вулкане это независимые девайсы со своей памятью и надо все гонять через ЦП.
Девайс один, адаптеров два. На одном адаптере независимости не получить, потоки тут не спасают. Разнесение в две очереди (компьют и графическую) тоже.
Я с этим долго бодался но не годится архитектура GPU для обработки двух потоков команд одновременно, прерываний там нет. Это не CPU.
Я делал выполнение двух независимых потоков на двух разных адаптерах. Вот это работает. На DX12 создается резделяемая текстура с помощью OpenSharedHandle. А потом копируй и извлекай оттуда все что нужно. Думаю в Вулкане есть что-то подобное.
Могу дать весь код, но он довольно большой - я делал универсальный класс CrossAdapter_Texture и там много лишнего.
almatea
> у меня довольно тяжелый интерфейс - например галерея с текстурами и причими картинками, которые придется гонять туда-сюда.
Ну у меня интерфейс наверно не легче. Надписи там, ползунки. Вот картинка. В центральном окошке рисуются или графики или текстуры которые файдятся друг через друга (типа слайд-шоу). Все это рендерит встроенный микрософтовский эмулятор видеокарты.
Можно заметить, что основной рендер выдает 23.2 fps (я не показал его окно - там 3D фрактал), a окно GUI рисуется с частотой 60 фпс (у меня монитор такой). И никаких проблем.
Suslik
> просто медленную задачу надо разбить на множество более простых задач и в промежутках между ними натолкать обновление того, что должно обновляться часто
Это не всегда возможно. У меня например крутится крайне тежелый шейдер занимающий до 100-200 мс. При этом ползунком например пользоваться практически невозможно - он просто не успевает за мышкой. Картинка замирает и дергается.
Разбить шейдер на отдельные куски можно, но при этом время его выполнения будет уже не 100-200 мс а 200-400 и более. Ну и до конца от дерганий все равно избавиться не удается.
Независимый адаптер решает все проблемы, благо он в системе уже есть и никем не используется. Все что нужно это один раз разобраться с мультиадаптерным режимом который есть и в DX12 и в Вулкане.
san
> Разбить шейдер на отдельные куски можно, но при этом время его выполнения будет
> уже не 100-200 мс а 200-400 и более Ну и до конца от дерганий все равно
> избавиться не удается.
спорим, это не так? у тебя обычный пиксельный шейдер и если ты просто разобьёшь свой рендертаргет на блоки 64х64 пикселя, то рендеринг каждого блока займёт меньше 1мс, а оверхед на рендеринг всего изображения блоками вместо большого квада будет порядка процентов в худшем случае (скорее всего измеримой разницы вообще не будет, если синхронизация поставлена нормально).
Suslik
Как мне разбить задачу, которая зависит от какой-то внешней библиотеки, которая для меня черный ящик? К примеру, я ожидаю вывода картинки от нейросети, а пока я жду эту картинку, мне нужно обновлять интерфейс
san
> Я с этим долго бодался но не годится архитектура GPU для обработки двух потоков
> команд одновременно, прерываний там нет. Это не CPU.
Операционная система же вполне позволяет запускать две и больше программы использующие GPU, и на мощном GPU все идет гладко и одновременно. Значит, и внутри одной программы это сделать можно. Я только удивлен, что это не так просто - вроде бы уже сто раз должны были это сделать с туториалами и открытым кодом.
almatea
> Как мне разбить задачу, которая зависит от какой-то внешней библиотеки, которая для меня черный ящик? К примеру, я ожидаю вывода картинки от нейросети, а пока я жду эту картинку, мне нужно обновлять интерфейс
запрашивай от нейросети не всё изображение, а только часть. нейросети батчат обработку пикселей в относительно небольшие группы и если ты запрашиваешь тайл больше этого размера, ты не потеряешь в производительности.
Suslik
> у тебя обычный пиксельный шейдер и если ты просто разобьёшь свой рендертаргет на блоки 64х64 пикселя, то рендеринг каждого блока займёт меньше 1мс, а оверхед на рендеринг всего изображения блоками вместо большого квада будет порядка процентов в худшем случае
Нет не так. Если разбить задачу для шейдера который считает картинку скажем 1024х1024 за 100 мс на 16 кусков по 256х256 то время выполнение возрастет примерно в 2-3 раза за счет загрузки-выгрузки шейдера. Переключение шейдеров это довольно медленная операция особенно если шейдер громадного размера (как в моем случае).
Поверь, я все перепробовал, причем консультировался непосредствено с разработчиками видеокарт из AMD. У меня это проблема стоит наиболее остро, поскольку это VR аппликация и мне кровь из носу нужно обновлять картинку в хедсете каждые 11 мс. При этом шейдер создающий изображение даже одной плитки (а в панораме таких 16 штук) выполняется за 100-200 мс. Уменьшение размера тейла (т.е. увеличение их количества) приводит к существенному (в разы) замедлению общего времени рендера. Но даже это не гарантирует отсутствие пропавших фреймов основного рендера. Как я сказал, архитектура GPU просто не предназначена для таких задач.
san
> Если разбить шейдер который считает картинку скажем 1024х1024 за 100 мс на 16
> кусков по 256х256 то время выполнение возрастет примерно в 2-3 раза за счет
> загрузки-выгрузки шейдера. Переключение пейдеров это довольно медленная
> операция особенно если шейдер громадного размера (как в моем случае).
спорим, что это не так? я утверждаю, что разница производительности одного таргета 1024х1024 против 16 кусков 256х256 в случае тяжёлого фрагментного шейдера будет либо порядка процентов, либо под погрешностью измерения.
если у тебя что-то при этом тормозило, это значит, что ты что-то где-то накосячил, что не относится к делу. например, ты пытаешься перекомпилировать пайплайн при каждой смене или что-то подобное по нелепости.
Suslik
> спорим, что это не так? я утверждаю, что разница производительности одного таргета 1024х1024 против 16 кусков 256х256 в случае тяжёлого фрагментного шейдера будет либо порядка процентов, либо под погрешностью измерения.
Спорим что нет. Я могу прислать тебе весь проект где размер тейла можно менять. Можешь посмотреть что будет. Только у меня не фрагментный шейдер а компьют но не суть важно. Единственное требование - код не для публикации. Это реальный продукт на Steam.
san
> Я могу прислать тебе весь проект где размер тейла можно менять.
у меня нет никакого желания фиксить твои баги. но я могу сделать тестовую пиксель-баунд демку и продемонстрировать, что разница будет под погрешностью. если у тебя это не так, то ищи косяки сам.
Suslik
> запрашивай от нейросети не всё изображение, а только часть. нейросети батчат
> обработку пикселей в относительно небольшие группы и если ты запрашиваешь тайл
> больше этого размера, ты не потеряешь в производительности.
Что если я считаю физику частиц или динамику жидкости с помощью фрагментного или компьют шейдера? Как разбивать?
Suslik
Не забудь, что между рендером куска, GPU должен переключиться на отрисовку GUI (в моем случае основной рендер). Т.е должен загрузить новый набор шейдеров и ресурсов.
Я не предлагаю тебе "фиксать баги", да ты и не разберешься во всем проекте, он очень большой. Но кусок кода отвечающий собственно за рендер фрактала достаточно прост. Там негде "накосачить". Просто я подозреваю что ты не имел дела с шейдерами такой сложности. И задачами подобной этой. У тебя все же другая направленность. Тут начинается такая специфика которая у 99.99% разработчиков не встречалась. Очень уж задача специфическая.
Но проверить можешь. Я могу дать тебе код шейдера. Выводи результат в текстуру. Ну и в качестве второго рендера запусти другой шейдер который эту текстуру будет просто показывать в окошке, попутно например меняя ее цвет. Думаю это легко реализовать на любом фреймворке.