Гарантирует ли OpenCL целостность буферной памяти с несколькими очередями команд? - PullRequest
0 голосов
/ 07 марта 2019

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

ThreadA - это легкий конвейер обработки, который запускается в режиме реального времени при получении новых данных.ThreadB - это тяжелый медленный конвейер обработки, который использует те же входные данные, но обрабатывает их асинхронно с более медленной скоростью.Я использую двойной буфер для разделения конвейеров, но позволяю ThreadB работать с теми же входными данными, которые записаны на устройство с помощью цикла ThreadA.

ThreadA:

  1. Извлечение изображения из сети, когда доступны данные
  2. Запись изображения на устройство cl_mem BufferA с использованием clEnqueueWriteBuffer(CommandQueueA)
  3. Вызов обработки изображения KernelA с использованием clEnqueueNDRangeKernel(CommandQueueA) после завершения записи (ядро выводит результаты в cl_mem OutputA)
  4. Чтение обработанного результата из OutputA с использованием цикла clEnqueueReadBuffer(CommandQueueA)

ThreadB

  1. Подождитепока не истечет достаточное время (работает медленнее)
  2. Копирование BufferA в BufferB с использованием clEnqueueCopyBuffer(CommandQueueB) (двойной буферный обмен)
  3. Вызов медленной обработки изображений KernelB с использованием clEnqueueNDRangeKernel(CommandQueueB) после завершения копирования (ядро выводит результаты в cl_mem OutputB)
  4. Чтение обработанного результата из OutputB с использованием clEnqueueReadBuffer(CommandQueueB)

Мои вопросы

Существует потенциальное состояние гонки между ThreadA шагом 2 и ThreadB шагом 2. Мне все равно, что будет выполнено первым, я простоНет, чтобы убедиться, что я не копирую BufferA в BufferB во время записи BufferA.

  1. Предоставляет ли OpenCL какие-либо неявные гарантии того, что этого не произойдет?
  2. Если нет, если я вместо этого на ThreadB шаг 2 использую clEnqueueCopyBuffer(CommandQueueA), чтобы операции записи и копирования находились в одной и той же очереди команд, гарантирует ли это, что они не могут выполняться одновременно, даже если очередь позволяетвыполнение заказа?
  3. Если нет, то есть ли лучшее решение, чем добавление события WriteBuffer в ThreadA в список ожидания команды CopyBuffer в ThreadB?

Кажется, что все это должно работать, но я не могу найти, где в спецификации OpenCL это говорит, что это хорошо.Если возможно, приведите в своих ответах спецификацию OpenCL.

1 Ответ

2 голосов
/ 08 марта 2019

Предоставляет ли OpenCL какие-либо неявные гарантии того, что этого не произойдет?

Нет, неявная синхронизация не выполняется, если вы не используете одну очередь команд по порядку.

Если нет, если я вместо этого на ThreadB шаг 2 использую clEnqueueCopyBuffer (CommandQueueA), чтобы и запись, и операции копирования находятся в той же очереди команд, делает это гарантировать, что они не могут работать одновременно, хотя очередь разрешает выполнение вне очереди?

Нет, независимо от типа очереди (по порядку или по порядку), Среда выполнения OpenCL не отслеживает зависимости памяти команды. Пользователь несет ответственность за указание событий в списке ожидания, если существует какая-либо зависимость между командами.

Следующая цитата может служить доказательством этого:

s3.2.1 Модель выполнения: контекст и очереди команд

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

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

Если нет, есть ли лучшее решение, чем добавление Событие WriteBuffer в ThreadA в лист ожидания Команда CopyBuffer в ThreadB?

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

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