2012-09-17 6 views
5

tengo:Mejor o igual: CPU memcpy() vs dispositivo cudaMemcpy() en memoria fija, asignada en CUDA?

    memoria
  • anfitrión que se ha fijado con éxito y mapeado usando cudaHostAlloc(..., cudaHostAllocMapped) o cudaHostRegister(..., cudaHostRegisterMapped);
  • Los punteros del dispositivo se han obtenido usando cudaHostGetDevicePointer(...).

Inicié cudaMemcpy(..., cudaMemcpyDeviceToDevice) en src y dest indicadores de dispositivo que apuntan a dos regiones diferentes de memoria fija + asignada obtenidas mediante la técnica anterior. Todo funciona bien.

Pregunta: ¿Debería continuar haciendo esto o simplemente usar un estilo de CPU tradicional memcpy() ya que todo está en la memoria del sistema de todos modos? ... o son los mismos (es decir, ¿se correlaciona cudaMemcpy con un memcpy recto cuando están fijados tanto src como dest)?

(Sigo usando el método cudaMemcpy porque antes todo estaba en su dispositivo de memoria global, pero desde entonces han cambiado a la memoria fijada debido a las limitaciones de tamaño GMEM)

+1

es una pregunta interesante. Siempre que use una memcpy optimizada, la CPU es probablemente mejor, la memoria le pertenece, después de todo, y la capacidad discreta de una GPU de hacer host> host memcpy está limitada al ancho de banda PCIe. Pero si la GPU estaría inactiva de lo contrario, ¿por qué no? – ArchaeaSoftware

+0

Espero que la GPU no esté haciendo la copia. Espero que el tiempo de ejecución vea que los punteros son punteros de host e invocan un memcpy de host. He pedido averiguar qué sucede en realidad. – harrism

Respuesta

3

Con cudaMemcpy, el controlador CUDA detecta que está copiando desde un puntero de host a un puntero de host y la copia se realiza en la CPU. Por supuesto, puede usar memcpy en la CPU si lo prefiere.

Si usa cudaMemcpy, puede haber una sincronización de flujo adicional realizada antes de hacer la copia (que puede ver en el generador de perfiles, pero supongo que hay — prueba y ver).

En un sistema UVA puedes simplemente usar cudaMemcpyDefault como dice talonmies en su respuesta. Pero si no tiene UVA (sm_20 + y SO de 64 bits), debe llamar a la copia correcta (por ejemplo, cudaMemcpyDeviceToDevice). Si cudaHostRegister() todo lo que le interesa a continuación cudaMemcpyDeviceToDevice va a terminar haciendo lo siguiente dependiendo de la donde se encuentra la memoria:

  • anfitrión < -> Host: realizado por la CPU (memcpy)
  • anfitrión < - > dispositivo: DMA (motor de la copia del dispositivo)
  • < dispositivo -> dispositivo: establecimiento de memoria del kernel CUDA (carreras en el SMS, puesto en marcha por el conductor)
+0

muy interesante, ¿tiene alguna fuente donde encontró las informaciones? –

+0

Creo que les pedí a mis colegas de NVIDIA los detalles de implementación. – harrism

2

Si está trabajando en una plataforma con UVA (unificada direccionamiento virtual), le sugiero que use cudaMemcpy con cudaMemcpyDefault. De esta forma, toda esta guía sobre la ruta más rápida se convierte en un detalle interno de implementación API del que no tiene que preocuparse.

+0

Sí y no, a menudo trabajo en un C1060, pero tengo acceso a C2050/70. Entonces, ¿qué pasa con respecto a mi pregunta de memoria fija específicamente - ¿sabes lo que 'cudaMemcpyDefault' hace detrás de las escenas en este caso?Eso respondería bastante a la pregunta. – schmichael

+0

No trabajo.Para NVIDIA, entonces no he visto ningún código, pero parece ver los punteros de origen y de destino y en consecuencia. Obtendrá una copia del lado del servidor con un puntero de host y una copia de dispositivo a dispositivo con un puntero de dispositivo – talonmies