agosto 9, 2020

BitCuco

¡Hola Mundo!

Nvidia Quadro, GeForce y Tesla: Test de rendimiento

nvidia quadro
Tiempo de Lectura5 Minuto(s), 15 Segundo(s)
Anuncio / Advertisement

Nvidia Quadro, Nvidia GeForce y Nvidia Tesla son tarjetas de alto rendimiento que utilizan GPU para hacer sus operaciones básicas, aumentando hasta 1000 veces la capacidad de hacer operaciones con respecto a las tarjetas tradicionales con CPU.

Un protocolo de paralelismo híbrido hace mejor uso de la infraestructura y recursos disponibles para la solución de problemas paralelizables. Éste protocolo hace uso de memoria compartida (OpenMP), memoria distribuida (MPI) y GPU ́s (CUDA) a fin de resolver en menor tiempo éste tipo de tareas.

A fin de mejorar el rendimiento en la comunicación entre los cores y la tarjeta CUDA se ha provisto de un core (núcleo) que es el que tiene acceso inmediato al bus de PCI-express y por lo tanto realiza las operaciones de subida y bajada en un tiempo inferior que el resto de núcleos. Para saber de que core se trata, se hacen pruebas de profiling (análisis de rendimiento) y de éste modo el tiempo de subida y bajada de datos utilizando éste core optimiza el desempeño del problema, sobre todo al tratarse de problemas de complejidad superior a la polinomial.

nvidia geforce

¿Cómo identificar el core más veloz?

A fin de identificar el núcleo más veloz de la tarjeta, recurrimos al tomado de tiempo utilizando eventos de CUDA, cuya documentación expícita se encuentra en http://devblogs.nvidia.com/parallelforall/how-implement-performance-metrics-cuda-cc/

Esto se debe a que necesitamos puntos de sincronización entre el device y el host, los cuáles se encuentran en el pipeline del GPU. En ellos se pueden crear, grabar, destruir eventos, etc. y de éste modo podemos calcular el tiempo en milisegundos entre dos eventos.

Anuncio / Advertisement

En particular, para tomar el tiempo de subida, grabamos un evento antes de la copia de datos en memoria del host al device y después de ella grabamos otro evento, el tiempo recorrido es el tiempo que hay entre esos dos eventos. De forma similar lo hacemos con la copia de datos en memoria del device al host.

Con éstos datos podemos calcular el rendimiento de cada core al transmitir información a la tarjeta cuda y así determinar cuál es el que tiene mejor profiling.

nvidia quadro

Desarrollo del algortimo

Para medir el profiling que tiene cada una de las tarjetas (Nvidia Quadro, Nvidia GeForce y Nvidia Tesla), creamos una función que se va a ejecutar en el kernel de cada una de las tarjetas en el lenguaje de programación CUDA.

CUDA es un lenguaje de programación orientado a GPU y permite realizar operaciones paralelas de alto rendimiento en las tarjetas Nvidia Quadro, GeForce y Tesla. Es un lenguaje que utiliza meta-funciones, así como eventos específicos para ejecutarse para cada Core.

En particular se realizó una función que hace el producto de un escalar por la matriz subida a la tarjeta:

//Tiempos de subida y bajada
float tsub, tbaj;
float subidacore[3], bajadacore[3];
Anuncio / Advertisement
__global__ void kernelescalarVectores(double *a, int n) {
int i = threadIdx.x + blockIdx.x*blockDim.x;
int escalar=10;
while (i<n) {
a[i] = a[i]*escalar; i+=blockDim.x*gridDim.x;
}
}

Posteriormente creamos la función que va a invocar el kernel para ejecutarse en cada una de las tarjetas Nvidia Quadro, Nvidia GeForce y Nvidia Tesla respectivamente al hacer uso del lenguaje CUDA. Ésta función es invocada por cada uno de los procesos MPI que inician a través de la función principal (vista más adelante).

