簡體   English   中英

復雜向量與openMP的點積

[英]dot product of complex vectors with openMP

我正在使用一個不支持 reduce() 復雜參數的 openMP 版本。 我需要一個快速的點積 function 之類的

std::complex< double > dot_prod( std::complex< double > *v1,std::complex< double > *v2,int dim )

{
    std::complex< double > sum=0.;
    int i;
# pragma omp parallel shared(sum)
# pragma omp for
    for (i=0; i<dim;i++ )
    {
#pragma omp critical
        {
            sum+=std::conj<double>(v1[i])*v2[i];
        }
    }
    return sum;
}

顯然,這段代碼並沒有加快問題的速度,而是減慢了速度。 對於復雜的 arguments,您是否有不使用 reduce() 的快速解決方案?

每個線程可以作為第一步計算私有總和,作為第二步,它可以組合成最終總和。 在這種情況下,僅在最后一步中才需要關鍵部分。

std::complex< double > dot_prod( std::complex< double > *v1,std::complex< double > *v2,int dim )
{
  std::complex< double > sum=0.;
  int i;
  # pragma omp parallel shared(sum)
  {
    std::complex< double > priv_sum = 0.;
    # pragma omp for
    for (i=0; i<dim;i++ )
    {
      priv_sum += std::conj<double>(v1[i])*v2[i];
    }

    #pragma omp critical
    {
      sum += priv_sum;
    }
  }
  return sum;
}

嘗試並行進行乘法運算,然后將它們串行求和:

template <typename T>
std::complex<T> dot_prod(std::complex<T> *a, std::complex<T> *b, size_t dim)
{
    std::vector<std::complex<T> > prod(dim);  // or boost::scoped_array + new[]

    #pragma omp parallel for
    for (size_t i=0; i<dim; i++)
        // I believe you had these reversed
        prod[i] = a[i] * std::conj(b[i]);

    std::complex<T> sum(0);
    for (size_t i=0; i<dim; i++)
        sum += prod[i];

    return sum;
}

當然,這確實需要 O(dim) 工作 memory。

為什么不讓 N 個線程計算 N 個單獨的總和。 然后最后你只需要對 N 個總和進行求和,這可以連續完成,因為 N 非常小。 雖然我不知道如何使用 OpenMP 來實現這一點,但目前(我沒有任何經驗),我很確定這很容易實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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