"Группировка" нескольких вызовов async_work_group_copy() с одним событием

Прав ли я, что следующая цитата из стандарта OpenCL 1.1 (раздел 6.11.10)

Аргумент события может также использоваться для связывания async_work_group_copy с предыдущей асинхронной копией, позволяющей событию быть разделенным несколькими асинхронными копиями;

означает, что я мог бы "сгруппировать" несколько async_work_group_copy() вызовы с одним событием и использование только этого события для ожидания завершения всей группы операций копирования?

Замечание: кажется, фрагмент кода для using_local() Ядро в следующем блоге сделать именно это? https://streamcomputing.eu/blog/2014-06-19/using-async_work_group_copy-on-2d-data/

1 ответ

Решение

На Intel iGPU,

// tmp-store
// tmp2-compute
// tmp3-load    
pipelineEvent[0]=async_work_group_copy(&b[g*gs],tmp,gs,pipelineEvent[0]);
pipelineEvent[0]=async_work_group_copy(tmp3,&e[g*gs],gs,pipelineEvent[0]);
tmp2[l]=tmp2[l]+3;
wait_group_events(1,&pipelineEvent[0]);

дает тот же результат с той же задержкой, что и

// tmp-store
// tmp2-compute
// tmp3-load    
pipelineEvent[0]=async_work_group_copy(&b[g*gs],tmp,gs,0);
pipelineEvent[1]=async_work_group_copy(tmp3,&e[g*gs],gs,0);
tmp2[l]=tmp2[l]+3;
wait_group_events(2,&pipelineEvent[0]);

поэтому спецификация должна быть правильной в отношении "общего доступа к нескольким асинхронным копиям".


Может быть event_t имеет счетчик внутри. Тогда возможно

  • async_work_group_copy увеличивает его на 1(или на N= количество рабочих элементов в группе)
  • когда асинхронное выполнение завершено, планировщик уменьшает счетчик на 1(или каждый рабочий элемент уменьшается на 1)
  • wait_group_events проверяет, равен ли он нулю

так что не имеет значения, если использовать 90 событий или одно событие (и не спекулировать больше) .


Но если подходить к "можно также использовать, чтобы связать" часть спекулятивно,

если реализация просто чередует инструкции для выполнения "асинхронного преобразования":

multiple events for multiple async copies
copy1 calculate copy2 calculate copy1 calculate copy2 calculate copy1

single event for multiple async copies(grouped copies)
copy1 copy2 calculate copy1 copy2 calculate copy1 copy2 calculate

ожидающий барьер может быть более детализирован, когда копии группируются и проверяются (против завершения) один раз, а не дважды на каждой асинхронной итерации.

если реализация выполняет копирование одновременно асинхронно(например, использование скалярных конвейеров для копий при использовании SIMD-конвейеров для вычислений, например, NCU имеет 2xScalar-единицы и 30xSIMD-единицы в каждом вычислительном блоке):

multiple events for multiple copies
SIMD: compute compute compute compute
scalar-1: copy1 copy1 copy1 copy1
scalar-2: copy2 copy2 copy2 copy2

single event for multiple copies
SIMD: compute compute compute compute
scalar-1:copy1 copy2 copy1 copy2 copy1 copy2
scalar-2: copy1 copy2 copy1 copy2 copy1 copy2

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


CPU, GPU, FPGA могут работать совершенно по-разному и async_work_group_copy поддерживается, чтобы мы не спекулировали на объединенном доступе к памяти, используя примитивы (или их векторные типы), поэтому я бы использовал любую версию обработки событий, которая кажется полезной.

Другие вопросы по тегам