2012-03-20 2 views
-1

는 I이 화학식 실현하는 프로그램 작성 :프로그램을 어떻게 최적화 할 수 있습니까?

의 PI = 1/N의 *의 써머 (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

+3

Sergey, 스페이스 바가 작동하지 않습니까? – jrok

+4

왜'printf'와'cout'을 합친 것입니까 – triclosan

답변

3

난 당신이 훌륭한 문서를 읽으십시오 :

Software Optimization Guide for AMD64 Processors

도 좋은 어느 당신이 AMD 프로세서가없는 경우.

하지만 당신이라면, 나는 보면, 당신은 파이 계산을위한 빠른 알고리즘에 실제로 관심이 있다면 아마 ... 가장 빠른 될 것입니다 단지

pi1 = M_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

+0

@ Sergey : 다시 확인 – 111111

+0

아 ... 죄송합니다.) 대단히 감사합니다! – Sergey

2

예 : 루프

  • pi1 += 4/(1 + j*j);
  • 내부 각 반복
  • 계산 double j = (i-0.5) * one_per_nn로 나누어 비용 저감 for 루프 외부

    • 컴퓨팅 double one_per_n = 1/n;

      더 빠르며 더 큰 값인 n에 대해 정수 오버플로가 발생하지 않도록해야합니다. 더욱 최적화 된 코드를 생성하려면 생성 된 코드를 살펴보고 프로파일 러를 사용하여 적절하게 변경해야합니다. 이런 식으로 최적화 된 코드는 CPU 나 캐시가 다른 컴퓨터에서 다르게 동작 할 수 있습니다. 분할을 피하는 것은 계산 시간을 절약하기 위해 항상 좋은 방법입니다.

  • 3

    하나의 아이디어는 다음과 같습니다

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

    하지만 당신은 현재의 코드와 어떤 차이가있는 경우 테스트해야합니다.

    관련 문제