четверг, 14 января 2010 г.

UAV vs RT

Сегодня решил померить точно, во сколько обходится unordered read/write на HD 5xxx. Для теста взял десять перекрывающих друг друга плоскостей, которые формируют различный overdraw в разных частях буфера кадра:



В первом варианте для подсчёта overdraw использовалась unordered текстура (флаги D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE, формат R32_UINT) и инкремент в пиксельном шейдере, во втором - простая render-target текстура (флаги D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE, формат R8_UNORM) и аддитивный блендинг в буфере кадра. Для записи в UAV нельзя использовать форматы, отличные от R32_UINT и R32_FLOAT (их можно только кастовать через механизм view, например, R32_UINT -> R8G8B8A8_UNORM, при чтении, что я и делал). Если попробовать использовать форматы вроде R_UNORM, R8_UINT или R16_UINT, то DX Debug вываливает в Output сообщение такого вида:
D3D11: ERROR: ID3D11DeviceContext::DrawIndexed: The Unordered Access View (UAV) in slot 0 of the Pixel Shader unit has the Format (R8_UINT). This format does not support being read from a shader as as UAV. This mismatch is invalid if the shader actually uses the view (e.g. it is not skipped due to shader code branching). It was unfortunately not possible to have all hardware implementations support reading this format as a UAV, despite that the format can written to as a UAV. If the shader only needs to perform reads but not writes to this resource, consider using a Shader Resource View instead of a UAV.
Т. к. мне необходим инкремент, приходится использовать R32_UINT, хотя в RT-текстуре для экономии используется R8_UNORM (R8_UINT не blendable).

Я тестировал инкремент в двух разрешениях, это был отдельный render path, без всего остального кода. Только инкремент/блендинг и вывод значения через чтение в пиксельном шейдере из SRV. И вот что получилось:
512x512:

R/W texture: ~1040(1080) fps (0.962(0.925) ms)
RT texture: ~3130 fps (0.319 ms)
1024x1024:

R/W texture: ~300(305) fps (3.33(3.28) ms)
RT texture: ~1220 fps (0.819 ms)
(Для R/W текстуры значение в скобках указано для случая, когда UAV очищается в Compute Shader, а не через ID3D11DeviceContext::ClearUnorderedAccessViewUint()).

Из тестов видно, что старый добрый RT + fixed function blending серьёзно опережает unordered access - в 3-4 раза. В более высоких разрешениях отставание будет только увеличиваться, возможно, составит порядок.

Исходя из этого, можно сделать следующий вывод: на HD 5xxx везде, где только можно, следует избегать использования unordered access, и использовать старые добрые методы обработки данных. Использовать UAV следует только там, где он абсолютно необходим.

P.S. Не думаю, что на Fermi эта ситуация изменится. Неважно, насколько быстр GPU - это проблема памяти.

3 комментария:

  1. > Неважно, насколько быстр GPU - это проблема памяти.
    И в чем собственно она заключается? Чем блендинг кардинально отличается от UAV? Те же RW только в порядке RWRWRW. Имхо, проблема драйвера.

    ОтветитьУдалить
  2. > В более высоких разрешениях отставание будет только увеличиваться, возможно, составит порядок.
    странное утверждение

    > Не думаю, что на Fermi эта ситуация изменится.
    у ферми память с L1 и L2-кэшем, поэтому рано делать такие утверждения

    ОтветитьУдалить
  3. Блендинг производится в ROP-ах, которые предназначены для этой операции. Сложно сказать, что именно приводит к различиям (архитектуры закрыты). Возможно, организация в широкие тайлы и большее кол-во обрабатываемых данных за такт, чем в shader core.

    L1, L2 кэши - ну, может быть, не знаю. Мне все эти "революции" надоели ещё со времён GeForce FX. Когда выйдет - тогда и посмотрим, что и как. А так вилами по воде.

    ОтветитьУдалить