`

3月14日圆周率日—使用并行计算求圆周率π

阅读更多
关于圆周率大家再熟悉不过了:
我们从课本上学习到早在一千多年前,祖冲之将圆周率计算到3.1415926到3.1415927之间…计算机诞生后,计算圆周率被用来检测计算机的硬件性能,昼夜燃烧cpu看会不会出问题…另外一些人也想看看这个无限延伸的神秘数字背后是否有规律,能发现一些宇宙的秘密…


提起圆周率,不能不提及Fabrice Bellard,他被认为是一位计算机天才,在业界有着重要的影响。1996年他编写了一个简洁但是完整的C编译器和一个Java虚拟机Harissa。Fabrice Bellard发明的TinyCC是GNU/Linux环境下最小的ANSI C语言编译器,是目前号称编译速度最快的C编译器。Fabrice Bellard杰作众多且涉及广泛,1998年编写了一个简洁的OpenGL实现TinyGL,2003年开发了Emacs克隆QEmacs,2005年还设计了一个廉价的数字电视系统。


Fabrice Bellard使用一台普通的台式电脑,完成了冲击由超级计算机保持的圆周率运算记录的壮举,他使用台式机将圆周率计算到了小数点后2.7万亿位,超过了由目前排名世界第47位的T2K Open超级计算机于去年8月份创造的小数点后2.5万亿位的记录。

Bellard使用的电脑是一台基于2.93GHz Core i7处理器的电脑,这部电脑的内存容量是6GB,硬盘则使用的是五块RAID-0配置的1.5TB容量的希捷7200.11,系统运行64位Red Hat Fedora 10操作系统,文件系统则使用Linux的ext4.

这次计算出来的圆周率数据占去了1137GB的硬盘容量,Bellard花了103天的时间计算出了这样的结果。

计算圆周率的方法有很多种:
微积分割圆法求:


或者利用便于计算机计算的丘德诺夫斯基公式法求:


不过这些计算方法都比较复杂,难以让读者理解和使用并行计算来求,所幸数学上的泰勒级数是个好东西,它将微积分的东西改成用无限级数来表示,这样很容易进行并行计算分解:

π=4*∑(-1)^n+1/(2n-1) 或者写为: π=4*( 1-1/3+1/5-1/7+…)
也可以得到:πn =πn-1+(-1)^n+1/(2n-1),也就是可以通过迭代前面的π值去求当前π值。


我们根据上面公式先写个单机程序来求:

public class PiTest
{
	public static void main(String[] args)
	{
		double pi=0.0;
		for(double i=1.0;i<1000000001d;i++){
			pi += Math.pow(-1,i+1)/(2*i-1);
		}
		System.out.println(4*pi);
	}
}


运行以上程序,并对照pi的标准值:3.141592653589793238462643383279…
如果i<10000,得到pi = 3.1416926635905345 (从红色部分以后不精确了)
如果i<1000000,得到pi = 3.1415936535907742 (从红色部分以后不精确了)
如果i<1000000000,得到pi = 3.1415926525880504(从红色部分以后不精确了)
……
可以看到,当迭代的轮数越大,求出的π值越精确。

由于是无限累加,我们可以很容易改成并行程序求解,比如i=4n,可以分成4段并行求解,再将4部分和合并起来得到最终π值。假设我们有4台计算机,并行计算设计如下:


我们这里通过fourinone提供的各种并行计算模式去设计,第一次使用可以参考分布式计算上手demo指南,开发包下载地址:http://code.google.com/p/fourinone/

程序实现:
PiWorker:是一个π计算工人实现,我们可以看到它通过命令行输入一个计算π值的起始值和结束值,我们同时启动4个PiWorker实例,启动时指定不同的起始结束参数。

PiCtor:是一个π计算包工头实现,它的实现很简单,获取到线上工人后,通过doTaskBatch进行阶段计算,等待每个工人计算完成后,将各工人返回的π计算结果合并累加。

运行步骤:
1、启动ParkServerDemo(它的IP端口已经在配置文件指定)
java -cp fourinone.jar; ParkServerDemo


2、运行4个PiWorker,将迭代100,000,000轮的计算拆分到4个工人并行完成,这里方便演示是在同一台机器上,现实应用中可以在多台计算机上完成。
java  -cp fourinone.jar; PiWorker localhost 2008 1 250000000
java  -cp fourinone.jar; PiWorker localhost 2009 250000000 500000000
java  -cp fourinone.jar; PiWorker localhost 2010 500000000 750000000
java  -cp fourinone.jar; PiWorker localhost 2011 750000000 100000000


3、运行PiCtor
java  -cp fourinone.jar; PiCtor


可以看到,4个工人实例在同台机器并行完成计算π值的时间为29秒,如果是运行单机程序PiTest完成的时间在45秒,精准度都是到小数点后8位“3.14159265”,但是耗时上有明显差距,如果多机多实例,效率还会进一步提升,并行计算性能提升分析可以参考“使用并行计算大幅提升递归算法效率”。

完整demo源码如下:
// ParkServerDemo
import com.fourinone.BeanContext;
public class ParkServerDemo
{
	public static void main(String[] args)
	{
		BeanContext.startPark();
	}
}


// PiWorker
import com.fourinone.MigrantWorker;
import com.fourinone.WareHouse;

public class PiWorker extends MigrantWorker
{
	public double m=0.0,n=0.0;
	
	public PiWorker(double m, double n){
		this.m = m;
		this.n = n;
	}
	
	public WareHouse doTask(WareHouse inhouse)
	{
		double pi=0.0;
		for(double i=m;i<n;i++){
			pi += Math.pow(-1,i+1)/(2*i-1);
		}
		
		System.out.println(4*pi);
		inhouse.setObj("pi",4*pi);

		return inhouse;
	}
	
	public static void main(String[] args)
	{
		PiWorker mw = new PiWorker(Double.parseDouble(args[2]),Double.parseDouble(args[3]));
		mw.waitWorking(args[0],Integer.parseInt(args[1]),"PiWorker");
	}
}

// PiCtor
import com.fourinone.Contractor;
import com.fourinone.WareHouse;
import com.fourinone.WorkerLocal;
import java.util.Date;

public class PiCtor extends Contractor
{
	public WareHouse giveTask(WareHouse inhouse)
	{
		WorkerLocal[] wks = getWaitingWorkers("PiWorker");
		System.out.println("wks.length:"+wks.length);
		
		WareHouse[] hmarr = doTaskBatch(wks, inhouse);
		
		double pi=0.0;
		for(WareHouse result:hmarr){
			pi = pi + (Double)result.getObj("pi");
		}
		
		System.out.println("pi:"+pi);
		return inhouse;
	}
	
	public static void main(String[] args)
	{
		PiCtor a = new PiCtor();
		long begin = (new Date()).getTime();
		a.giveTask(new WareHouse());
		long end = (new Date()).getTime();
		System.out.println("time:"+(end-begin)/1000+"s");
		a.exit();
	}
}
  • 大小: 70.3 KB
  • 大小: 86.3 KB
  • 大小: 19.1 KB
  • 大小: 2.1 KB
  • 大小: 32.8 KB
  • 大小: 37.1 KB
  • 大小: 120.2 KB
  • 大小: 55.2 KB
0
0
分享到:
评论
1 楼 dingherry 2013-12-06  
这是件很有意思的事

相关推荐

    C语言串行并行求圆周率π.zip

    这里我们讨论的"C语言串行并行求圆周率π.zip"是一个示例,它包含了两种方法来计算π:串行计算和利用OpenMP进行并行计算。 首先,我们来看"求π串行.cpp"。这个程序使用了一种常见的方法来估计π,如马特洪公式...

    分别用MPI和串行程序计算圆周率

    C++计算圆周率,分别用穿行计算和通过MPI实现的并行计算来进行。并行计算课程实验代码,分别用MPI和串行程序实现圆周率的计算并输出时间

    java并行计算圆周率

    在Java编程语言中,实现并行计算圆周率是一项挑战性的任务,但通过利用多线程和适当的算法,我们可以大大提高计算效率。在这个项目中,我们关注的是如何在4个线程的状态下,3分钟内计算出圆周率的第62到63万位小数。...

    课程项目-基于MPI及蒙特卡洛方法的圆周率并行计算

    ### 课程项目-基于MPI及蒙特卡洛方法的圆周率并行计算 #### 一、项目背景 本项目旨在结合MPI(Message Passing Interface)并行计算框架与蒙特卡洛方法,实现对圆周率π的高效并行计算。MPI作为一种标准的并行编程...

    M.rar_圆周率_蒙特卡洛 并行_蒙特卡洛并行

    例如,压缩包中的"M.txt"文件可能包含了使用并行蒙特卡洛算法计算圆周率的具体实现。可能的程序设计包括以下步骤: 1. **初始化**:设置投掷次数、计算核心数、分配任务。 2. **并行计算**:每个核心独立生成随机...

    计算圆周率的java程序

    - 当需要计算大量位数的π时,可以使用Java的并发工具如`ForkJoinPool`或者`ExecutorService`来并行计算各个部分。这样可以显著减少计算时间,但需要设计合适的分治策略。 5. **代码示例**: 使用`BigInteger`...

    圆周率计算 3000位 pi的计算 VC++ C++代码

    首先,我们要理解圆周率π的定义,它表示一个圆的周长与其直径之比。在数学中,π的近似值为3.14159,但实际值远远复杂得多。要计算到3000位,我们需要使用高级的算法,这些算法能够更有效地逼近π的值。 一种常见...

    圆周率计算(超万位小数).zip

    例如,通过使用蒙特卡洛方法,可以进行并行计算来估计π的值,这种方法虽然不能直接给出精确值,但可以在大量随机试验后得到非常接近的真实值。此外,还可以利用特殊的硬件,如 FPGA(现场可编程门阵列)和 GPU...

    计算圆周率

    标题中的“计算圆周率”指的是利用编程语言C来实现计算π(圆周率)的算法。圆周率是一个无理数,表示圆的周长与其直径之比,通常用希腊字母π表示,其数值约为3.14159。在计算机科学中,有多种方法可以用于近似计算...

    精确的圆周率计算vb

    圆周率(π)是数学中的一个重要常数,它代表一个圆的周长与其直径之比,通常表示为3.14159。在VB中实现圆周率的计算可以让我们理解编程和数学的结合,以及VB的基本编程结构和控制流。 描述中提到的“随机点名程序...

    pi.rar_PI_java 并行计算_并行计算 pi

    在这个“pi.rar_PI_java”压缩包中,包含了一个用Java实现的并行计算实验,目的是通过并行计算来求解π(圆周率)的值。 π的计算通常涉及复杂的数学算法,例如蒙特卡洛方法,这是一种基于概率统计的数值计算方法。...

    计算π 考验你的计算机

    标题“计算π 考验你的计算机”暗示了我们即将探讨的是一个与计算圆周率π相关的程序或算法,这通常涉及到数值计算、数学和计算机性能的测试。π是一个无理数,其值无限不循环,因此计算π的精确值是一项挑战,尤其...

    求圆周率问题的一段程序

    首先,我们了解圆周率π的定义,它是一个常数,约等于3.14159。在数学史上,诸多数学家都尝试过用各种方法来计算π的值。从古老的几何法到现代的计算机算法,这些方法的精度和效率不断提高。随着计算机技术的发展,...

    天津大学并行计算 多线程求pi并进行性能分析

    本实验“天津大学并行计算 多线程求pi并进行性能分析”关注的是如何通过C语言实现多线程来计算圆周率π,并对计算性能进行深入分析。 在C语言中,多线程可以借助POSIX线程库(pthread)来实现。`pi.cpp`文件很可能...

    fpi.rar_MPI并行 Fortran_fortran 并行_并行计算

    在本资源“fpi.rar”中,我们关注的是一个使用MPI(Message Passing Interface)和Fortran编程语言实现的并行计算示例,用于计算圆周率π的值。MPI是一种广泛使用的并行计算接口,它允许程序员在分布式内存系统上...

    求圆周率精确到16位

    圆周率π是一个无理数,它表示圆的周长与其直径之比,其值约为3.14159265358979。在实际应用中,如工程计算或科学研究,有时需要更精确的π值来确保结果的准确性。 描述虽然简洁,但暗示了我们讨论的核心——如何...

    一个计算圆周率达到小数点后任意精度的程序

    圆周率π定义为任何圆的周长与直径之比,其数值约为3.14159265358979323846...。在众多计算圆周率的算法中,马赫林级数是一个高效的选择,它可以快速地逼近圆周率的真实值。除此之外,Bailey-Borwein-Plouffe公式是...

    计算圆周率.zip

    3. 数字分析和并行计算:随着计算机技术的发展,人们使用高速计算机和并行算法,如Chudnovsky兄弟的公式,实现了对圆周率的高精度计算。 4. 现代数学理论的应用:如量子计算和模形式理论等领域的进展,为计算圆周率...

Global site tag (gtag.js) - Google Analytics