En ella se crean 4 eventos (iniciosubida, altosubida, iniciobajada, altobajada) para tomar los tiempos de subida y bajada de datos a fin de medir el profiling de la tarjeta. Antes y después de la subida y bajada de datos a la tarjeta grabamos un evento y tomamos esos tiempos en cada una de las tarjetas:

void escalarVectoresEnDevice(double a[], int n,int dispositivo) {
double *aD;
int size=N*sizeof(double);
cudaEvent_t iniciosubida, altosubida,iniciobajada,altobajada;
cudaSetDevice(dispositivo);
cudaEventCreate(&iniciosubida);
cudaEventCreate(&altosubida);
cudaEventCreate(&iniciobajada);
cudaEventCreate(&altobajada);
cudaMalloc(&aD, size); cudaEventRecord(iniciosubida, 0);
cudaEventSynchronize(iniciosubida);
cudaMemcpy(aD, a, size, cudaMemcpyHostToDevice);
cudaEventRecord(altosubida, 0);
cudaEventSynchronize(altosubida);
kernelescalarVectores<<<4096,4096>>>(aD, n); cudaEventRecord(iniciobajada, 0);
cudaEventSynchronize(iniciobajada);
cudaMemcpy(a, aD, size, cudaMemcpyDeviceToHost);
cudaEventRecord(altobajada, 0);
cudaEventSynchronize(altobajada);
cudaEventElapsedTime(&tsub, iniciosubida, altosubida);
cudaEventElapsedTime(&tbaj, iniciobajada, altobajada);
cudaEventDestroy(iniciosubida);
cudaEventDestroy(altosubida);
cudaEventDestroy(iniciobajada);
cudaEventDestroy(altobajada);
cudaFree(aD);
}

Dentro de la función principal tomamos las características de cada tarjeta CUDA así como la invocación de la función medidora de profiling. La ventaja de usar MPI es que la asignación del kernel para cada core es dividida por el mismo mpi. Éstas funciones las mandamos que envíen sus tiempos de subida y bajada de modo que se calcula cuál es el mejor profiling en cada caso por una simple comparación al recorrer ese arreglo.

Anuncio / Advertisement
nvidia geforce

¿Nvidia Quadro, Nvidia Geforce o Nvidia Tesla?

Los resultados de mejor comunicación entre los cores de cada socket y cada una de las tarjetas (de modo que se tiene el control de ésta) son los siguientes:

Mejores cores por tarjeta

Tarjeta Nvidia Tesla C2070 Mejor core: 4 Tiempo = 0.202096

Tarjeta Nvidia GeForce GTX 460 Mejor core: 11
Tiempo = 0.197680

Tarjeta Nvidia Quadro K2000 Mejor core: 10 Tiempo = 0.195536

En un próximo artículo mostraremos como recorrer un array con MPI.

Usos de las tarjetas Nvidia Quadro, GeForce y Tesla

Toda aplicación paralela que sea independiente de un proceso de sincronización, es factible de realizarla por medio de GPU, algunos ejemplos de aplicaciones factibles de realizarse por medio de cómputo paralelo son las siguientes:

Aplicaciones de Realidad Virtual: Muchos de los procedimientos utilizados en el motor de renderizado se pueden hacer en paralelo, mejorando los gráficos y adquiriendo un rendimiento superior.

Aplicaciones de Machine Learning: El aprendizaje máquina en base al conocimiento humano, simula rutinas humanas de aprendizaje, aptas para su desarrollo utilizando cómputo paralelo.

Problemas clásicos de la programación: Productor Consumidor y Problema del barbero durmiente. Éstos problemas funcionan para sincronizar tareas paralelas en una aplicación real mixta, en donde la tarea paralela se realiza con GPU y la sincronización utiliza OpenMP, así los GPU se pueden utilizar en aplicaciones de uso común, siempre y cuando se cuente con una tarjeta de Nvidia.

Anuncio / Advertisement
Anuncio / Advertisement
0 0

Sobre el Autor

BitCuco

BitCuco. El Blog para los desarrolladores emergentes.