2011-10-01 9 views

Respuesta

5

Encontré que MKL tiene un conjunto completo de operaciones matemáticas en vector, en su Biblioteca de Funciones Matemáticas de Vector (VML), incluyendo v? Mul, que hace lo que quiero. Funciona con matrices de C++, por lo que es más conveniente para mí que GSL.

+0

+1 para MKL per se – sehe

5

En GSL, gsl_vector_mul hace el truco.

6

Siempre hay std :: valarray que define operaciones elementwise que son con frecuencia (Intel C++ /Quse-intel-optimized-headers, G ++) compilado en instrucciones SIMD si el objetivo compatible con ellas.

Ambos compiladores también harán auto-vectorización

En ese caso, puede simplemente escribir

#define N 10000 

float a[N], b[N], c[N]; 

void f1() { 
    for (int i = 1; i < N; i++) 
    c[i] = a[i] + b[i]; 
} 

y vea que compila en código vectorizado (usando SSE4 por ejemplo)

Sí que son arcaicas y, a menudo considerado como obsoleto, pero en la práctica son estándar y se ajustan a la tarea muy bien .

8

(tomando el título de la pregunta literalmente ...)

Sí que se puede hacer con BLAS solos (aunque probablemente no es la forma más eficiente.)

El truco es tratar a uno de los vectores de entrada como una matriz diagonal:

⎡a ⎤ ⎡x⎤ ⎡ax⎤ 
⎢ b ⎥ ⎢y⎥ = ⎢by⎥ 
⎣ c⎦ ⎣z⎦ ⎣cz⎦ 

a continuación, puede utilizar una de las funciones se multiplican matriz-vector que puede tomar una matriz diagonal como entrada sin relleno, por ejemplo, SBMV

Ejemplo:

void ebeMultiply(const int n, const double *a, const double *x, double *y) 
{ 
    extern void dsbmv_(const char *uplo, 
         const int *n, 
         const int *k, 
         const double *alpha, 
         const double *a, 
         const int *lda, 
         const double *x, 
         const int *incx, 
         const double *beta, 
         double *y, 
         const int *incy); 

    static const int k = 0; // Just the diagonal; 0 super-diagonal bands 
    static const double alpha = 1.0; 
    static const int lda = 1; 
    static const int incx = 1; 
    static const double beta = 0.0; 
    static const int incy = 1; 

    dsbmv_("L", &n, &k, &alpha, a, &lda, x, &incx, &beta, y, &incy); 
} 

// Test 
#define N 3 
static const double a[N] = {1,3,5}; 
static const double b[N] = {1,10,100}; 
static double c[N]; 

int main(int argc, char **argv) 
{ 
    ebeMultiply(N, a, b, c); 
    printf("Result: [%f %f %f]\n", c[0], c[1], c[2]); 
    return 0; 
} 

Result: [1.000000 30.000000 500.000000]

+0

esto también se trabajará en matrices? – Matt

+2

Sé que esto es bastante tarde, pero solo quiero decir que aunque esta respuesta de finnw es válida, probablemente no recomiende usarla. En mis casos prácticos, escribir bucles yo mismo era mucho más rápido (2-3 veces). No sé cuánto optimiza mi compilador, pero generalmente cambiar a blas produce una buena aceleración (por ejemplo, 2-3 veces en la otra dirección) en lugar de disminuir la velocidad. Por supuesto, esto depende de varios factores, pero solo como una advertencia para cronometrar los cálculos. – oli