OpenCL: рабочие элементы, элементы обработки, NDRange

Мои одноклассники и я впервые сталкиваются с OpenCL. Как и ожидалось, мы столкнулись с некоторыми проблемами. Ниже я подытожил вопросы, которые у нас были, и ответы, которые мы нашли. Тем не менее, мы не уверены, что с нами все в порядке, так что было бы здорово, если бы вы, ребята, могли посмотреть на наши ответы и на вопросы ниже.

Почему мы не разделили это на отдельные вопросы?

  • Они частично связаны друг с другом.
  • Мы считаем, что это типичные начинающие вопросы. Те сокурсники, с которыми мы консультировались, ответили "Ну, что я тоже не понял".

Рабочие элементы и элементы обработки

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

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

Вопрос 1: Правильно ли это? Есть ли лучший способ выразить это?

NDRange

Вот как мы воспринимаем концепцию NDRange:

  • Количество рабочих элементов, находящихся там, представлено размером NDRange. Как правило, это также называют глобальным размером. Однако NDRange может быть одно-, двух- или трехмерным ( "ND" ):
    • Одномерной задачей было бы некоторое вычисление линейного вектора. Если размер вектора равен 64 и для обработки этого вектора есть 64 рабочих элемента, размер NDRange равен 64.
    • Двумерная задача - это некоторое вычисление на изображении. В случае с изображением 1024x768 размер GDR NDRange будет 1024, а размер NDRange Gy будет 768. Это предполагает, что для обработки каждого пикселя этого изображения есть рабочие элементы 1024x768. Размер NDRange равен 1024x768.
    • Трехмерным примером может быть некоторое вычисление на 3D-модели или около того. Кроме того, существует размер NDRange Gz.

Вопрос 2: Еще раз, это правильно?

Вопрос 3:. Эти измерения просто для правильной верности? Можно просто сохранить значения цвета каждого пикселя изображения в линейном векторе размера width * height. То же самое верно для любой 3D-проблемы.

Различные

Вопрос 4: Нам сказали, что выполнение ядер (другими словами: рабочие элементы) можно синхронизировать в рабочей группе с помощью barrier(CLK_LOCAL_MEM_FENCE); Understood. Мы также (неоднократно) говорили, что рабочие группы не могут быть синхронизированы. Хорошо. Но тогда какое использование barrier(CLK_GLOBAL_MEM_FENCE);?

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

Ответ 1

Вопрос 1: Почти правильный. Рабочий элемент - это экземпляр ядра (см. Параграф 2 раздела 3.2 стандарта). См. Также определение элемента обработки из стандарта:

Элемент обработки: виртуальный скалярный процессор. Рабочий элемент может выполнить на одном или нескольких элементах обработки.

см. также ответ, который я предоставил этому question.

Вопрос 2 и 3: Используйте более одного измерения или то же самое количество рабочих элементов, что и элементы данных для обработки, зависит от вашей проблемы. Это зависит от вас и насколько проще будет развитие. Также обратите внимание, что у вас есть ограничение с ocl 1.2 и ниже, что заставляет вас иметь глобальный размер, кратный размер рабочей группы (удаленный с ocl 2.0).

Вопрос 4: Да, синхронизация во время выполнения ядра возможна только в рабочей группе благодаря барьерам. Разница между флажками, которые вы передаете как параметр, относится к типу памяти. С CLK_LOCAL_MEM_FENCE все рабочие элементы должны будут убедиться, что данные, которые они должны записать в локальной памяти, будут видны другим. С CLK_GLOBAL_MEM_FENCE это то же самое, что и для глобальной памяти

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

Однако вы можете синхронизировать очереди команд по событиям, и на самом деле вы также можете создавать свои собственные события (называемые пользовательскими событиями), см. раздел 5.9 для событий и раздела 5.10 для пользовательских событий (стандартного).

Я бы посоветовал вам прочитать по крайней мере первые главы (от 1 до 5) стандарта. Если вы спешите, по крайней мере, глава 2, который на самом деле является глоссарием.