轻松一下,利用计算圆周率PI的程序测试MCU的性能
今天在网上看到了计算PI的一种快速算法和程序。我稍微作了一些修改,理论上可以放到任何的平台上编译执行。#define NUMBERS 5000
long long base;
long long calc;
long long result;
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 >= 1000000000000LL)
{
calc -= 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 < 0)
{
calc += 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 += calc * 16;
for(i = array - 1;i >= 0;i --)
{
total += total / 1000000000000LL + calc * 16;
total %= 1000000000000LL;
}
}
else
{
long long tail;
total -= calc * 4;
for (i = array - 1;i >= 0;i --)
{
tail = total % 1000000000000LL;
total += total / 1000000000000LL - ((tail < 0) ? 1 : 0) - calc * 4;
total = tail + ((tail < 0) ? 1000000000000LL : 0);
}
}
}
}
调用时采用语句:CalculatePI(result, NUMBERS),结果保存在long long型的数组result中,其中result存放的是数字3,result以后的以整数形式存放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上的速度如何。 这样也行呀?计算结果应该跟编译器和优化等级有关哦。 是啊,通过类似的测试,可以大致了解一下在不同平台上实现同样功能的性能差别,以及在同一MCU上不同编译器的差别(例如我就发现KARM 2.32(采用Keil编译器)比KARM 2.50(采用RealView编译器)慢很多而且不能得到正确结果),还可以比较同一编译器,不同MCU上运行的差别(例如比较各种ARM7)。 我还有M128的板(外扩32KByte SRAM)
调用void CalculatePI(long long *total, long number) 就行了吗? 当然可以,程序代码大概20多K。你把
long long base;
long long calc;
long long result;
这3个全局变量定义到外部SRAM就可以了。
然后用定时器来算算运行时间。 刚才在VC下编译运行了一次,在C4 2.4D,512M DDR的配置下运行居然只需要0.176s,比BCB6.0的版本快了7倍多! qwernet 发表于 2006-2-26 13:23
当然可以,程序代码大概20多K。你把
long long base;
我放在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];
}
}
数组 试一下ADI的blackfin DSP,应该也在1秒左右。 flyforyou85 发表于 2014-7-10 14:56
我放在LPC1768上,编译不过,报错啊.
//-------------------------------------- if(!step)
见鬼了,当年贴上来的代码,所有“[ i ]”都贴丢了。。。 flyforyou85 发表于 2014-7-10 14:56
我放在LPC1768上,编译不过,报错啊.
//-------------------------------------- if(!step)
我明白了,原来“【i】”在现在的论坛里变成了斜体格式代码,所以全部都丢了。。。 qwernet 发表于 2014-7-10 16:19
我明白了,原来“【i】”在现在的论坛里变成了斜体格式代码,所以全部都丢了。。。 ...
楼主,你好.我正想测试下手头的NXP CORTEX-M0+的,为了避免出错,能够将这个函数以及他的具体用法,放到记事本,传上来!?多谢! 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
{:lol:}
BCB64位的进步真大! [ 本帖最后由 redroof 于 2014-7-10 17:46 编辑 ]\n\nredroof 发表于 2014-7-10 17:41
PC,BCB XE5 64位编译器,Win7 64位系统,CPU是I7-4700MQ,2.4G
最高优化,计算时间 28-29ms
切换为BCB XE ...
据说地球上最好的编译器是Intel的ICC
不知道哪位有新的64位版的ICC,可以编译这个代码来试试看
楼主的代码的正确处理方法是:
显示网页代码,然后把<i>替换成
然后再用浏览器打开,正常拷出里面的内容就行了
我试过,可以编译,计算结果也正确
找圆周率的计算方法,找到这里,用VS2015 顺便测试了一下。
感觉挺有意思,虽然 没看懂,
使用的电脑 计算一次用时不超过50ms
win10 64位
CPU E3-1230 V2@3.30GHz
编辑后的code 重新传了一遍
// CalculatePI.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "math.h"
#define NUMBERS 5000
long long base;
long long calc;
long long result;
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 >= 1000000000000LL)
{
calc -= 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 < 0)
{
calc += 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 += calc * 16;
for (i = array - 1; i >= 0; i--)
{
total += total / 1000000000000LL + calc * 16;
total %= 1000000000000LL;
}
}
else
{
long long tail;
total -= calc * 4;
for (i = array - 1; i >= 0; i--)
{
tail = total % 1000000000000LL;
total += total / 1000000000000LL - ((tail < 0) ? 1 : 0) - calc * 4;
total = tail + ((tail < 0) ? 1000000000000LL : 0);
}
}
}
}
//调用时采用语句:CalculatePI(result, NUMBERS),
//结果保存在long long型的数组result中,
//其中result存放的是数字3,
//result以后的以整数形式存放PI的小数部分,
//每个整数对应12位的小数。
int main()
{
CalculatePI(result, NUMBERS);
return 0;
}
谁放在世界第一的STC上试一下{:lol:}
页:
[1]