скалярное произведение комплексных векторов с openMP - PullRequest
2 голосов
/ 06 июня 2011

Я использую версию 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;
}

Очевидно, что этот код не ускоряет проблему, а замедляет ее. Есть ли у вас быстрое решение без использования redu () для сложных аргументов?

Ответы [ 3 ]

4 голосов
/ 06 июня 2011

Каждый поток может вычислить частную сумму в качестве первого шага, а в качестве второго шага он может быть составлен в конечную сумму.В этом случае критический раздел необходим только на последнем этапе.

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 голос
/ 06 июня 2011

Попробуйте выполнить умножения параллельно, затем последовательно суммируйте их:

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 (тусклая) рабочая память.

0 голосов
/ 06 июня 2011

Почему бы N потокам не вычислить N отдельных сумм.Затем в конце вам нужно только сложить N сумм, что можно сделать последовательно, так как N довольно мало.Хотя в настоящее время я не знаю, как этого добиться с помощью OpenMP (у меня нет с этим никакого опыта), я вполне уверен, что это легко достижимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...