Как применить Unified Memory к существующей выровненной памяти хоста

Я участвую в интеграции 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) последний оператор print печатает 0. При доступе к устройству с помощью запуска ядра в больших файлах неудивительно сообщать о недопустимых доступах.

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

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

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

1 ответ

Решение

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

Другие вопросы по тегам