c# - API CUDA Driver vs. tiempo de ejecución CUDA
c++ gpgpu (4)
El tiempo de ejecución de CUDA hace posible compilar y vincular los kernels de CUDA en ejecutables. Esto significa que no tiene que distribuir archivos cubin con su aplicación, o tratar de cargarlos a través de la API del controlador. Como ya habrás notado, generalmente es más fácil de usar.
Por el contrario, la API del controlador es más difícil de programar pero proporciona más control sobre cómo se usa CUDA. El programador tiene que lidiar directamente con la inicialización, la carga del módulo, etc.
Al parecer, se puede consultar información más detallada del dispositivo a través de la API del controlador que a través de la API de tiempo de ejecución. Por ejemplo, la memoria gratuita disponible en el dispositivo solo se puede consultar a través de la API del controlador.
De la guía del programador de CUDA:
Está compuesto por dos API:
- Una API de bajo nivel llamada API de controlador CUDA,
- Una API de nivel superior denominada API de tiempo de ejecución de CUDA que se implementa sobre la API del controlador CUDA.
Estas API son mutuamente excluyentes: una aplicación debe usar una u otra.
El tiempo de ejecución de CUDA facilita la administración del código del dispositivo al proporcionar la inicialización implícita, la administración del contexto y la administración del módulo. El código de host C generado por nvcc se basa en el tiempo de ejecución de CUDA (consulte la Sección 4.2.5), por lo que las aplicaciones que se vinculan a este código deben usar la API de tiempo de ejecución de CUDA.
Por el contrario, la API del controlador CUDA requiere más código, es más difícil de programar y depurar, pero ofrece un mejor nivel de control y es independiente del lenguaje, ya que solo trata con objetos cubin (ver Sección 4.2.5). En particular, es más difícil configurar y ejecutar kernels usando la API del controlador CUDA, ya que la configuración de ejecución y los parámetros del kernel deben especificarse con llamadas a funciones explícitas en lugar de la sintaxis de configuración de ejecución descrita en la Sección 4.2.3. Además, la emulación del dispositivo (consulte la Sección 4.5.2.9) no funciona con la API del controlador CUDA.
No hay una diferencia de rendimiento notable entre las API. La forma en que los núcleos usan la memoria y cómo se distribuyen en la GPU (en urdimbres y bloques) tendrá un efecto mucho más pronunciado.
Al escribir aplicaciones CUDA, puede trabajar en el nivel del controlador o en el nivel de ejecución como se ilustra en esta imagen (Las bibliotecas son CUFFT y CUBLAS para matemáticas avanzadas):
Supongo que la compensación entre los dos es un mayor rendimiento para la API de bajo nivel, pero a costa de una mayor complejidad del código. ¿Cuáles son las diferencias concretas y hay cosas importantes que no se pueden hacer con la API de alto nivel?
Estoy usando CUDA.net para la interoperabilidad con C # y está construido como una copia de la API del controlador. Esto alienta a escribir mucho código bastante complejo en C # mientras que el equivalente en C ++ sería más simple usando la API de tiempo de ejecución. ¿Hay algo para ganar al hacerlo de esta manera? El único beneficio que puedo ver es que es más fácil integrar el manejo inteligente de errores con el resto del código C #.
un par de cosas importantes a tener en cuenta:
primero, las diferencias entre las API solo se aplican al código del lado del host. Los granos son exactamente lo mismo. en el lado del host, la complejidad de la API del controlador es bastante trivial, las diferencias fundamentales son:
en la API del controlador tiene acceso a la funcionalidad que no está disponible en los contextos api en tiempo de ejecución.
el emulador solo funciona con el código escrito para la API de tiempo de ejecución.
oh, y actualmente cudpp, que es una biblioteca muy útil, solo funciona con la API de tiempo de ejecución.
Hay algunos problemas reales con la alineación de argumentos y la API del controlador. Consulte la documentación de CUDA 2.2 beta (o posterior) para obtener más información.
Encontré que para el despliegue de bibliotecas en aplicaciones de subprocesos múltiples, el control sobre el contexto CUDA proporcionado por el controlador API era crítico. La mayoría de mis clientes desean integrar la aceleración de la GPU en las aplicaciones existentes, y en la actualidad, casi todas las aplicaciones tienen múltiples subprocesos. Como no podía garantizar que todo el código de la GPU se inicializara, ejecutara y desasignara del mismo hilo, tuve que usar la API del controlador.
Mis intentos iniciales con varias soluciones alternativas en la API de tiempo de ejecución condujeron al fracaso, a veces de manera espectacular. Encontré que podía reiniciar una máquina de forma repetida al realizar el conjunto incorrecto de llamadas CUDA de diferentes hilos.
Como migramos todo a través de la API de controladores, todo ha ido bien.
J