2014-12-03 2 views
10

Возможно ли доступ к жесткому диску/флеш-памяти непосредственно с GPU (CUDA/openCL) и загрузка/хранение контента непосредственно из памяти графического процессора?Можно ли получить доступ к жесткому диску непосредственно из gpu?

Я пытаюсь избежать копирования файлов с диска в память и затем скопировать его в память графического процессора.

Я читал о Nvidia GPUDirect, но не уверен, что он делает то, что я объяснил выше. В нем рассказывается о удаленной памяти и дисках GPU, но диски в моем случае являются локальными для GPU.

Основная идея - загрузить содержимое (что-то вроде dma) -> выполнить некоторые операции -> сохранить содержимое на диск (снова в режиме dma).

Я стараюсь как можно меньше задействовать процессор и оперативную память.

Пожалуйста, не стесняйтесь предлагать какие-либо предложения по дизайну.

+1

Может кто-нибудь объяснить, что не так с вопросом? –

+5

Это невозможно без вмешательства хозяина. Хост владеет диском. GPUDirect предназначен для передачи данных между устройствами PCIE.Если у вас был собственный контроллер жесткого диска PCIE, на той же самой PCIE-матрице, что и у графического процессора, и доступ к исходному коду драйвера устройства, можно было бы, возможно, написать драйвер RUDMA GPUDirect, который позволит осуществлять прямую передачу с GPU на диск. (Это все равно потребует вмешательства хозяина для настройки.) На практике никто не предполагает, что это тот уровень усилий, который вы хотите предпринять. –

+0

На практике пропускная способность системной памяти (25-50 ГБ/сек) и пропускная способность PCIe gen3 (10-12 ГБ/с) настолько велики по сравнению с пропускной способностью SSD (0,5 ГБ/с), что должно быть минимальное воздействие на пропускная способность GPU <-> Передача диска при перемещении данных через хост. Задержка может быть другой, но вопрос не указывает конкретные требования к задержке или пропускной способности. – njuffa

ответ

9

Для тех, кто ищет это, «ленивый отказ» сделал более или менее то, что я хочу.

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

Самый простой реализации с использованием RDMA для GPUDirect бы штырьковый памяти перед каждой передачей и открепить его сразу же после передачи завершена. К сожалению, это будет плохо работать в целом, так как запоминание и отмена памяти - дорогостоящие операции. Однако остальные шаги , необходимые для выполнения передачи RDMA, могут быть выполнены без ввода ядра (список DMA можно кэшировать, а воспроизводится с использованием регистров MMIO/списков команд).

Следовательно, лениво неокрашиваемая память является ключом к реализации RDMA с высокой производительностью. Это подразумевает, что память сохраняется даже после завершения передачи . Это исходит из того, что вполне вероятно, что одна и та же область памяти будет использоваться для будущих передач DMA , поэтому ленивое отключение сохраняет операции pin/unpin.

Пример реализация отложенного открепления будет держать набор возлагало областей памяти, и только открепить некоторые из них (например, по меньшей мере недавно использовал один), если суммарный размер областей достигли некоторых порога, или если пиннинга новый регион потерпел неудачу из-за пробега BAR (см. размеры PCI BAR).

Вот ссылка на application guide и на nvidia docs.

1

Пытаясь использовать эту функцию, я написал небольшой пример для Windows x64, чтобы реализовать это. В этом примере ядро ​​«напрямую» обращается к дисковым пространствам. На самом деле, как упоминал ранее @RobertCrovella, операционная система выполняет свою работу, возможно, с некоторой работой процессора; но никакого дополнительного кодирования.

__global__ void kernel(int4* ptr) 
{ 
    int4 val ; val.x = threadIdx.x ; val.y = blockDim.x ; val.z = blockIdx.x ; val.w = gridDim.x ; 
    ptr[threadIdx.x + blockDim.x * blockIdx.x] = val ; 
    ptr[160*1024*1024 + threadIdx.x + blockDim.x * blockIdx.x] = val ; 
} 

#include "Windows.h" 

int main() 
{ 
    // 4GB - larger than installed GPU memory 
    size_t size = 256 * 1024 * 1024 * sizeof(int4) ; 

    HANDLE hFile = ::CreateFile ("GPU.dump", (GENERIC_READ | GENERIC_WRITE), 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ; 

    HANDLE hFileMapping = ::CreateFileMapping (hFile, 0, PAGE_READWRITE, (size >> 32), (int)size, 0) ; 

    void* ptr = ::MapViewOfFile (hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, size) ; 

    ::cudaSetDeviceFlags (cudaDeviceMapHost) ; 

    cudaError_t er = ::cudaHostRegister (ptr, size, cudaHostRegisterMapped) ; 
    if (cudaSuccess != er) 
    { 
     printf ("could not register\n") ; 
     return 1 ; 
    } 

    void* d_ptr ; 
    er = ::cudaHostGetDevicePointer (&d_ptr, ptr, 0) ; 
    if (cudaSuccess != er) 
    { 
     printf ("could not get device pointer\n") ; 
     return 1 ; 
    } 

    kernel<<<256,256>>> ((int4*)d_ptr) ; 

    if (cudaSuccess != ::cudaDeviceSynchronize()) 
    { 
     printf ("error in kernel\n") ; 
     return 1 ; 
    } 

    if (cudaSuccess != ::cudaHostUnregister (ptr)) 
    { 
     printf ("could not unregister\n") ; 
     return 1 ; 
    } 

    ::UnmapViewOfFile (ptr) ; 

    ::CloseHandle (hFileMapping) ; 
    ::CloseHandle (hFile) ; 

    ::cudaDeviceReset() ; 

    printf ("DONE\n"); 

    return 0 ; 
} 
+0

Не будет ли это просто кэшировать все в основной памяти, а иногда/окончательно сбрасывать изменения на диск? – einpoklum

+0

@einpoklum, это показало мне разумный ответ на начальный вопрос: «Основная идея - загрузить содержимое (что-то вроде dma) -> выполнить некоторые операции -> сохранить содержимое обратно на диск (снова в режиме dma)». Однако это может быть так. Однако программно ничто не должно быть реализовано на стороне процессора. –

Смежные вопросы