[英]Using OpenMP "for simd" in matrix-vector multiplication?
我目前正在嘗試通過將#pragma omp for
與#pragma omp simd
相結合,使我的矩陣向量乘法 function 與 BLAS 相比具有優勢,但與僅使用 for 構造相比,它並沒有得到任何加速改進。 如何使用 OpenMP 的 SIMD 構造正確矢量化內部循環?
vector dot(const matrix& A, const vector& x)
{
assert(A.shape(1) == x.size());
vector y = xt::zeros<double>({A.shape(0)});
int i, j;
#pragma omp parallel shared(A, x, y) private(i, j)
{
#pragma omp for // schedule(static)
for (i = 0; i < y.size(); i++) { // row major
#pragma omp simd
for (j = 0; j < x.size(); j++) {
y(i) += A(i, j) * x(j);
}
}
}
return y;
}
您的指令不正確,因為會引入競爭條件(在y(i)
上)。 在這種情況下,您應該使用減少。 這是一個例子:
vector dot(const matrix& A, const vector& x)
{
assert(A.shape(1) == x.size());
vector y = xt::zeros<double>({A.shape(0)});
int i, j;
#pragma omp parallel shared(A, x, y) private(i, j)
{
#pragma omp for // schedule(static)
for (i = 0; i < y.size(); i++) { // row major
decltype(y(0)) sum = 0;
#pragma omp simd reduction(+:sum)
for (j = 0; j < x.size(); j++) {
sum += A(i, j) * x(j);
}
y(i) += sum;
}
}
return y;
}
請注意,可能不需要更快,因為某些編譯器能夠自動矢量化代碼(例如 ICC)。 GCC 和 Clang 經常無法自動執行(高級)SIMD 縮減,這樣的指令對他們有所幫助。 您可以檢查匯編代碼以檢查代碼是如何矢量化的或啟用矢量化報告(有關 GCC,請參見此處)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.