В чем разница между «действиями GPU» и «вызовами API» в результатах «nvprof»? - PullRequest
1 голос
/ 08 апреля 2019

В чем разница между «действиями графического процессора» и «вызовами API» в результатах «nvprof»?

Я не знаю, почему есть разница во времени в той же функции.Например, [CUDA memcpy DtoH] и cuMemcpyDtoH.

Так что я не знаю, какое сейчас подходящее время.Я должен написать измерение, но я не знаю, какой из них использовать.

enter image description here

1 Ответ

3 голосов
/ 08 апреля 2019

Активности - это фактическое использование графического процессора для какой-то конкретной задачи.

Операция может быть запущена ядром, или она может использовать оборудование GPU для передачи данных с хоста на устройство или наоборот.

Продолжительность такой "активности" - это обычный смысл продолжительности: когда эта деятельность начала использовать GPU, и когда она прекратила использовать GPU.

Вызовы API - это вызовы, сделанные вашим кодом (или другими вызовами API CUDA, выполненными вашим кодом) в драйвер CUDA или библиотеки времени выполнения.

Оба связаны, конечно. Вы выполняете действие на GPU, инициируя его с помощью какого-то вызова API. Это верно для копирования данных и запуска ядер.

Однако может быть разница в «продолжительности» или сообщаемом времени. Например, если я запускаю ядро, может быть много причин (например, предыдущее действие, которое еще не завершено в том же потоке), почему ядро ​​не "немедленно" начинает выполняться. «Запуск» ядра может быть выдающимся с точки зрения API в течение гораздо более длительного времени, чем фактическая продолжительность работы ядра.

Это относится и к другим аспектам использования API. Например, для cudaDeviceSynchronize() может потребоваться очень длительное или очень короткое время, в зависимости от того, что происходит (действия) на устройстве.

Вы можете лучше понять разницу между этими двумя категориями отчетов, изучив временную шкалу в визуальном профилировщике NVIDIA (nvvp).

Давайте использовать ваш конкретный случай в качестве примера. Похоже, это приложение, связанное с API драйвера, и у вас, по-видимому, есть запуск ядра и (я бы предположил) операция memcpy D-> H сразу после запуска ядра:

multifrag_query_hoisted_kernels (kernel launch - about 479ms)
cuMemcpyDtoH  (data copy D->H, about 20us)

В этой ситуации, поскольку запуск ядра CUDA происходит асинхронно, код хоста запустит ядро ​​и затем перейдет к следующей строке кода, которая является вызовом cuMemcpyDtoH, который блокирует вызов. Это означает, что вызов заставляет поток ЦП ждать там, пока не завершится предыдущая операция CUDA.

Часть активности профилировщика говорит нам, что продолжительность ядра составляет около 479 мс, а длительность копирования - около 20 мкс (намного короче). С точки зрения продолжительности деятельности, это время, которое имеет значение. Однако, как видно из потока ЦП хоста, время, которое требовалось потоку ЦП хоста для «запуска» ядра, было намного короче, чем 479 мс, и время, которое требовалось потоку ЦП хоста для завершения вызова cuMemcpyDtoH и перехода к следующая строка кода была намного длиннее, чем 20us, потому что она должна была ждать там при этом вызове библиотеки, пока не будет завершено ранее выпущенное ядро. И то, и другое связано с асинхронной природой запуска ядра CUDA и "блокирующей" или синхронной природой cuMemcpyDtoH.

...