搜索
bottom↓
回复: 14

轻松一下,利用计算圆周率PI的程序测试MCU的性能

[复制链接]

出0入0汤圆

发表于 2006-2-26 02:01:50 | 显示全部楼层 |阅读模式
今天在网上看到了计算PI的一种快速算法和程序。我稍微作了一些修改,理论上可以放到任何的平台上编译执行。



#define NUMBERS                5000



long long base[NUMBERS / 12 + 10];

long long calc[NUMBERS / 12 + 10];

long long result[NUMBERS / 12 + 10];



void CalculatePI(long long *total, long number)

{

    long a, i, j, step;

    long array = number / 12 + 3;

    long long remain, q;

    long head, devide, devidedouble, loop, start;

    double ratio;

    for(i = 0; i <= array; i ++)

        total = 0;

    for (step = 0; step < 2; step ++)

    {

        devide = (!step) ? 5 : 239;

        devidedouble = devide * devide;

        remain = 1;

        for(i = 0;i <= array; i ++)

        {

            base=remain / devide;

//            remain=(remain%devide)*1000000000000LL;

/**/        remain=(remain - base * devide) * 1000000000000LL;

        }

        loop = (long)(number * log(10) / log(devide) + 1);

        ratio = log(devide) / log(10) / 12;

        start;

        for(i = 0; i <= array; i ++)

            calc = 0;

        for(j = 1;j <= loop; j++, j++)

        {

            start = (long)(j * ratio);

            remain = 0;

            if(!(j & 2))

                for(i = start; i <= array;)

                {

                    a=i;

//                    calc+=remain/j;

//                    remain=(remain%j)*1000000000000LL+base[++i];

/**/                q = remain / j;

/**/                calc += q;

/**/                remain -= q * j;

/**/                remain = remain * 1000000000000LL + base[++i];

                    while(calc[a] >= 1000000000000LL)

                    {

                        calc[a] -= 1000000000000LL;

                        calc[--a] ++;

                    }

                }

            else

                for(i = start; i <= array;)

                {

                    a=i;

//                    calc-=remain/j;

//                    remain=(remain%j)*1000000000000LL+base[++i];

/**/                q = remain / j;

/**/                calc -= q;

/**/                remain -= q * j;

/**/                remain = remain * 1000000000000LL + base[++i];

                    while(calc[a] < 0)

                    {

                        calc[a] += 1000000000000LL;

                        calc[-- a] --;

                    }

                }

            remain = 0;

            if(!step)

            {

                head = j/12 + 2;

                for (i = start;(i <= array) && (i <= head);)

                {

                    base = remain / devidedouble;

//                    remain=(remain%devidedouble)*1000000000000LL+base[++i];

/**/                remain -= base * devidedouble;

/**/                remain = remain * 1000000000000LL + base[++ i];

                }

            }

            else

                for(i = start;i <= array;)

                {

                    base=remain / devidedouble;

//                    remain=(remain%devidedouble)*1000000000000LL+base[++i];

/**/                remain -= base * devidedouble;

/**/                remain = remain * 1000000000000LL + base[++ i];

                }

        }

        if(!step)

        {

            total[array] += calc[array] * 16;

            for(i = array - 1;i >= 0;i --)

            {

                total += total[i + 1] / 1000000000000LL + calc * 16;

                total[i + 1] %= 1000000000000LL;

            }

        }

        else

        {

            long long tail;

            total[array] -= calc[array] * 4;

            for (i = array - 1;i >= 0;i --)

            {

                tail = total[i + 1] % 1000000000000LL;

                total += total[i + 1] / 1000000000000LL - ((tail < 0) ? 1 : 0) - calc * 4;

                total[i + 1] = tail + ((tail < 0) ? 1000000000000LL : 0);

            }

        }

    }

}



调用时采用语句:CalculatePI(result, NUMBERS),结果保存在long long型的数组result中,其中result[0]存放的是数字3,result[1]以后的以整数形式存放PI的小数部分,每个整数对应12位的小数。



我分别在PC上和ARM7(LPC2142)上测试了程序的运算速度,结果如下:



  CPU       主频        RAM        编译器          计算5000位小数的时间

-----------------------------------------------------------------------

P4 2.4C     2.4GHz   512M DDR400   BCB 6.0                 0.912s

C4 2.4D     2.4GHz   512M DDR333   BCB 6.0                 1.285s

LPC2142     60MHz    16K SRAM    Keil ARM 2.50a,全优化    9.698s



由于代码太大,无法在我的M8515上测试,有兴趣的可以试试在AVR上的速度。迟些我也想试试在DSP上的速度如何。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2006-2-26 11:49:57 | 显示全部楼层
这样也行呀?计算结果应该跟编译器和优化等级有关哦。

出0入0汤圆

 楼主| 发表于 2006-2-26 12:17:03 | 显示全部楼层
是啊,通过类似的测试,可以大致了解一下在不同平台上实现同样功能的性能差别,以及在同一MCU上不同编译器的差别(例如我就发现KARM 2.32(采用Keil编译器)比KARM 2.50(采用RealView编译器)慢很多而且不能得到正确结果),还可以比较同一编译器,不同MCU上运行的差别(例如比较各种ARM7)。

