我可以计算多线程数的平均值吗?

时间:2018-09-04 11:58:55

标签: c++ multithreading openmp

我在C ++中使用多线程功能。使用n多线程,我有n随机输出。我需要计算代码中多线程输出的平均值。假设对于n=4个线程,代码是

#include <omp.h>
#include <unistd.h>
#include <stdio.h>
#include <random>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <array>
#include <eigen3/Eigen/Dense>

#define         W               1.0
#define         avg_disorder    10
#define         numThd          4

int main()
{
  #pragma omp parallel num_threads(numThd)
  {
    // define random numbers
    std::mt19937 rng;                  
    std::uniform_real_distribution <> dist;
    std::random_device r;
    std::array<int,624> seed_data;
    std::generate(seed_data.begin(), seed_data.end(), std::ref(r));
    std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
    rng.seed(seq);

    Eigen::Array<double, -1, 1> rp; // rp= random potential
    rp  = Eigen::Array<double, -1, 1>::Zero(avg_disorder, 1);

    //List of 10 random numbers
    for(int avr = 0; avr < avg_disorder; avr++ )
    {
      rp(avr,0) = 0.5* W* (-1 + 2* dist(rng) );
    }
    // output: the mean of the rp
    #pragma omp critical
    { 
      FILE *output;
      char name[50];
      sprintf(name, "avgW%06.2f.dat", W);    
      output = fopen(name, "a");
      fprintf(output, "%e \n", rp.mean() );
      fclose(output);     
    }

  }

  return 1;
}

// run the file avgThreads
//g++ -std=c++0x -fopenmp -o avgThreads avgThreads.cpp
  

输出:4个线程:4个结果(4个不同的rp平均值)。

1.015983e-01
4.097469e-02
-1.275186e-01
-1.243190e-01
  

我的问题是:

我可以计算代码中输出的多线程的平均值吗?

1 个答案:

答案 0 :(得分:5)

您可以尝试这样的事情

#include <omp.h>
#include <stdio.h>
#include <random>
#include <iostream>
#include <cmath>
#include <iomanip>
#include <array>
#include <Eigen/Dense>

#define         W          1.0
#define    avg_disorder    10
#define     numThd          4

int main()
{
    double average = 0.0;
#pragma omp parallel num_threads(numThd) reduction(+ : average)  
{
    // define random numbers
    std::mt19937 rng;
    std::uniform_real_distribution <> dist;
    std::random_device r;
    std::array<int, 624> seed_data;
    std::generate(seed_data.begin(), seed_data.end(), std::ref(r));
    std::seed_seq seq(std::begin(seed_data), std::end(seed_data));
    rng.seed(seq);

    Eigen::Array<double, -1, 1> rp; // rp= random potential
    rp = Eigen::Array<double, -1, 1>::Zero(avg_disorder, 1);

    //List of 10 random numbers
    for (int avr = 0; avr < avg_disorder; avr++)
    {
        rp(avr, 0) = 0.5* W* (-1 + 2 * dist(rng));
    }
    average += rp.mean();
    // output: the mean of the rp
#pragma omp critical
 {
     cout << rp.mean() << endl;
     //FILE *output;
     //char name[50];
     //sprintf(name, "avgW%06.2f.dat", W);
     //output = fopen(name, "a");
     //fprintf(output, "%e \n", rp.mean());
     //fclose(output);
 }

}
cout << average / (double) numThd << endl;
return 1;
}

它使用omp减少功能。

针对一般目的(假设您不知道使用的线程数)

double operation();
double averaged_operation()
{
    double average = 0.0, count_threads=0.0;
    #pragma omp parallel reduction(+ : average, count_threads)  
    {
        average += operation();
        count_threads += 1.0;
    }
    return  average / count_threads;
}