Как OpenCL распространяет рабочие элементы? - PullRequest
0 голосов
/ 06 июня 2018

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

  • 1 рабочий элемент: 35735 мс
  • 2 рабочих элемента: 11822 мс (в 3 раза быстрее, чем с1 рабочий элемент
  • 100 рабочих элементов: 239 мс (в 10 раз быстрее, чем с 10 рабочими)-items)
  • 200 рабочих элементов: 122 мс (в 2 раза быстрее, чем с 100 рабочими элементами)

Процессору в среднем требуется около 580 мс для выполнения той же операции.

Единственный результат, который я не понимаю и не могу объяснить, это результат с двумя рабочими элементами.Я ожидаю, что скорость будет примерно в 2 раза выше по сравнению с результатом только с одним рабочим элементом, так почему это 3?

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

CL_DEVICE_MAX_WORK_ITEM_SIZES равны 1024/1024/64 иCL_DEVICE_MAX_WORK_GROUP_SIZE 1024. Поскольку я использую только одно измерение, означает ли это, что у меня может быть одновременно запущено 1024 рабочих элемента на элемент обработки или на вычислительную единицу?Когда я попробовал с 1000 рабочих элементов, результат был меньшим, поэтому я решил, что не все из них были выполнены, но почему это будет?

Информация о моем GPU: Nvidia GeForce GT 525M, 96 ядер CUDA (2 вычислительных устройства, 48 ядер CUDA на устройство)

1 Ответ

0 голосов
/ 07 июня 2018

Единственный результат, который я не понимаю и не могу объяснить, это результат с двумя рабочими элементами.Я ожидаю, что скорость будет примерно в 2 раза выше по сравнению с результатом только с одним рабочим элементом, так почему это 3?

Точные причины, вероятно, будет трудно определить, но здесьВот несколько предложений:

  • Графические процессоры не оптимизированы вообще для небольшого количества рабочих элементов.Бенчмаркинг этого конца шкалы не особенно полезен.
  • 35 секунд - это очень много времени для графического процессора.Вероятно, у вашего GPU есть другие дела, поэтому ваш рабочий элемент, вероятно, прерывается много раз, и каждый раз его контекст сохраняется и возобновляется.
  • Это будет очень сильно зависеть от вашего алгоритма.Например, если ваше ядро ​​использует локальную память или объем частной памяти, зависящий от размера работы, оно может «перетекать» в глобальную память, что замедляет работу.
  • В зависимости от шаблонов доступа к памяти вашего ядра,Вы можете столкнуться с эффектами объединения чтения / записи.Больше рабочих элементов означает меньшее количество обращений к памяти.

Я также не уверен в том, может ли обрабатывающий элемент обрабатывать несколько рабочих элементов одновременно или это только одна работа-item на элемент обработки?

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

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

И последнее замечание: вычислительное оборудование имеет тенденцию группироваться в степени 2, поэтому обычно хорошей идеей будет сделать размеры рабочих групп кратными, например:16 или 64. 1000 - ни то, ни другое, что обычно означает, что некоторые ядра ничего не будут делать.

Когда я попробовал с 1000 рабочих элементов, результат был меньшим, поэтому я подумал, что не все из них получиливыполнено, но с чего бы это?

Пожалуйста, будьте более точны в этом вопросе, не понятно, о чем вы спрашиваете.

...