具有openMP的复杂向量的点积

时间:2011-06-06 10:02:32

标签: c++ openmp reduce dot-product

我正在使用openMP版本,它不支持复杂参数的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)
# pragma omp for
    for (i=0; i<dim;i++ )
    {
#pragma omp critical
        {
            sum+=std::conj<double>(v1[i])*v2[i];
        }
    }
    return sum;
}

显然,此代码不会加速问题,但会降低速度。如果没有对复杂参数使用reduce(),您是否有快速解决方案?

3 个答案:

答案 0 :(得分:4)

每个线程可以计算私有和作为第一步,作为第二步,它可以组成最终总和。在这种情况下,关键部分仅在最后一步中需要。

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;
}

答案 1 :(得分:1)

尝试并行进行乘法运算,然后对它们进行串行求和:

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(暗淡)工作记忆。

答案 2 :(得分:0)

为什么不让N个线程计算N个单独的总和。然后在结束时你只需要求N个和,这可以连续完成,因为N非常小。虽然我不知道如何使用OpenMP实现这一目标(目前我没有任何经验),但我确信这很容易实现。