Para los que los métodos estadísticos son GPU más rápido que las CPU?

17

Acabo de instalar una tarjeta gráfica Nvidia GT660 en mi escritorio y, después de una lucha, me las arreglo para interactuar con R.

He estado jugando con varios paquetes de R que las GPU utilizando, especialmente gputools, y yo estaba comparando el tiempo empleado por mi GPU y CPU para realizar algunas operaciones básicas:

  • matrices inversora (CPU más rápido)
  • descomposición QR (CPU más rápida)
  • grandes matrices de correlación (CPU más rápida)
  • la multiplicación de matrices (GPU mucho más rápido!)

Tenga en cuenta que he experimentado principalmente con gputools, por lo que quizás otros paquetes funcionen mejor.

En términos generales, mi pregunta es: ¿cuáles son algunas operaciones estadísticas de rutina que podrían valer la pena ejecutar en una GPU en lugar de una CPU?

jugurtha
fuente
1
Cualquier cosa que implica un montón de multiplicación de matrices? :) Las GPU son bastante populares en la comunidad de redes neuronales.
debe proporcionar el tamaño de las matrices involucradas. Por ejemplo, yo sepa (hace reconocidamente 2 años), la inversión y la descomposición eran sólo es más rápido en la GPU a partir de grandes matrices (2 ^ 2 ^ 9 veces 9 y hacia arriba)
user189035
1
Solía matrices de alrededor de para la inversión, qr y la multiplicación de matrices, mientras que para correlaciones he utilizado alrededor de 10 ^ 4 observaciones de vectores de tamaño 100. Por inversión de la matriz la GPU fue mucho más lento, mientras que para la descomposición QR era más lento pero comparable a la CPU. 103×103
Jugurtha
2
esta es una muy buena pregunta, pero creo que obtendrá mejores respuestas al migrarla a stackoverflow (creo que se han hecho preguntas similares antes)
user189035
2
La ventaja de la GPU de las CPU normales es el hecho de que pueden ser paralelas "masivamente", no que sean más rápidas por núcleo. Como tal, para trabajos que requieren una gran cantidad de "limpieza" como la factorización de Cholesky etc. necesita utilizar algoritmos de bloque y así sucesivamente para obtener significativa aceleración; esto no es trivial y supongo que tomará un tiempo antes de la toma de la GPU más de este tipo de operaciones. Lo que se va definitivamente la forma en la GPU es MCMC-ción (y la generación de números aleatorios). Toma de muestras de una posterior tiene "paralelización" escrito por todas partes ... y matrices dispersas cálculos; ya están "bloqueados" de todos modos ...
usεr11852 dice Reinstate Monic

Respuestas:

6

Las GPU son bestias sensibles. A pesar de que la tarjeta de Nvidia beefiest teóricamente puede ejecutar cualquiera de las operaciones que anotó 100 veces más rápido que la CPU más rápida, alrededor de un millón de cosas pueden interponerse en el camino de ese aumento de velocidad. Cada parte del algoritmo relevante, y del programa que dirige, tiene que ser ampliamente ajustado y optimizado con el fin de llegar a ninguna parte cerca de ese aumento de velocidad máxima teórica. R generalmente no es conocido por ser un lenguaje particularmente rápido, por lo que no me sorprende que su aplicación GPU por defecto no es tan grande, por lo menos en términos de rendimiento bruto. Sin embargo, las funciones de R GPU pueden tener configuraciones de optimización que puede ajustar para recuperar parte del rendimiento que falta.

Si usted está buscando en las GPU porque se ha encontrado que algunos de cálculo que usted necesita para ejecutar va a tomar semanas / meses a fin, puede ser digno de su tiempo para migrar de R a un lenguaje más el rendimiento de usar. Python no es mucho más difícil de trabajar que R. El NumPy y paquetes SciPy tienen la mayor parte de las mismas funciones estadísticas como R y PyCuda se puede utilizar para poner en práctica sus propias funciones basadas en la GPU de una manera bastante sencilla.

Si usted realmente desea aumentar la velocidad a la que sus funciones se ejecutan en las GPU, consideraría la aplicación de sus propias funciones en una combinación de C ++ y CUDA. La biblioteca CUBLAS se puede usar para manejar todo el trabajo pesado relacionado con el álgebra lineal. Sin embargo, tenga en cuenta que puede llevar bastante tiempo escribir dicho código (especialmente si es la primera vez que lo hace), por lo que este enfoque debe reservarse solo para aquellos cálculos que tardan mucho tiempo en ejecutarse (meses) y / o que vas a repetir cientos de veces.

tel
fuente
6

En términos generales, los algoritmos que se ejecutan en la GPU más rápido son aquellos en los que está haciendo el mismo tipo de instrucción sobre muchos puntos de datos diferentes.

