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