Qt 并行计算圆周率示例

Qt 并行计算圆周率示例

简介:
因为最近的一项项目中要用到并行计算,所以花了两天的时间了解了下Qt的并行计算的功能,顺便也尝试写了一个Demo和大家一起分享。

任务如下:
1、实现多种方法计算圆周率。(据了解圆周率的计算方法估计有上百种)
2、实现普通计算和并行计算的比较。
3、计算的循环次数可以设定。
4、计算结果可是在界面显示。

在这里插入图片描述
实现过程:
本示例需要解决的难点在于:
1、计算时间的获取。
2、并行计算的调用。
3、圆周率计算方法的实现。

那先了解下,计算时间的获取:

    ARGE_INTEGER litmp;
    LONGLONG QPart1, QPart2;
    double  dfFreq = 0;


    //计算程序的执行时间
    QueryPerformanceFrequency(&litmp);///>取得高精度运行计数器的频率f
    dfFreq = static_cast<double>(litmp.QuadPart);

    QueryPerformanceCounter(&litmp);
    QPart1 = litmp.QuadPart;///>开始计时

  /*
   插入fucntion 执行部分
   */

    QueryPerformanceCounter(&litmp);
    QPart2 = litmp.QuadPart;///>终止计时
    dfTime = (static_cast<double>(QPart2 - QPart1) / dfFreq) * 1000;

通过调取 windows API 来获取系统的时间,进而实现fucntion 执行部分的时间。

2、并行计算的调用。
首先 需要在.pro 文件关联

QT       += concurrent

然后,添加头文件

#include <QtConcurrent>
#include <QtConcurrent/QtConcurrentRun>
#include<QFuture>
#include<QFutureWatcher>

接着,设置变量

    QFuture<double> future ;

    QFutureWatcher<void> *m_pWatcher;

然后,调用

      future =  QtConcurrent::run(this, &MainWindow::series_method_1,loopNums);///>并行处理数据

有关并行计算方面的内容,本人在之前写过一篇翻译:
https://blog.csdn.net/qq_21291397/article/details/105805043、

最后,圆周率计算的实现;

//数列1逼近
/*
欧拉:级数
*/
double  MainWindow::series_method_1( long long loops)
{
    double sum=0;     //初始化和为0;
    double pi = 0;
    double n = 0.5;
    double m = 1.0/3;
    int k = 1;
    /*极限逼近求圆周率*/
    for(int i=1;i<=loops;i++,k=-k)
    {    
        sum=sum+((1.0/(2*i-1))*n*k + (1.0/(2*i-1))*m*k);
        n*=pow(0.5,2) ;
        m*=pow(1.0/3,2);
    }

    pi=sum*4;

    //预留调试接口
    qDebug()<<QString::number(pi,'g',10)<<endl;

    return pi;

}

//数列3逼近
/*
使用格雷戈里 - 莱布尼茨无穷级数。数学家们发现了若干个数学级数,
如果实施无穷多次运算,就能精确计算出 Pi 小数点后面的多位数字。
其中部分无穷级数非常复杂,需要超级计算机才能运算处理。
但是有一个最简单的无穷级数,即格雷戈里-莱布尼茨级数。
尽管计算较费时间,但每一次迭代的结果都会更接近 Pi 的精确值,
迭代 500,000 次后可准确计算出 Pi 的 10 位小数。[2] 公式如下:
π = (4/1) - (4/3) + (4/5) - (4/7) + (4/9) - (4/11) +
(4/13) - (4/15) ...
首先用 4 减去 4 除以 3,然后加上4除以5,然后减去4除以7。
反复变换使用加减法,后面的小数是用4作分子,用连续的奇数作分母。
计算的次数越多,则结果越接近 Pi。*/
double MainWindow:: series_method_2(long long loops)
{
    double pi = 0, k = 1;
    for (int i = 0; i < loops; i++, k = -k)
        pi += k / (2 * i + 1);

    return pi*4;
   // printf("pi: %lf\n", pi * 4);
}

//数列4逼近
/*
 * π/2≈1+1/3+1/3 * 2/5+1/3 * 2/5 * 3/7+······+An * (n-1)/(2n-1)
​*/
double MainWindow::series_method_3(long long loops)
{
    double pi = 1, n = 1;
    for (int i = 1; i < loops; i++)
    {
        n *= (double)i / (2 * i + 1);
        pi += n;
    }
    return pi*2;
   // printf("pi: %lf\n", pi * 2);
}

//蒙特·卡罗法(Monte Carlo method)
/*蒙特卡罗法本质是随机撒点*/
double  MainWindow::Monte_Carlo_method_1(long long N)
{
   double pi = 0;
    double x, y, hits = 0;
    for (int i = 0; i < N; i++)
    {
        x = (double)rand() / RAND_MAX;
        y = (double)rand() / RAND_MAX;
        if (x * x + y * y < 1.0)
            hits++;
    }
    pi = (hits / N)*4;
    return pi;
   // printf("pi: %lf\n", (hits / N) * 4);
}

/*蒙特卡罗 均匀撒点。*/
double MainWindow::Monte_Carlo_method_2(long long N)
{
    double x, y, hits = 0;
    for (x = 0; x < sqrt(N); x++)
        for (y = 0; y < sqrt(N); y++)
            if (x * x + y * y < N)
                hits++;

    return (hits / N) * 4;
   // printf("pi: %lf\n", (hits / N) * 4);
}

总结:
1、并行计算只是系统会单独建一个线程来实现,但计算所花的不占用主线程而已。并不是所花的计算时间减少了,这点一定要理解透。
2、double 数据类型的精度是小数点15~16位。long double 数据类型的精度会更高一些。通过调取本机所支持的数据类型的位数
发现:

sizeof(double) = 8
sizeof(long double) = 12

显然 如果计算精度达到小数点二三十位以
上,那就是不这些个数据类型了。我国航天工业近10年来迅猛发展,有关数据计算精确度越来越高,卫星发射偏差已达到0.0000104。按照这个精度要求,double数据类型来也早就够航天数据的计算了,不知道我这样理解是否有误?
3、测试发现100亿循环普通单线程运算的本机的耗时在9S 左右。按照这个比例关系,1000亿次的循环需要1个半小时。。。。。

有关圆周率的计算,本篇就讨论到这里吧!

本篇示例程序
下载链接:
https://download.csdn.net/download/qq_21291397/12372605

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值