出0入0汤圆

发表于 2006-2-26 13:08:28 | 显示全部楼层
我还有M128的板(外扩32KByte SRAM)

调用void CalculatePI(long long *total, long number) 就行了吗?

出0入0汤圆

 楼主| 发表于 2006-2-26 13:23:35 | 显示全部楼层
当然可以,程序代码大概20多K。你把



long long base[NUMBERS / 12 + 10];

long long calc[NUMBERS / 12 + 10];

long long result[NUMBERS / 12 + 10];



这3个全局变量定义到外部SRAM就可以了。

然后用定时器来算算运行时间。

出0入0汤圆

 楼主| 发表于 2006-2-26 14:12:28 | 显示全部楼层
刚才在VC下编译运行了一次,在C4 2.4D,512M DDR的配置下运行居然只需要0.176s,比BCB6.0的版本快了7倍多!

出0入0汤圆

发表于 2014-7-10 14:56:26 | 显示全部楼层
qwernet 发表于 2006-2-26 13:23
当然可以,程序代码大概20多K。你把



long long base[NUMBERS / 12 + 10];

我放在LPC1768上,编译不过,报错啊.

//--------------------------------------         if(!step)
         {
                                                        head = j/12 + 2;
                                                        for (i = start;(i <= array) && (i <= head);)
                                                        {
                                                    base = remain / devidedouble;   //################数组不能这样这样用吧
        //            remain=(remain%devidedouble)*1000000000000LL+base[++i];
//                      remain -= base * devidedouble;
//                      remain = remain * 1000000000000LL + base[++ i];

                                                         }
         }
          else
                                        {
              for(i = start;i <= array;)
              {
                 base= (remain / devidedouble);
//              remain=(remain%devidedouble)*1000000000000LL+base[++i];
//              remain -= base * devidedouble;
//              remain = remain * 1000000000000LL + base[++ i];
              }
                                        }

数组

出0入0汤圆

发表于 2014-7-10 15:34:13 | 显示全部楼层
试一下ADI的blackfin DSP,应该也在1秒左右。

出0入0汤圆

 楼主| 发表于 2014-7-10 16:16:35 | 显示全部楼层
flyforyou85 发表于 2014-7-10 14:56
我放在LPC1768上,编译不过,报错啊.

//--------------------------------------         if(!step)


见鬼了,当年贴上来的代码,所有“[ i ]”都贴丢了。。。

出0入0汤圆

 楼主| 发表于 2014-7-10 16:19:14 | 显示全部楼层
flyforyou85 发表于 2014-7-10 14:56
我放在LPC1768上,编译不过,报错啊.

//--------------------------------------         if(!step)


我明白了,原来“【i】”在现在的论坛里变成了斜体格式代码,所以全部都丢了。。。

出0入0汤圆

发表于 2014-7-10 16:25:13 | 显示全部楼层
qwernet 发表于 2014-7-10 16:19
我明白了,原来“【i】”在现在的论坛里变成了斜体格式代码,所以全部都丢了。。。 ...

楼主,你好.我正想测试下手头的NXP CORTEX-M0+的,为了避免出错,能够将这个函数以及他的具体用法,放到记事本,传上来!?多谢!

出300入477汤圆

发表于 2014-7-10 17:41:06 | 显示全部楼层
astankvai 发表于 2014-7-10 15:34
试一下ADI的blackfin DSP,应该也在1秒左右。

PC,BCB XE5 64位编译器,Win7 64位系统,CPU是I7-4700MQ,2.4G
最高优化,计算时间 28-29ms
切换为BCB XE5 32位编译器,最高优化,计算时间500ms

BCB64位的进步真大!

出300入477汤圆

