Java parallel programming to calculate PI using Dart algorithm
程序员文章站
2022-04-01 17:21:54
...
study it, I don’t want to explain too much about these code segment. Starting from :
public class TestDartThread
at the end of this article.
you can change long num_trails = 1000000000 to make it shorter according to your hardware.
public class MyTimer {
private static long begin;
public static void time_start(){
begin = System.nanoTime();
}
public static double time_end_milli_seconds(){
return System.nanoTime()-begin/1e6;
}
public static double time_end_seconds(){
double total_time = (System.nanoTime()-begin)/1e6;
return ((double)((int)total_time))/1000;
}
}
public class DartThread extends Thread{
public long hitting_times=0;
public long begin_index=0;
public long numtrials=0;
public DartThread(long begin_index,long numtrials) {
this.begin_index = begin_index;
this.numtrials = numtrials;
}
@Override
public void run() {
hit_point();
}
// radius = 1
public boolean hit_in_circle(double x,double y){
return (x*x+y*y)<=1?true:false;
}
// Evaluate ( ax+c ) mod m
long modlin(long a, long x, long c, long m)
{
return (a * x + c) % m;
}
// Put integer n in range x1 , x2 with the maximum integer value
double rescale(long N, long n, double x1, double x2)
{
double f = Double.valueOf(n)/Double.valueOf(N);
return x1 + f * (x2 - x1);
}
public void hit_point() {
// For the s e q u e n t i a l random number generator
long a = 1664525;
long c = 1013904223;
long m = 4294967296L;
long sidelen = 65536;
// s q r t of m
// long numtrials = 1000000;
long i_prev = 12345; // Seed value
for (long n = begin_index; n < numtrials; n+=4) {
long i_next = modlin(a, i_prev, c, m);
i_prev = i_next;
// Scale the random number to a random 2−d position
long ix = i_next % sidelen;
long iy = i_next / sidelen;
// Scale current random integer to value from 0−1
double x = rescale(sidelen, ix, -1, 1);
double y = rescale(sidelen, iy, -1, 1);
// Now we have an (x , y) pair generated from a s i n g l e random integer
if (hit_in_circle(x, y)) {
hitting_times++;
}
}
}
}
public class TestDartThread {
// radius = 1
public static boolean hit_in_circle(double x,double y){
return (x*x+y*y)<=1?true:false;
}
// Evaluate ( ax+c ) mod m
static long modlin(long a, long x, long c, long m)
{
return (a * x + c) % m;
}
// Put integer n in range x1 , x2 with the maximum integer value
static double rescale(long N, long n, double x1, double x2)
{
double f = Double.valueOf(n)/Double.valueOf(N);
return x1 + f * (x2 - x1);
}
public static double parallel(long num_trails) throws InterruptedException {
MyTimer.time_start();
long hitting_times_result = 0;
DartThread thread1 = new DartThread(1,num_trails);
thread1.start();
DartThread thread2 = new DartThread(2,num_trails);
thread2.start();
DartThread thread3 = new DartThread(3,num_trails);
thread3.start();
DartThread thread4 = new DartThread(4,num_trails);
thread4.start();
thread1.join();
thread2.join();
thread3.join();
thread4.join();
hitting_times_result += thread1.hitting_times + thread2.hitting_times + thread3.hitting_times+ thread4.hitting_times;
double time_end = MyTimer.time_end_seconds();
//System.out.println("parallel time elapse: "+ time_end);
System.out.println("parallel time elapse: "+ time_end+"s parallel hitting times: "+hitting_times_result);
double pi = 4*(Double.valueOf(hitting_times_result)/Double.valueOf(num_trails));
System.out.println("parallel PI : "+pi);
return time_end;
}
public static double sequential(long numtrials){
MyTimer.time_start();
// For the s e q u e n t i a l random number generator
long a = 1664525;
long c = 1013904223;
long m = 4294967296L;
long sidelen = 65536;
long hit_times = 0;
// s q r t of m
// long numtrials = 1000000;
long i_prev = 12345; // Seed value
for (long n = 0; n < numtrials; ++n) {
long i_next = modlin(a, i_prev, c, m);
i_prev = i_next;
// Scale the random number to a random 2−d position
long ix = i_next % sidelen;
long iy = i_next / sidelen;
// Scale current random integer to value from 0−1
double x = rescale(sidelen, ix, -1, 1);
double y = rescale(sidelen, iy, -1, 1);
// Now we have an (x , y) pair generated from a s i n g l e random integer
if(hit_in_circle(x,y))
{
hit_times++;
}
}
double end_time = MyTimer.time_end_seconds();
System.out.println("sequential time elapse : "+end_time+"s sequential hitting times: "+hit_times);
double pi = 4*(Double.valueOf(hit_times)/Double.valueOf(numtrials));
System.out.println(" sequential PI : "+pi);
return end_time;
}
public static void main(String[] args) throws InterruptedException {
long num_trails = 1000000000;
System.out.println("speed up: "+sequential(num_trails)/parallel(num_trails));
}
}
sequential time elapse : 19.278s sequential hitting times: 785383696
sequential PI : 3.141534784
parallel time elapse: 6.429s parallel hitting times: 785401631
parallel PI : 3.141606524
speed up: 2.998600093327111