我在Google上搜索了一个提供一些简单的OpenMp算法的页面。也许有一个示例可以从庞大的数据数组中计算最小值,最大值,中位数,平均值,但我找不到它。
至少我通常会尝试将每个核心的阵列分成一个块,然后再进行一些边界计算,以获得完整阵列的结果。
我只是不想重新发明轮子。
补充说明:我知道有成千上万个可以简单简化的示例。例如计算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;
但是,当这些算法无法使用时,几乎没有可简化算法的例子。
OpenMP(至少2.0)支持某些简单操作的缩减,但不支持max和min。
在下面的示例中,该reduction子句用于求和,而一个critical节用于使用线程局部变量无冲突地更新共享变量。
reduction
critical
#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; }
编辑:一个更清洁的实现:
#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; }