2012-03-20 81 views
-1

我写程序,其实现该配方:如何优化我的程序?

PI = 1/N * SUMM(4 /(1 +((I-0.5)/ N)^ 2)

程序代码:

#include <iostream> 
#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/time.h> 
using namespace std; 

const long double PI = double(M_PI); 

int main(int argc, char* argv[]) 
{ 
    typedef struct timeval tm; 
    tm start, end; 
    int timer = 0; 
    int n; 

    if (argc == 2) n = atoi(argv[1]); 
    else n = 8000; 

    long double pi1 = 0; 
    gettimeofday (&start, NULL); 

    for(int i = 1; i <= n; i++) { 
     pi1 += 4/(1 + (i-0.5) * (i-0.5)/(n*n)); 
    } 

    pi1/=n; 
    gettimeofday (&end, NULL); 
    timer = (end.tv_usec - start.tv_usec); 
    long double delta = pi1 - PI; 
    printf("pi = %.12Lf\n",pi1); 
    printf("delta = %.12Lf\n", delta); 

    cout << "time = " << timer << endl; 
    return 0; 
} 

如何呈现其最佳的方式的时候会有更少的浮点运算这一部分:

for(int i = 1; i <= n; i++) { 
      pi1 += 4/(1 + (i-0.5) * (i-0.5)/(n*n)); 
     } 

感谢

+0

你是什么意思“少操作” - 一行代码或指令一旦建成? – Nim 2012-03-20 12:52:51

+3

谢尔盖,你的空格键不工作? – jrok 2012-03-20 12:53:23

+4

为什么要结合'printf'和'cout' – triclosan 2012-03-20 12:53:31

回答

3

我建议你阅读这个优秀的文档:

Software Optimization Guide for AMD64 Processors

这也是伟大的,当你没有AMD处理器。

但是,如果我是你,我会替换刚刚

pi1 = M_PI; 

整个计算循环这可能将是最快的。如果你是在对于Pi计算更快的算法真正感兴趣的,看看维基百科的文章:Category:Pi algorithm

如果你只是想微代码,请阅读上面提到的软件优化指南。简单的优化的

1
#include <iostream> 
#include <cmath> 
#include <chrono> 

#ifndef M_PI //M_PI is non standard make you sure catch this case 
    #define M_PI 3.14159265358979323846 
#endif 

typdef long double float_t; 
const float_t PI = double(M_PI); 

int main(int argc, char* argv[]) 
{ 
    int n = argc == 2 ? atoi(argv[1]) : 8000; 
    float_t pi1=0.0; 
    //if you can using auto here is a no brainer 
    std::chrono::time_point start 
      =std::chrono::system_clock::now(); 

    unsigned n2=n*n; 
    for(unsigned i = 1; i <= n; i++) 
    { 
     pi1 += 4.0/(1.0 + (i-0.5) * (i-0.5)/n2); 
    } 
    pi1/=n; 
    std::chrono::duration<double> time 
     =std::chrono::system_clock::now()-start; 

    float_t delta = pi1 - PI; 

    std::cout << "pi = " << std::setprecision(12) << pi1 
       << "delta = " << std::setprecision(12) << delta 
       << "\ntime = " << time.count() << std::endl; 
    return 0; 
} 
+0

@Sergey:哪一部分,我刚刚编辑过,再看看。 – 111111 2012-03-20 13:10:28

+0

@Sergey:再次检查 – 111111 2012-03-20 13:10:42

+0

哦...抱歉)非常感谢你! – Sergey 2012-03-20 13:11:45

2

实例:

  • 计算double one_per_n = 1/n;for循环在每次迭代
  • 计算double j = (i-0.5) * one_per_n减少分割的成本由n环路
  • pi1 += 4/(1 + j*j);
内部外

这应该会更快,并且还可以避免整数溢出对于更大的值n。对于更优化的代码,您必须查看生成的代码并使用分析器进行适当的更改。以这种方式优化的代码在具有不同CPU或缓存的机器上的行为可能会有所不同....避免划分是节省计算时间总是很好的事情。

3

一个想法是:

double nn = n*n; 
for(double i = 0.5; i < n; i += 1) { 
    pi1 += 4/(1 + i * i/nn); 
} 

,但你需要测试它是否与当前的代码有什么区别。