是否有一种使用BLAS、GSL或其他高性能库进行矢量-矢量逐元素相乘的方法?
(如果从问题的标题字面上理解...)
是的,可以仅使用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]
我发现MKL在其矢量数学函数库(VML)中有一整套的矢量数学运算,其中包括v?Mul,可以完成我所需的功能。它适用于C ++数组,因此对我来说比GSL更方便。
始终可以使用 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标签。请注意,这些技术虽然已被认为是过时的和陈旧的,但在实践中它们仍然是标准的且非常适合该任务。
gsl_vector_mul
可以解决这个问题。
-O2 -fPIC -fstack-protector-strong
选项。我猜测sbmv太过于通用,无法充分利用向量化指令。 - Witiko