Контексты, потоки и события CUDA на нескольких графических процессорах - PullRequest
1 голос
/ 08 марта 2012

TL; версия DR:"Каков наилучший способ циклического обращения к ядру для нескольких графических процессоров с Python / PyCUDA, чтобы работа ЦП и ГП могла выполняться параллельно?"с надписью «Я не мог быть первым, кто спросил об этом; что-нибудь, о чем я должен прочитать?»

Полная версия:

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

  • Запросы поступают в центральный процесс.
  • Этот процесс разветвляется для обработки одного запроса.
  • Данныезагружается из БД (относительно дорого).

Следующее повторяется произвольное количество раз в зависимости от запроса (десятки):

  • Несколько быстрых вызовов ядрадля вычисления данных, необходимых для более поздних ядер.
  • Один медленный вызов ядра (10 секунд).

Наконец:

  • Результаты вызовов ядрасобираются и обрабатываются на процессоре, а затем сохраняются.

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

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

  • Создайте контекст перед началом любой работы с графическим процессором.
  • Запустите ядра для первого набора данных.
  • Запишите событие после последнего вызова ядра в серии.
  • Подготовьте второй набор данных на ЦП, пока первый выполняет вычисления на GPU.
  • Запусквторой набор, повторите.
  • Убедитесь, что каждое событие синхронизировано перед сбором результатов и их сохранением.

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

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

Основной программой является Python 2.7, использующийPyCUDA для доступа к графическому процессору.В настоящее время он не является многопоточным, и хотя я бы предпочел оставить его таким («теперь у вас две проблемы» и т. Д.), Если ответ означает потоки, это означает потоки.Точно так же было бы неплохо просто иметь возможность вызывать event.synchronize () в главном потоке, когда пришло время блокировать данные, но для наших нужд более важно эффективное использование оборудования.Поскольку мы потенциально будем обслуживать несколько запросов одновременно, важно, чтобы другие процессы использовали графический процессор, когда этот процесс не использует его.

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

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

1 Ответ

1 голос
/ 09 марта 2012

Предупреждение: я не пользователь PyCUDA (пока).

С CUDA 4.0+ вам даже не нужен явный контекст для каждого графического процессора.Вы можете просто позвонить cudaSetDevice (или эквиваленту PyCUDA), прежде чем выполнять работу с устройством (cudaMalloc, cudaMemcpy, запускать ядра и т.Возможно, потребуется создать потоки и / или события и использовать cudaEventSynchronize (или эквивалент PyCUDA).Вы можете даже сделать один поток ожидания для события, вставленного в другой поток, для создания сложных зависимостей.

Поэтому я подозреваю, что ответ на сегодняшний день намного проще, чем отличный ответ talonmies pre-CUDA-4.0.

Вы также можете найти этот ответ полезным.

(Re) Редактировать с помощью OP: Насколько я понимаю, PyCUDA поддерживает версии CUDA до 4.0,и поэтому все еще использует старый API / семантику (API драйвера?), поэтому ответ talonmies по-прежнему актуален.

...