我该如何优化我的程序?

时间:2012-03-20 12:50:58

标签: c++ c optimization

我编写的程序实现了这个公式:

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) );
        }

由于

4 个答案:

答案 0 :(得分:3)

我建议你阅读这篇优秀的文件:

Software Optimization Guide for AMD64 Processors

如果您没有AMD处理器,这也很棒。

但如果我是你,我会用

替换整个计算循环
pi1 = M_PI;

哪个可能是最快的......如果您真的对Pi计算的更快算法感兴趣,请查看维基百科文章:Category:Pi algorithm

如果您只想微观优化代码,请阅读上述软件优化指南。

答案 1 :(得分:3)

一个想法是:

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

但您需要测试它与当前代码是否有任何区别。

答案 2 :(得分:2)

简单优化的例子:

  • double one_per_n = 1/n;循环之外计算for,减少每次迭代时除以n的费用
  • 在循环中计算double j = (i-0.5) * one_per_n
  • pi1 += 4 / (1 + j*j);

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

答案 3 :(得分: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;
}