Как применить Unified Memory к существующей выровненной памяти хоста - PullRequest
0 голосов
/ 30 апреля 2019

Я участвую в интеграции CUDA в некоторые существующие программы. Программное обеспечение, в которое я интегрирую, псевдо-в реальном времени, поэтому оно имеет библиотеку диспетчера памяти, которая вручную передает указатели из одного большого выделения памяти, которое выделяется заранее. Унифицированная память CUDA привлекательна для нас, так как теоретически мы могли бы теоретически изменить этот большой кусок памяти на Унифицированную память, сохранить существующий код ЦП и позволить нам добавлять ядра графических процессоров с минимальными изменениями в существующих данных. Поток ввода / вывода.

Части нашего существующего кода обработки ЦП требуют, чтобы память была выровнена с определенным выравниванием. cudaMallocManaged () не позволяет мне указывать выравнивание для памяти, и я чувствую, что необходимость копировать между «управляемыми» и строгими буферами ЦП для этих разделов ЦП практически не вписывается в цель единой системы обмена сообщениями. Есть ли какой-нибудь известный способ решения этой проблемы, который мне не хватает?

Я нашел эту ссылку на переполнении стека, которая, кажется, решает ее теоретически, но я не смог получить хорошие результаты с помощью этого метода. Использование CUDA 9.1, Tesla M40 (24 ГБ):

#include <stdio.h>
#include <malloc.h>
#include <cuda.h>

#define USE_HOST_REGISTER 1

int main (int argc, char **argv)
{
   int num_float = 10;
   int num_bytes = num_float * sizeof(float);

   float *f_data = NULL;

   #if (USE_HOST_REGISTER > 0)
   printf(
      "%s: Using memalign + cudaHostRegister..\n",
       argv[0]);

   f_data = (float *) memalign(32, num_bytes);

   cudaHostRegister(
      (void *) f_data,
      num_bytes,
      cudaHostRegisterDefault);
   #else
   printf(
      "%s: Using cudaMallocManaged..\n",
       argv[0]);

   cudaMallocManaged(
      (void **) &f_data,
      num_bytes);
   #endif

   struct cudaPointerAttributes att;
   cudaPointerGetAttributes(
      &att,
      f_data);

   printf(
      "%s: ptr is managed: %i\n",
       argv[0],
       att.isManaged);
   fflush(stdout);

   return 0;
}

При использовании memalign () + cudaHostRegister () (USE_HOST_REGISTER == 1) последний оператор печати печатает 0. Доступ к устройству с помощью запусков ядра в больших файлах неудивительно сообщает о недопустимых доступах.

При использовании cudaMallocManaged () (USE_HOST_REGISTER == 0) последний оператор print печатает 1, как и ожидалось.

edit: cudaHostRegister () и cudaMallocManaged () возвращают мне успешные коды ошибок. Оставил эту проверку ошибок в моем образце, которым я поделился, но я проверял их во время моей начальной работы по интеграции. Просто добавил код для проверки, и оба все еще возвращают CUDA_SUCCESS.

Спасибо за ваши идеи и предложения.

1 Ответ

1 голос
/ 08 мая 2019

В настоящее время в CUDA не существует метода, позволяющего взять существующее выделение памяти хосту и преобразовать его в управляемое выделение памяти.

...