簡體   English   中英

在矩陣向量乘法中使用 OpenMP“for simd”?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM