cuda - sata - ¿Es posible acceder al disco duro directamente desde gpu?
disco duro externo (2)
¿Es posible acceder al disco duro / disco flash directamente desde la GPU (CUDA / openCL) y cargar / almacenar contenido directamente desde la memoria de la GPU?
Estoy tratando de evitar copiar cosas del disco a la memoria y luego copiarlas en la memoria de la GPU.
Leí sobre Nvidia GPUDirect pero no estoy seguro de si cumple con lo que he explicado anteriormente. Habla de memoria y discos GPU remotos, pero los discos en mi caso son locales para la GPU.
La idea básica es cargar los contenidos (algo así como dma) -> hacer algunas operaciones -> almacenar los contenidos de nuevo en el disco (de nuevo en modo dma).
Estoy tratando de involucrar CPU y RAM lo menos posible aquí.
Por favor, siéntase libre de ofrecer cualquier sugerencia sobre el diseño.
Al tratar de usar esta característica, escribí un pequeño ejemplo en Windows x64 para implementar esto. En este ejemplo, kernel "directamente" accede al espacio en disco. En realidad, como lo mencionó @RobertCrovella anteriormente, el sistema operativo está haciendo el trabajo, probablemente con algún trabajo de CPU; pero no hay codificación suplementaria.
__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 ;
}
Para cualquier otra persona que busque esto, ''desatar el perezoso'' hizo más o menos lo que quiero.
Revise lo siguiente para ver si esto puede ser útil para usted.
La implementación más directa usando RDMA para GPUDirect anclaría la memoria antes de cada transferencia y la destrabaría justo después de que se complete la transferencia. Desafortunadamente, esto no funcionará bien en general, ya que inmovilizar y anular la memoria son operaciones costosas. El resto de los pasos requeridos para realizar una transferencia RDMA, sin embargo, se puede realizar rápidamente sin ingresar al kernel (la lista DMA puede almacenarse en caché y reproducirse utilizando registros MMIO / listas de comandos).
Por lo tanto, la memoria de desenganche perezosa es clave para una implementación de RDMA de alto rendimiento. Lo que implica es mantener fija la memoria incluso después de que la transferencia haya finalizado. Esto aprovecha el hecho de que es probable que la misma región de memoria se use para futuras transferencias de DMA, por lo tanto, el desabillar la fijación guarda las operaciones de pin / unpin.
Una implementación de ejemplo de desenganche lento mantendría un conjunto de regiones de memoria ancladas y solo destrabará algunas de ellas (por ejemplo, la usada menos recientemente) si el tamaño total de las regiones alcanzó algún umbral, o si el bloqueo de una nueva región falló debido a BAR agotamiento del espacio (ver tamaños de la BARRA PCI).
Aquí hay un enlace a una guía de aplicación y documentos de nvidia .