在BLAS中,元素级向量-向量乘法是什么?

19

是否有一种使用BLAS、GSL或其他高性能库进行矢量-矢量逐元素相乘的方法?

4个回答

18

(如果从问题的标题字面上理解...)

是的,可以仅使用BLAS来完成这项任务(尽管这可能不是最有效的方法)。

诀窍是将其中一个输入向量视为对角矩阵:

⎡a    ⎤ ⎡x⎤    ⎡ax⎤
⎢  b  ⎥ ⎢y⎥ =  ⎢by⎥
⎣    c⎦ ⎣z⎦    ⎣cz⎦
你可以使用可以接受对角矩阵输入而无需填充的矩阵-向量乘法函数之一,例如 SBMV 示例:
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;
}

结果:[1.000000 30.000000 500.000000]


6
我知道现在已经很晚了,但我想说一下,尽管finnw的答案是正确的,但我可能不建议使用它。在我的实际情况中,自己编写循环要快得多(2-3倍)。我不知道我的编译器有多么优化,但通常转换为BLAS会产生良好的加速效果(例如在另一个方向上加速2-3倍),而不是变慢。当然,这取决于几个因素,但只是一个提醒:计算时间很重要。 - oli
1
我可以确认@oli的发现。对于我来说,当N = 300时,ssbmv比两个嵌套的for循环慢了约20倍。我正在使用Intel Xeon X7560、OpenBLAS和GCC 8.3.0,并使用-O2 -fPIC -fstack-protector-strong选项。我猜测sbmv太过于通用,无法充分利用向量化指令。 - Witiko

12

我发现MKL在其矢量数学函数库(VML)中有一整套的矢量数学运算,其中包括v?Mul,可以完成我所需的功能。它适用于C ++数组,因此对我来说比GSL更方便。


9

始终可以使用 std::valarray1,它定义了经常被编译成 SIMD 指令的逐元素操作(如果目标支持)(Intel C++ /Quse-intel-optimized-headers, G++)。

这两个编译器也会进行自动向量化。 在这种情况下,您可以只需编写以下内容:

#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]; 
} 

我希望您能将其编译成矢量化代码(例如使用SSE4),内容涉及编程。您需要修改内容以使其更加通俗易懂,但保留HTML标签。请注意,这些技术虽然已被认为是过时的和陈旧的,但在实践中它们仍然是标准的且非常适合该任务。


似乎你的第一个链接已经失效。 - Bracula

5
在GSL中,gsl_vector_mul可以解决这个问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接