Pregunta Multiplicación simple y rápida de matriz-vector en C / C ++


Necesito el uso frecuente de matrix_vector_mult() que multiplica la matriz con el vector, y abajo está su implementación.

Pregunta: ¿Existe una manera simple de hacerlo significativamente, al menos dos veces más rápido?

Observaciones: 1) El tamaño de la matriz es de aproximadamente 300x50. No cambia durante el correr. 2) Debe funcionar tanto en Windows como en Linux.

double vectors_dot_prod(const double *x, const double *y, int n)
{
    double res = 0.0;
    int i;
    for (i = 0; i < n; i++)
    {
        res += x[i] * y[i];
    }
    return res;
}

void matrix_vector_mult(const double **mat, const double *vec, double *result, int rows, int cols)
{ // in matrix form: result = mat * vec;
    int i;
    for (i = 0; i < rows; i++)
    {
        result[i] = vectors_dot_prod(mat[i], vec, cols);
    }
}

13
2017-09-05 20:27


origen


Respuestas:


Esto es algo que, en teoría, un buen compilador debería hacer por sí mismo; sin embargo, probé con mi sistema (g ++ 4.6.3) y obtuve aproximadamente el doble de velocidad en una matriz de 300x50 desenrollando manualmente 4 multiplicaciones (aproximadamente 18us por matriz en lugar de 34us por matriz):

double vectors_dot_prod2(const double *x, const double *y, int n)
{
    double res = 0.0;
    int i = 0;
    for (; i <= n-4; i+=4)
    {
        res += (x[i] * y[i] +
                x[i+1] * y[i+1] +
                x[i+2] * y[i+2] +
                x[i+3] * y[i+3]);
    }
    for (; i < n; i++)
    {
        res += x[i] * y[i];
    }
    return res;
}

Sin embargo, espero que los resultados de este nivel de micro-optimización varíen enormemente entre sistemas.


16
2017-09-05 20:48



Como dice Zhenya, solo use una buena biblioteca BLAS o de matriz matemática.

Si por alguna razón no puede hacer eso, vea si su compilador puede desenrollar y / o vectorizar sus bucles; asegurándose filas y cols si ambas constantes en el sitio de llamadas pueden ayudar, suponiendo que las funciones que publicó están disponibles para enlining

Si aún no puede obtener la aceleración que necesita, está buscando desenrollar manualmente y vectorizar usando extensiones o ensamblador en línea.


4
2017-09-05 20:49



Si el tamaño es constante y conocido de antemano, páselo como una variable de precompilador, lo que permitirá al compilador optimizar de forma más completa.


0
2017-09-05 20:54