2011-02-15 14 views
10

Estoy tratando de averiguar si el uso de cudaHostAlloc (o cudaMallocHost?) Es apropiado.CUDA Consideraciones sobre la memoria cero copia

Estoy tratando de ejecutar un núcleo donde mis datos de entrada son más que la cantidad disponible en la GPU.

¿Puedo cudaMallocHost más espacio que en la GPU? Si no, y digamos que asigné 1/4 del espacio que necesito (que se ajustará a la GPU), ¿hay alguna ventaja con el uso de memoria fija?

En esencia, tendré que copiar desde ese búfer de 1/4 de tamaño en mi búfer malloc'd de tamaño completo y eso probablemente no sea más rápido que el simple uso de cudaMalloc normal ¿verdad?

¿Este típico escenario de uso correcto para el uso cudaMallocHost:

  1. memoria del host allocate clavado (permite llamarlo "h_p")
  2. h_p poblar con la entrada Data- puntero del dispositivo
  3. get en la GPU para h_p
  4. núcleo de ejecución mediante ese puntero dispositivo para modificar el contenido de Expandido
  5. uso h_p como normal, que ahora se ha modificado contenido-

Entonces, ninguna copia tiene que contentarse entre los pasos 4 y 5, ¿verdad?

si eso es correcto, entonces puedo ver la ventaja para los núcleos que se ajuste en la GPU a la vez al menos

+0

Parece que se está haciendo varias preguntas ... – jmilloy

+0

@Derek Para evitar copias cuando se usa memoria no pagable (también conocida como memoria fija) en el host con 'cudaHostAlloc () 'solo tienes que usar la bandera' cudaHostAllocMapped' en lugar de 'cudaHostAllocDefault' al asignar. De esta forma, puede acceder a la memoria del host directamente desde los kernels C de CUDA. Esto se conoce como 'memoria de copia cero '. La memoria fija también es como una espada de doble filo, la computadora que ejecuta la aplicación necesita tener memoria física disponible para cada búfer bloqueado en la página, ya que estos búferes nunca se pueden intercambiar al disco, pero esto lleva a que se agote la memoria. – BugShotGG

Respuesta

1

El uso de la memoria del host sería órdenes de magnitud más lenta que la memoria en el dispositivo. Tiene muy alta latencia y muy rendimiento limitado. Por ejemplo la capacidad de PCIe x16 es mera 8 GB/s, cuando el ancho de banda de memoria de dispositivo GTX460 es ni la Guía de programación CUDA C 108 GB/s

1

, ni la Guía CUDA Buenas Prácticas mencionar que la cantidad asignada por cudaMallocHost puede 't ser más grande que la memoria del dispositivo, así que concluyo que es posible.

Las transferencias de datos de la memoria bloqueada de la página al dispositivo son más rápidas que las transferencias de datos normales y aún más rápidas si se utiliza la memoria combinada de escritura. Además, la memoria asignada de esta manera se puede mapear en el espacio de memoria del dispositivo eliminando la necesidad de copiar (manualmente) los datos en total. Sucede automáticamente a medida que se necesitan los datos, por lo que debería poder procesar más datos de los que caben en la memoria del dispositivo.

Sin embargo, el rendimiento del sistema (del host) puede sufrir mucho, si la cantidad de bloqueo de página constituye una parte importante de la memoria del host.

Entonces, ¿cuándo usar esta técnica ?, simple: si los datos necesitan ser solo lectura una vez y escritos solo una vez, úselos. Obtendrá una ganancia de rendimiento, ya que uno tendría que copiar datos de ida y vuelta en algún punto de todos modos. Pero tan pronto como surge la necesidad de almacenar resultados intermedios, que no encajan en los registros o la memoria compartida, procesa trozos de sus datos que se ajustan a la memoria del dispositivo con cudaMalloc.

0
  1. Sí, puedes cudaMallocPerder más espacio que en el gpu.
  2. La memoria fija puede tener mayor ancho de banda, pero puede disminuir el rendimiento del host. Es muy fácil cambiar entre la memoria de host normal, la memoria fija, la memoria de escritura combinada e incluso la memoria mapeada (copia cero). ¿Por qué no usa primero la memoria de host normal y compara el rendimiento?
  3. Sí, su escenario de uso debería funcionar.

Tenga en cuenta que el acceso a la memoria global del dispositivo es lento y el acceso a la memoria del host de copia cero es aún más lento. Que la copia cero sea adecuada para usted depende completamente de cómo use la memoria.

5

La transferencia de memoria es un factor importante cuando se trata del rendimiento de las aplicaciones CUDA. cudaMallocHost puede hacer dos cosas:

  • cubrió a asignar memoria: esta es la página de bloqueo de la memoria del host que el tiempo de ejecución de CUDA puede realizar un seguimiento. Si la memoria del host asignada de esta manera está involucrada en cudaMemcpy como origen o destino, el tiempo de ejecución de CUDA podrá realizar una transferencia de memoria optimizada.
  • asignar memoria mapeada: esta es también la memoria de página bloqueada que se puede utilizar en el código del kernel directamente, ya que se asigna al espacio de direcciones CUDA. Para hacer esto, debe establecer el indicador cudaDeviceMapHost usando cudaSetDeviceFlags antes de usar cualquier otra función CUDA. El tamaño de la memoria de la GPU no limita el tamaño de la memoria de host asignada.

No estoy seguro del rendimiento de esta última técnica. Podría permitirle superponer el cálculo y la comunicación muy bien.

Si accede a la memoria en bloques dentro de su kernel (es decir, no necesita todos los datos sino solo una sección) puede usar un método de buffer múltiple utilizando transferencias de memoria asíncronas con cudaMemcpyAsync al tener múltiples búferes en el GPU: calcule en un búfer, transfiera un búfer al host y transfiera un búfer al dispositivo al mismo tiempo.

Creo que sus afirmaciones sobre el escenario de uso son correctas al usar el tipo de asignación cudaDeviceMapHost. No tiene que hacer una copia explícita, pero ciertamente habrá una copia implícita que no verá. Existe la posibilidad de que se superpone muy bien con su cálculo. Tenga en cuenta que es posible que necesite sincronizar la llamada del kernel para asegurarse de que el kernel finalizó y que tiene el contenido modificado en h_p.

0

Considere también el uso de flujos para la superposición de transferencia de datos/ejecución del kernel. Esto proporciona trabajo de GPU en trozos de datos

Cuestiones relacionadas