OpenMP的C ++算法,最小值,最大值,中位数,平均 [英] OpenMp C++ algorithms for min, max, median, average

查看:1761
本文介绍了OpenMP的C ++算法,最小值,最大值,中位数,平均的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在谷歌搜索页面提供了一些简单的OpenMP算法。 也许有一个例子来计算最小,最大,中位数,平均从庞大的数据阵列,但我不能找到它。

I was searching Google for a page offering some simple OpenMp algorithms. Probably there is an example to calculate min, max, median, average from a huge data array but I am not capable to find it.

至少我通常会试图分裂阵列成一大块每个核心,并做一些边界的计算后得到的结果为完整的数组。

At least I would normally try to divide the array into one chunk for each core and do some boundary calculation afterwards to get the result for the complete array.

我只是不想重新发明轮子。

I just didn't want to reinvent the wheel.


附加备注: 我知道,有数以千计的简单减排工作的例子。 例如计算圆周率。

Additional Remark: I know that there are thousands of examples that work with simple reduction. e.g. Calculating PI.

const int num_steps = 100000; 
double x, sum = 0.0; 
const double step = 1.0/double(num_steps); 
#pragma omp parallel for reduction(+:sum) private(x) 
for (int i=1;i<= num_steps; i++){ 
  x = double(i-0.5)*step; 
  sum += 4.0/(1.0+x*x); 
} 
const double pi = step * sum;

但是,当这些类型的算法是不可用有左为降低算法几乎没有例子。

but when these kind of algorithms aren't usable there are almost no examples left for reducing algorithms.

推荐答案

OpenMP的(至少2.0)支持减少对于一些简单的操作,但不为最大值和最小值。

OpenMP (at least 2.0) supports reduction for some simple operations, but not for max and min.

在下面的例子中还原子句用来做一笔和关键部分用于更新使用线程局部一个没有冲突的共享变量。

In the following example the reduction clause is used to make a sum and a critical section is used to update a shared variable using a thread-local one without conflicts.

#include <iostream>
#include <cmath>

int main()
{
  double sum = 0;
  uint64_t ii;
  uint64_t maxii = 0;
  uint64_t maxii_shared = 0;
#pragma omp parallel shared(maxii_shared) private(ii) firstprivate(maxii)
  {
#pragma omp for reduction(+:sum) nowait
    for(ii=0; ii<10000000000; ++ii)
      {
        sum += std::pow((double)ii, 2.0);
        if(ii > maxii) maxii = ii;
      }
#pragma omp critical 
    {
      if(maxii > maxii_shared) maxii_shared = maxii;
    }
  }
  std::cerr << "Sum: " << sum << " (" << maxii_shared << ")" << std::endl;
}

编辑:实现更简洁:

a cleaner implementation:

#include <cmath>
#include <limits>
#include <vector>
#include <iostream>
#include <algorithm>
#include <tr1/random>

// sum the elements of v
double sum(const std::vector<double>& v)
{
  double sum = 0.0;
#pragma omp parallel for reduction(+:sum)
  for(size_t ii=0; ii< v.size(); ++ii)
    {
      sum += v[ii];
    }
  return sum;
}

// extract the minimum of v
double min(const std::vector<double>& v)
{
  double shared_min;
#pragma omp parallel 
  {
    double min = std::numeric_limits<double>::max();
#pragma omp for nowait
    for(size_t ii=0; ii<v.size(); ++ii)
      {
        min = std::min(v[ii], min);
      }
#pragma omp critical 
    {
      shared_min = std::min(shared_min, min);
    }
  }
  return shared_min;
}

// generate a random vector and use sum and min functions.
int main()
{
  using namespace std;
  using namespace std::tr1;

  std::tr1::mt19937 engine(time(0));
  std::tr1::uniform_real<> unigen(-1000.0,1000.0);
  std::tr1::variate_generator<std::tr1::mt19937, 
    std::tr1::uniform_real<> >gen(engine, unigen);

  std::vector<double> random(1000000);
  std::generate(random.begin(), random.end(), gen);

  cout << "Sum: " << sum(random) << " Mean:" << sum(random)/random.size()
       << " Min:" << min(random) << endl;
}

这篇关于OpenMP的C ++算法,最小值,最大值,中位数,平均的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