Рабочее измерение для произвольного простого числа рабочих элементов - PullRequest
0 голосов
/ 30 апреля 2018

Я видел много учебных пособий по настройке рабочих измерений, в которых количество рабочих элементов удобно разделить на 3 измерения. У меня большое количество рабочих заданий, говорите 164052. Каков наилучший способ настроить произвольное количество рабочих элементов? Поскольку в моей программе количество рабочих элементов может варьироваться, мне нужен способ для его автоматического расчета.

Что мне делать, если число простое, скажем 7879?

1 Ответ

0 голосов
/ 30 апреля 2018

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

Таким образом, остается вопрос о том, как разделить рабочие элементы среди местных групп. Учитывая размер задачи N рабочих элементов, у вас есть несколько вариантов их разделения на локальные группы.

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

size_t work_items = 164052;
clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, &work_items, nullptr, 0, nullptr, nullptr);

Если вы программируете для конкретной среды, в которой заранее известно идеальное количество локальных рабочих элементов (часто 32 или 64 для архитектур NVidia / AMD), вы можете добиться более высокой производительности, если заставить количество рабочих элементов соответствовать кратное этому числу.

size_t work_items = 164052;
size_t LOCAL_SIZE = 64;
work_items += LOCAL_SIZE - (work_items % LOCAL_SIZE);
clEnqueueNDRangeKernel(queue, kernel, 1, nullptr, &work_items, &LOCAL_SIZE, 0, nullptr, nullptr);

Обратите внимание, однако, что для этого необходимо добавить проверку в код ядра, чтобы предотвратить обработку на рабочих элементах, которые на самом деле не существуют, или чтобы вы добавили в свои буферы пространство для фиктивных элементов.

kernel void main(..., int N) {
    if(get_global_id(0) >= N) return;
    ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...