Разница между использованием блокирующей записи и event.wait() с неблокирующей записью в OpenCL

Это может показаться глупым, но я наткнулся на этот вопрос и не могу сам на него ответить.

В чем практическая разница между использованием следующих двух фрагментов кода при записи в буфер в OpenCL?

  1. Блокировка записи:
queue->enqueueWriteBuffer(d_vec, CL_TRUE, 0, sizeof(int) * vec.size(), vec.data());
  1. Неблокирующая запись с помощью event.wait():
cl::Event event;
queue->enqueueWriteBuffer(d_vec, CL_FALSE, 0, sizeof(int) * vec.size(), vec.data(), nullptr, &event);
event.wait();

Мне кажется, что оба кода в итоге будут вести себя одинаково. Кто-нибудь может объяснить разницу?

Благодарю вас!


person José Eduardo Bueno    schedule 27.10.2020    source источник


Ответы (1)


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

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

person pmdj    schedule 27.10.2020
comment
Спасибо за ответ! Знаете ли вы, могут ли эти блокирующие и неблокирующие записи вести себя по-разному в Intel и NVidia? Причина, по которой я спрашиваю об этом, заключается в том, что у меня есть полная программа с некоторыми ядрами OpenCL, и я получаю расходящееся поведение с NVidia и Intel. Я провел несколько тестов на обоих и подтвердил, что ядра дают одинаковые результаты, что заставило меня подумать, что это может быть что-то с записью. Если вы знаете некоторые ссылки, где я могу прочитать больше об этом, это было бы очень полезно. (Кстати, при запуске моей программы на NVidia программа дает сбой, а на Intel - успешно). Спасибо еще раз - person José Eduardo Bueno; 27.10.2020
comment
@J.E.Chiarelli J.E.Chiarelli Что ж, реализации Intel используют унифицированную архитектуру памяти - память устройства и хоста - это одна и та же физическая память, поэтому чтение и запись не обязательно будут вызывать фактическую копию - это можно реализовать с помощью сопоставления копирования при записи и т. д. - person pmdj; 27.10.2020
comment
@ J.E.Chiarelli, возможно, код каким-то образом зависит от аспекта этой разницы в деталях реализации. Вы уверены, что для всех поставленных в очередь ядер, чтения и записи буфера, доступа к памяти хоста и т. д. правильно установлены события зависимости или используются соответствующие последовательные очереди? - person pmdj; 27.10.2020
comment
@ J.E.Chiarelli, трудно делать конкретные предложения, не видя кода - person pmdj; 27.10.2020
comment
ваши ответы очень полезны. Я не знал об этой унифицированной архитектуре памяти и функциях копирования при записи Intel. Код, над которым я работаю, довольно большой, и я не хотел бы больше тратить ваше время, но если вам интересно, вы можете его увидеть здесь и моя проблема связана с этим модуль. - person José Eduardo Bueno; 27.10.2020
comment
@JoséEduardoBueno Код там не совсем линейный, поэтому нет ничего явно неправильного, что бросалось бы мне в глаза. Но если вы подозреваете проблемы с синхронизацией, я бы попробовал дождаться завершения работы ядра после постановки в очередь в applyStdWells. Я бы также проверил, является ли используемая очередь параллельной или последовательной. - person pmdj; 27.10.2020
comment
еще раз большое спасибо! Я пытался дождаться завершения ядра в applyStdWells, а также ядра, которое работает до него, но все равно не повезло для NVidia ... Но в любом случае я продолжу копать. - person José Eduardo Bueno; 27.10.2020