Un ejemplo sencillo para ilustrar esto es con la multiplicación de matrices.

Supongamos que estamos haciendo el cálculo de la matriz

UN×si=C

Un algoritmo sencillo CPU podría ser algo como

// empezando con C = 0

for (int i = 0; i < C_Width; i++)
{
    for (int j = 0; j < C_Height; j++)
    {
        for (int k = 0; k < A_Width; k++)
        {
            for (int l = 0; l < B_Height; l++)
            {
                C[j, i] += A[j, k] * B[l, i];
            }
        }
    }
}

La clave para ver aquí es que hay una gran cantidad de bucles for anidados y cada paso deben ser ejecutadas una después de la otra.

Ver un diagrama de esta

Observe que el cálculo de cada elemento de C no depende de ninguno de los otros elementos. Por lo tanto, no importa en qué orden se realicen los cálculos.

Entonces, en la GPU, estas operaciones se pueden realizar simultáneamente.

Un núcleo de GPU para calcular una multiplicación de matriz se vería algo así

__kernel void Multiply
(
    __global float * A,
    __global float * B,
    __global float * C
)
{
     const int x = get_global_id(0);
     const int y = get_global_id(1);
     for (int k = 0; k < A_Width; k++)
     {
         for (int l = 0; l < B_Height; l++)
         {
             C[x, y] += A[x, k] * B[l, y];
         }
     }
}

Este núcleo solo tiene los dos bucles for internos. Un programa de envío de este trabajo a la GPU le dirá la GPU para ejecutar este núcleo para cada punto de datos en C. La GPU va a hacer cada una de estas instrucciones al mismo tiempo en muchos hilos. Al igual que el viejo dicho "Más barato por docena" GPU están diseñados para ser más rápido haciendo lo mismo muchas veces.

Sin embargo, hay algunos algoritmos que se ralentizará la GPU abajo. Algunos no son adecuados para la GPU.

Si, por ejemplo, había dependencias de datos, es decir: imaginar el cálculo de cada elemento de C dependía de los elementos anteriores. El programador tendría que poner una barrera en el kernel que esperar a que cada cálculo anterior a fin. Esto sería una gran desaceleración.

Además, los algoritmos que tienen una gran cantidad de ramificación es decir, la lógica:

__kernel Foo()
{
    if (somecondition)
    {
        do something
    }
    else
    {
        do something completely different
    }
}

tienden a funcionar más lentamente en la GPU porque la GPU ya no está haciendo lo mismo en cada subproceso.

Esta es una explicación simplificada ya que hay muchos otros factores a considerar. Por ejemplo, el envío de datos entre la CPU y la GPU también es mucho tiempo. A veces vale la pena hacer un cálculo en la GPU, incluso cuando su más rápido en la CPU, sólo para evitar el tiempo extra de envío (y viceversa).

También muchos concurrencia de soporte CPU moderna ahora también con los procesadores multinúcleo hyperthreaded.

GPU también parece ser no tan bueno para la recursividad, ver aquí lo que probablemente explica algunos de los problemas con el algoritmo QR. Creo que uno tiene algunas dependencias de datos recursivas.

SAV
fuente
2
Es oficialmente SX-traviesa a comentar una respuesta sólo para decir que se trata de una respuesta excelente, pero no me importa perineo de una rata sobre negs: esta es una respuesta muy agradable e informativo. Una de las grandes injusticias de SX es la falta de felicitaciones a las personas que dan respuestas exquisitamente informativos sobre cuestiones 'viejos' (en tiempo de Internet). (Además, yo estoy dando un pulgar hacia arriba a un 'viejo' (en tiempo de Internet) Respuesta: Yo sé, ¿verdad META?).
GT.
Una consideración importante es si realmente hay una biblioteca para hacer el cálculo: por ejemplo, que yo sepa, no hay implementaciones dispersas x densas de GPU de multiplicación de matrices, ciertamente no a través de paquetes R. Si está preparado para trabajar escribiendo código GPU C, entonces buena suerte.
Jack Wasey
4

norte=210norte,metro210,k214 . Es un todo gran sorpresa para mí que las grandes matrices de correlación sería más rápido en la CPU utilizando R.

En términos más generales, sospecho operaciones más estadísticas que pasan la mayor parte de su tiempo en el álgebra densa (funcionalidad BLAS, Lapack) lineal puede ser implementado de manera eficiente en la GPU.

Max Hutchinson
fuente
0

¿Múltiples métodos de imputación para datos faltantes? Como los de Alice-II (R).

Creo que aquellos tienden a ser a menudo vergonzosamente paralelo y por lo tanto adecuado para una arquitectura de GPU. Aunque nunca lo intenté yo mismo.

curious_cat
fuente