Thank you for your help.
Currently, we are using OpenMP for parallelization to speed up Monte Carlo method, but compared to when OpenMP was used and when it was not used, the execution speed was a little faster, and on the contrary, the accuracy of the results was poor.
What is the cause of this?Please let me know if you understand.Thank you for your cooperation.
The following program uses the Monte Carlo method to find the circumference.
[Results]
·Without openMP
3.141556216 120948
·With openMP (run multiple times with the same code)
3.102521972 103864
3.104310832 108247
3.106061276 109388
[Executive Environment]
g++ (not clang but GNU)
The CPU is a two-core, four-threaded processor.
#include<iostream>
# include <random>
# include <chrono>
# include <iomanip>
# Include <omp.h>// Comment out when not using openMP
using namespace std;
const long int N = 1'000'000'000;
random_device seed_gen;
std::mt19937 engine(seed_gen());
std::uniform_real_distribution<double>dist(0.0,1.0);
int main (void)
{
double x, y, val = 0.0;
long int count = 0;
chrono::system_clock::time_point start, end;
start=chrono::system_clock::now();
# pragma omp parallel for reduction (+:count) // Same
for (long int loop=0;loop<N;++loop)
{
x = dist(engine);
y = dist(engine);
if(x*x+y*y<=1.) count++;
}
end=std::chrono::system_clock::now();
double-elapped=std:chrono::duration_cast<std:chrono::milliseconds>(end-start).count();
val=4*double(count)/N;
cout<<setprecision(10)<<val<<"<elapped<<endl;
return 0;
}
I have almost the same problem as parallelizing pseudo-random number generation (Mersenne Twister).
See the random number engine
in the OpenMP parallel loop.I don't think multi-threaded is safe.At best, the same random number is obtained between threads, and the accuracy is reduced to about one thread.In other words, only N/8
times of execution is meaningful if it is 8 parallels.In the worst case scenario, the internal state of std::mt19937
may be improperly updated between threads, and may not function as a random number or may be extremely accurate.
By the way, in C and C++ languages, variable declarations should not be enumerated at the beginning of the function in a basic way.In particular, the C++ language is inappropriate because the constructor operates at the declaration point (and is not in the order in which the destructor no longer needs to be executed, but in reverse order of declaration). In this case, the variables x
and y
should be declared in the loop.
#pragmaomp parallel
{
std::mt19937 engine {std::random_device{}()};
std::uniform_real_distribution<double>dist {0.0,1.0};
# pragma op for reduction (+:count)
for(long int loop=0;loop<N;++loop){
auto x = dist(engine);
autoy = dist(engine);
if(x*x+y*y<=1.) count++;
}
}
© 2024 OneMinuteCode. All rights reserved.