发表于 2014-7-10 17:45:34 | 显示全部楼层
[ 本帖最后由 redroof 于 2014-7-10 17:46 编辑 ]\n\n[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=7675106&ptid=589912][color=#999999]redroof 发表于 2014-7-10 17:41[/color][/url][/size]
PC,BCB XE5 64位编译器,Win7 64位系统,CPU是I7-4700MQ,2.4G
最高优化,计算时间 28-29ms
切换为BCB XE ...[/quote]

据说地球上最好的编译器是Intel的ICC
不知道哪位有新的64位版的ICC,可以编译这个代码来试试看
楼主的代码的正确处理方法是:
显示网页代码,然后把<i>替换成[i]
然后再用浏览器打开,正常拷出里面的内容就行了
我试过,可以编译,计算结果也正确

出5入110汤圆

发表于 2020-8-27 12:07:09 | 显示全部楼层
找圆周率的计算方法,找到这里,用VS2015 顺便测试了一下。
感觉挺有意思,虽然 没看懂,
使用的电脑 计算一次用时不超过50ms
win10 64位
CPU E3-1230 V2@3.30GHz
编辑后的code 重新传了一遍



  1. // CalculatePI.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "math.h"

  5. #define NUMBERS 5000

  6. long long base[NUMBERS / 12 + 10];
  7. long long calc[NUMBERS / 12 + 10];
  8. long long result[NUMBERS / 12 + 10];

  9. void CalculatePI(long long *total, long number)
  10. {
  11.         long a, i, j, step;
  12.         long array = number / 12 + 3;
  13.         long long remain, q;
  14.         long head, devide, devidedouble, loop, start;
  15.         double ratio;
  16.         for (i = 0; i <= array; i++)
  17.                 total[i] = 0;
  18.         for (step = 0; step < 2; step++)
  19.         {
  20.                 devide = (!step) ? 5 : 239;
  21.                 devidedouble = devide * devide;
  22.                 remain = 1;
  23.                 for (i = 0; i <= array; i++)
  24.                 {
  25.                         base[i] = remain / devide;
  26.                         //            remain=(remain%devide)*1000000000000LL;
  27.                         /**/ remain = (remain - base[i] * devide) * 1000000000000LL;
  28.                 }
  29.                 loop = (long)(number * log(10) / log(devide) + 1);
  30.                 ratio = log(devide) / log(10) / 12;
  31.                 start;
  32.                 for (i = 0; i <= array; i++)
  33.                         calc[i] = 0;
  34.                 for (j = 1; j <= loop; j++, j++)
  35.                 {
  36.                         start = (long)(j * ratio);
  37.                         remain = 0;
  38.                         if (!(j & 2))
  39.                                 for (i = start; i <= array;)
  40.                                 {
  41.                                         a = i;
  42.                                         //                    calc+=remain/j;
  43.                                         //                    remain=(remain%j)*1000000000000LL+base[++i];
  44.                                         /**/ q = remain / j;
  45.                                         /**/ calc[i] += q;
  46.                                         /**/ remain -= q * j;
  47.                                         /**/ remain = remain * 1000000000000LL + base[++i];
  48.                                         while (calc[a] >= 1000000000000LL)
  49.                                         {
  50.                                                 calc[a] -= 1000000000000LL;
  51.                                                 calc[--a]++;
  52.                                         }
  53.                                 }
  54.                         else
  55.                                 for (i = start; i <= array;)
  56.                                 {
  57.                                         a = i;
  58.                                         //                    calc-=remain/j;
  59.                                         //                    remain=(remain%j)*1000000000000LL+base[++i];
  60.                                         /**/ q = remain / j;
  61.                                         /**/ calc[i] -= q;
  62.                                         /**/ remain -= q * j;
  63.                                         /**/ remain = remain * 1000000000000LL + base[++i];
  64.                                         while (calc[a] < 0)
  65.                                         {
  66.                                                 calc[a] += 1000000000000LL;
  67.                                                 calc[--a]--;
  68.                                         }
  69.                                 }
  70.                         remain = 0;
  71.                         if (!step)
  72.                         {
  73.                                 head = j / 12 + 2;
  74.                                 for (i = start; (i <= array) && (i <= head);)
  75.                                 {
  76.                                         base[i] = remain / devidedouble;
  77.                                         //                    remain=(remain%devidedouble)*1000000000000LL+base[++i];
  78.                                         /**/ remain -= base[i] * devidedouble;
  79.                                         /**/ remain = remain * 1000000000000LL + base[++i];
  80.                                 }
  81.                         }
  82.                         else
  83.                                 for (i = start; i <= array;)
  84.                                 {
  85.                                         base[i] = remain / devidedouble;
  86.                                         //                    remain=(remain%devidedouble)*1000000000000LL+base[++i];
  87.                                         /**/ remain -= base[i] * devidedouble;
  88.                                         /**/ remain = remain * 1000000000000LL + base[++i];
  89.                                 }
  90.                 }
  91.                 if (!step)
  92.                 {
  93.                         total[array] += calc[array] * 16;
  94.                         for (i = array - 1; i >= 0; i--)
  95.                         {
  96.                                 total[i] += total[i + 1] / 1000000000000LL + calc[i] * 16;
  97.                                 total[i + 1] %= 1000000000000LL;
  98.                         }
  99.                 }
  100.                 else
  101.                 {
  102.                         long long tail;
  103.                         total[array] -= calc[array] * 4;
  104.                         for (i = array - 1; i >= 0; i--)
  105.                         {
  106.                                 tail = total[i + 1] % 1000000000000LL;
  107.                                 total[i] += total[i + 1] / 1000000000000LL - ((tail < 0) ? 1 : 0) - calc[i] * 4;
  108.                                 total[i + 1] = tail + ((tail < 0) ? 1000000000000LL : 0);
  109.                         }
  110.                 }
  111.         }
  112. }
  113. //调用时采用语句:CalculatePI(result, NUMBERS),
  114. //结果保存在long long型的数组result中,
  115. //其中result[0]存放的是数字3,
  116. //result[1]以后的以整数形式存放PI的小数部分,
  117. //每个整数对应12位的小数。
  118. int main()
  119. {
  120.         CalculatePI(result, NUMBERS);
  121.         return 0;
  122. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出10入120汤圆

发表于 2020-8-27 12:15:58 | 显示全部楼层
谁放在世界第一的STC上试一下
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 17:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表