수치 계산기로서의 Linux

    저자 : 박 진 우 (hitel : REDUCK96)  
     

 

    요즘에도 물리학자나 수치연산과 관련된 직종에서 연구하시는 분들은 대부분 Unix를 이용한다. Unix를 이용하는 가장 큰 이유는 시스템의 안정성과 출력 값의 신뢰도가 높기 때문이다. 이런 장점들은 Linux도 가지고 있다는 사실은 리눅서들은 잘 알 것이다. 그래서 필자는 Linux도 훌륭한 수치 연산을 할 수 있다는 것을 여러 플랫폼에 설치되어 있는 Linux를 가지고 비교/분석하려고 한다.

    비교 대상 플랫폼 및 사용할 컴파일러
     

    플랫폼

    사용할 컴파일러

     Sparc Solaris 2.5.1 (기준)  

    Sun Microsystem Fortran77

     Alpha Red Hat Linux 4.2

    Fort77, Microway NDP Fortran77

     Sparc Red Hat Linux 4.2

     Fort77, Sun Microsystem Fortran77  

     Intel Red Hat Linux 4.2

    GNU g77


    Sparc Solaris를 기준으로 삼은 이유는 현재 과학계산 출력 값의 대부분이 Sparc Solaris/HPUX 등에서 나온 것이 대부분이기 때문이다. 그리고 현재 일부 유명 대학의 교수님들도 Sparc에서 나온 값을 더 신뢰하는 경향이 있다. 그리고 Fort77은 Red Hat package안에 들어가 있는데, Fort77은 f2c로 우선 포트란 소스를 C 소스로 변환 시켜주고 나머지 링크나 컴파일을 fort77이 맡는다. 자세한 부분은 man페이지를 이용하시고 이제 본격적으로 출력 값에 대한 비교를 하겠다. 참고로 필자는 AlphaLinux에서 g77을 사용하지 않았는데, 그 이유는 Alpha에서는 g77의 performance가 너무 안 좋아서 그렇다. 그냥 fort77을 사용하는 것이 더 나을 것이다. 그러나 복잡한 연산에서는 fort77의 사용을 삼가해 주셨으면 한다.

     

1. 런지-쿠타 방법(Runge-Kutta Method)을 이용한 결과 비교

    런지-쿠타 방법은 미분 방정식을 푸는 알고리즘 중에서 가장 널리 이용되는 방법이다. 필자는 정확도가 소수점 6자리까지 유효한 4차 런지-쿠타 알고리즘을 사용하겠다.

    k1 = hf(xn,yn)
    k
    2 = hf(xn+1/2h,yn+1/2k1)
    k
    3 = hf(xn+1/2h,yn+1/2k2)
    k
    4 = hf(xn+h,yn+k3)
    y
    n+1 = yn+1/6(k1+2k2+2k3+k4)+O(h5)

    f는 function, 즉 함수를 뜻하며, h는 각 정의역의 간격을 뜻한다. O(h5)는 테일러 전개에 따른 5차 이상 항들을 무시한다는 뜻이다. (어려운 말을 사용해서 죄송합니다.)

    여기서 우리는 컴퓨터가 저지르는 엄청난 실수를 감안하여야 한다. 현존하는 모든 컴퓨터들은 아주 작은 값을 큰 값으로 나누거나 곱할 때, 또는 작은 값을 가지고 있는 데이터들을 큰 값을 가지는 데이터들과 같이 다룰 때 무시할 수 없는 오차가 나온다. 예를 들어 설명하겠다. 소수 5자리까지 데이터를 얻는 프로그램을 작성했다고 하자. 처음 계산에는 그 값을 신뢰할 수 있다. 그러나 계산을 반복하면 할수록 소수 6자리에 남아있던 부분이 실제 데이터에 영향을 미치기 시작한다. 티끌 모아 태산이라는 속담이 있듯이, 0.0000000001을 100만번 연산을 하면 앞의 값은 100만번 더해지거나 빼져서 원하는 출력 값을 얻지 못할 수 있다. 앞으로 비교할 출력 값들은 Solaris에서 오차율이 제일 적은 값을 기준으로 Linux에서 나온 값들을 비교해 나갈 것임을 미리 알려둔다. 다음의 소스는 런지-쿠타를 이용한 Oscillation 적분에 관한 것이다. w의 일반적인 조건은 Damped Oscillation을 따르고 있다. 소스에 대한 분석은 생략하겠다. 그러나 간단한 프로그램이므로 쉽게 분석할 수 있다.

            f(t,v,x,r)=v
            g(t,v,x,r)=-r*v-x
    20     print*,'enter value of w'
            read*,w
            if(w .le. 0.) stop
            r=w
            h=0.01
            nstep=10./h
            v=0
            x=2.5
            do 10 it=0, nstep-1
                           t=it*h
            aa=h*f(t,v,x,r)
            ba=h*g(t,v,x,r)
            ab=h*f(t+0.5*h,v+0.5*ba,x+0.5*aa,r)
            bb=h*g(t+0.5*h,v+0.5*ba,x+0.5*aa,r)
            ac=h*f(t+0.5*h,v+0.5*bb,x+0.5*ab,r)
            bc=h*g(t+0.5*h,v+0.5*bb,x+0.5*ab,r)
            ad=h*f(t+h,v+bc,x+ac,r)
            bd=h*g(t+h,v+bc,x+ac,r)
            v=v+(ba+2*bb+2*bc+bd)/6
            x=x+(aa+2*ab+2*ac+ad)/6
                          print*,t,x
    10     continue
            goto20
            end

    출력값을 GNUplot을 이용하여 plot하였다.
    여기서, data1은 w=1.5, data2는 w=1.0, data3는 w=0.75, data4는 w=0.50, data5는 w=0.25로 frequency를 놓았다.
    각 그래프는 눈으로 보아서 거의 차이가 없다.

     

    ◆ 각 데이터 값 비교

    data1의 값만을 List하겠다. (지면 관계상 모두 List할 수 없음을 양지해주세요^^;)
     

    ㄱ)Solaris

    ㄴ)SparcLinux
    f77(Sun)

    ㄷ)SparcLinux
    fort77

    0.                  2049988
    1.00000E-02  2.49950
    2.00000E-02  2.49889
    3.00000E-02  2.49804
    4.00000E-02  2.49695
    5.00000E-02  2.49563
    6.00000E-02  2.49409
    7.00000E-02  2.49231
    8.00000E-02  2.49032
    9.00000E-02  2.48811
    1.00000E-01  2.48569

    0.                  2.49988
    1.00000E-02  2.49950
    2.00000E-02  2.49889
    3.00000E-02  2.49804
    4.00000E-02  2.49695
    5.00000E-02  2.49563
    6.00000E-02  2.49409
    7.00000E-02  2.49231
    8.00000E-02  2.49032
    9.00000E-02  2.48811
    1.00000E-01  2.48569

    0.                   2.49987555
    .00999999978  2.4995048
    .0199999996    2.49889159
    .0299999993    2.49803948
    .0399999991    2.49695206
    .049999997      2.49563313
    .0599999987    2.49408603
    .0700000003    2.49231458
    .0799999982    2.49032211
    .0899999961    2.48811197
    .099999994      2.48568797

    ㄹ)AlphaLinux
    fort77

    ㅁ)AlphaLinux NDP
    fortran77

    ㅂ)IntelLinux GNU
    g77

    0.                   2.49987555
    .00999999978  2.4995048
    .0199999996    2.49889159
    .0299999993    2.49803948
    .0399999991    2.49695206
    .049999997      2.49563313
    .0599999987    2.49408603
    .0700000003    2.49231458
    .0799999982    2.49032211
    .0899999961    2.48811197
    .099999994      2.48568797

    0.0000000E+000 2.499876
    9.9999998E-03   2.499505
    2.0000000E-02   2.498892
    2.9999999E-02   2.498039
    3.9999999E-02   2.496952
    4.9999997E-02   2.495633
    5.9999999E-02   2.494086
    6.9999993E-02   2.492315
    7.9999998E-02   2.490322
    8.9999996E-02   2.488112
    9.9999994E-02   2.485688

    0.                    2.49987555
    0.00999999978 2.4995048
    0.0199999996   2.49889159
    0.0299999993   2.49803948
    0.0399999991   2.49695206
    0.049999997     2.49563313
    0.0599999987   2.49408603
    0.0700000003   2.49231458
    0.0799999982   2.49032211
    0.0899999961   2.48811197
    0.099999994     2.48568797


    위의 List를 보면 소수 유효 값과 반올림에 대한 표현의 차이만 있을 뿐, 결과 값의 큰 변화는 없다. 아시는 분은 아시겠지만, 위의 Wave function은 공업수학의 기초편만 공부하신 분이라면 간단히 풀 수 있는 문제이다. 이제 좀 더 복잡한 function으로 Test 해보자.

     

2. Bessel 함수를 이용한 소스 결과 비교

    Bessel 함수에 대한 간략한 설명은 피하겠다. (알고 싶으신 분은 공업수학에서 찾아 보세요.)
    Bessel 함수
    Jn(x)는 x2af2f(x)/dr2+xdf(x)/dx+(x2-n2)f(x)=0의 미분 방정식을 만족한다.
    한편 이들은
    J0'(x)=-J1(x), Jn-1(x)=n/rJn(x)+Jn'(x)  (n=1,2,3,...) 의 초기 조건을 사용하여 x의 값이 [1,20] 내의 Bessel 함수 J0(1)=0.7651977, J1(1)=0.4400506, J2(1)=0.1149034849, J3(1)=0.0195634
    AlphaLinux에서는 fort77 컴파일러에서 다음과 같은 에러 메세지를 출력하고 컴파일을 하지 못하였다.

     

    C    Find the Bessel functions by solving the diff equations
         parameter(nvat=4,nstep=150)
         dimension vstart(nvar)
         common /PATH/x(200),y(10,200)
         external derivs
         x1=1
         vstart(1)=0.7651976
         vstart(2)=0.4400506
         vstart(3)=1.149034849E-01
         vstart(4)=0.0195634
         x2=0
         call rkdumb(vstart,nvar,x1,x2,nstep,derivs)
    c    write(*,'(/1x,t9,a,t17,a/')'X','Integrated BESSJ3'

          do 10 i=nstep,1,-1
                   j=i
                   write(*,'(/1x,f10,4,2x,f12,6)')x(j),y(4,j)

    10   continue
          end

          subroutine derivs(x,y,dydx)
          dimension y(*),dydx(*)
          dydx(1)=-y(2)
          dydx(2)=(y(1)-(1.0/x)*y(2))
          dydx(3)=(y(2)-(2.0/x)*y(3))
          dydx(4)=(y(3)-(3.0/x)*y(4))
          return
          end

          subroutine rkdumb(vstart,nvar,x1,x2,nstep,derivs)
          integer nstep,nvar,nmax,nstpmx
          parameter (nmax=10,nstpmx=200)
          real x1,x2,vstart(nvar),xx(nstpmx),y(nmax,nstpmx)
          external derivs
          common /PATH/xx,y
    cu   uses rk4
          integer i,k
          real h,x,dv(nmax),v(nmax)
          do 11 i=1,nvar
                   v(i)=vatart(i)
                   y(i,1)=v(i)
    11   continue
           xx(1)=x1
           x=x1
           h=(x2-x1)/nstep
           do 13 k=1,nstep
                  call derivs(x,v,dv)
                  call rk4(v,dv,nvar,x,h,v,derivs)
                  if(x+h.eq.x)pause 'stepsize not significant in rkdumb'
                  x=x+h
                  xx(k+1)=x
                  do 12 i=1,nvar
                         y(i,k+1)=v(i)
    12           continue
    13    continue
           return
           end

           subrountine rk4(y,dydx,n,x,h,yout,derivs)
           integer n,nmax
           real h,x,dydx(n),y(n),yout(n)
           parameter (nmax=10)
           integer I
           real h6,hh,xh,dym(nmax),dyt(nmax),yt(nmax)
           hh=h*0.5
           h6=h/6
           xh=x+hh
           do 11 i=1,n
                   yt(i)=y(i)+hh*dydx(i)
    11     continue
           call derivs(xh,yt,dyt)
           do 12 i=1,n
                   yt(i)=y(i)+hh*dyt(i)
    12     continue
           call derivs(xh,yt,dym)
           do 13 i=1,n
                   yt(i)=y(i)+h*dym(i)
                   dym(i)=dyt(i)+dym(i)
    13     continue
           call derivs(x+h,yt,dyt)
           do 14 i=1,n
                   yout(i)=y(i)+h6*(dydx(i)+dyt(i)+2.*dym(i))
    14      continue
           return
           end

    그 이유는 잘 모르겠다.

    Compiler error line 18 of : floation exception during constant evaluation: cannot recover/usr/bin/fort77: aborting compilation

    위의 그래프를 보면 앞 부분에 차이가 있다. 뒤 부분으로 눈에 띄는 차이는 없다.

     

    ◆ 각 데이터 값 비교
     

    ㄱ)Solaris

    ㄴ)SparcLinux
    f77(Sun)

    ㄷ)SparcLinux
    fort77

    0.0067  0.145580
    0.0133  0.019414
    0.0200  0.005801
    0.0267  0.002453
    0.0333  0.001257
    0.0400  0.000729
    0.0467  0.000460
    0.0533  0.000310
    0.0600  0.000220
    0.0667  0.000163
    0.0733  0.000126
    0.0800  0.000102
    0.0867  0.000085
    0.0933  0.000074
    0.1000  0.000067

    0.0067  0.145580
    0.0133  0.019414
    0.0200  0.005801
    0.0267  0.002453
    0.0333  0.001257
    0.0400  0.000729
    0.0467  0.000460
    0.0533  0.000310
    0.0600  0.000220
    0.0667  0.000163
    0.0733  0.000126
    0.0800  0.000102
    0.0867  0.000085
    0.0933  0.000074
    0.1000  0.000067

    .0067  .145580
    .0133  .019414
    .0200  .005801
    .0267  .002453
    .0333  .001257
    .0400  .000729
    .0467  .000460
    .0533  .000310
    .0600  .000220
    .0667  .000163
    .0733  .000126
    .0800  .000102
    .0867  .000085
    .0933  .000074
    .1000  .000067

    ㄹ)AlphaLinux
    fort77

    ㅁ)AlphaLinux NDP
    fortran77

    ㅂ)IntelLinux GNU
    g77

    Compile 실패

    0.0067  0.143668
    0.0133  0.019159
    0.0200  0.005725
    0.0267  0.002420
    0.0333  0.001241
    0.0400  0.000719
    0.0467  0.000454
    0.0533  0.000306
    0.0600  0.000217
    0.0667  0.000161
    0.0733  0.000125
    0.0800  0.000100
    0.0867  0.000084
    0.0933  0.000073
    0.1000  0.000067

    0.0067  0.145607
    0.0133  0.019417
    0.0200  0.005802
    0.0267  0.002453
    0.0333  0.001257
    0.0400  0.000729
    0.0467  0.000460
    0.0533  0.000310
    0.0600  0.000220
    0.0667  0.000163
    0.0733  0.000126
    0.0800  0.000102
    0.0867  0.000085
    0.0933  0.000074
    0.1000  0.000067


    위의 값들은 그래프의 앞 부분과 잘 비교하기 바란다. 사실 이 프로그램에는 한가지 엄청난 오류를 일으키는 부분이 들어있다. 바로 작은 값을 큰 값으로 나누는 부분이다.(0에 가까운 수로 나눈다는 표현이 더 어울릴지도 모른다). 실제로 graph에서도 0에 가까울수록 갑자기 높은 값을 가진다는 것을 볼 수 있다. 필자는 이 graph를 보고 비교할 부분을 x값이 0.3이상인 부분으로 예상하고 다시 비교를 하겠다.

     

    ◆ 각 데이터 값 비교

    위의 Data를 보면 Alpha 쪽에서 0.333부분의 값이 다른 machine들의 값과 다르다. 아마도 유효자리 수를 따질 때 다른 machine들과 것 같다. 정확한 이유는 필자도 모르겠다.

    ㄱ)Solaris

    ㄴ)SparcLinux
    f77(Sun)

    ㄷ)SparcLinux
    fort77

    0.3000  0.000561
    0.3067  0.000599
    0.3133  0.000638
    0.3200  0.000680
    0.3267  0.000723
    0.3333  0.000768
    0.3400  0.000814
    0.3467  0.000863
    0.3533  0.000913
    0.3600  0.000965
    0.3667  0.001019
    0.3733  0.001076
    0.3800  0.001134
    0.3867  0.001194
    0.3933  0.001256
    0.4000  0.001321

    0.3000  0.000561
    0.3067  0.000599
    0.3133  0.000638
    0.3200  0.000680
    0.3267  0.000723
    0.3333  0.000768
    0.3400  0.000814
    0.3467  0.000863
    0.3533  0.000913
    0.3600  0.000965
    0.3667  0.001019
    0.3733  0.001076
    0.3800  0.001134
    0.3867  0.001194
    0.3933  0.001256
    0.4000  0.001321

    .3000  .000561
    .3067  .000599
    .3133  .000638
    .3200  .000680
    .3267  .000723
    .3333  .000768
    .3400  .000814
    .3467  .000863
    .3533  .000913
    .3600  .000965
    .3667  .001019
    .3733  .001076
    .3800  .001134
    .3867  .001194
    .3933  .001256
    .4000  .001321

    ㄹ)AlphaLinux
    fort77

    ㅁ)AlphaLinux NDP
    fortran77

    ㅂ)IntelLinux GNU
    g77

    Compile 실패

    0.3000  0.000561
    0.3067  0.000599
    0.3133  0.000638
    0.3200  0.000680
    0.3267  0.000723
    0.3333  0.000767
    0.3400  0.000814
    0.3467  0.000863
    0.3533  0.000913
    0.3600  0.000965
    0.3667  0.001019
    0.3733  0.001076
    0.3800  0.001134
    0.3867  0.001194
    0.3933  0.001256
    0.4000  0.001321

    0.3000  0.000561
    0.3067  0.000599
    0.3133  0.000638
    0.3200  0.000680
    0.3267  0.000723
    0.3333  0.000768
    0.3400  0.000814
    0.3467  0.000863
    0.3533  0.000913
    0.3600  0.000965
    0.3667  0.001019
    0.3733  0.001076
    0.3800  0.001134
    0.3867  0.001194
    0.3933  0.001256
    0.4000  0.001321


     

3. Relaxation Method를 이용한 비교

    Relaxation Method는 Two point Boundary Value문제를 다룰 때 사용하는 방법이다. 약간의 보충 설명을 하겠다. 처음 아주 초기값 두 개를 알고 아주 추상적인 함수를 알고 있는 상태에서 출발한다. 보통 2계 미분(두 번 미분한 함수라고 생각하기 바랍니다) 형태의 함수를 필자는 다룬다. 그 다음, 필자는 추상적인 함수에서 간단한 함수를 정하여 구하고 싶은 값이 나올 수 있도록 식을 만들어 간다. 이때, 필자는 자세한 정보는 모르고, 대충 비슷한 부분만을 컴퓨터에게 가르쳐주고, 나머지는 컴퓨터가 알아서 찾도록 하는 것이다. 즉, 인간의 힘으로는 예측할 수 없고 반목작업과 초기 조건들만을 사용하여 값을 찾는 것이다.
    다음의 Source를 보자.
    위의 Source에 대한 분석 및 초기 조건들은 생략하겠다.
    기준은 data-sparc(Solaris f77사용)으로 하겠다.

    ccccccccccccccccccccccccccccccccc

    cc           Relaxation                         cc
    cc           w; division                         cc
    cc     Very funny function...                cc
    cc     -3(x+1)-7+(3*3.141592/2+3)     cc

    cccccccccccccccccccccccccccccccccc

             PARAMETER (NSTEP=100)
             DIMENSION PHI(0:NSTEP),S(0:NSTEP)

             READ*,OMEGA

             IF (OMEGA.LE. 0) STOP

             H=3.141592/2./NSTEP
             dif=4./100.
             DO 10 IX=0.NSTEP

                             X=IX*H
    c                       S(IX)=-1*H*H*(-7*sin(X)-3*cos(X))
                             s(IX)=-1*H*H*(-3.*(X+1.)-7.+(3.*3.141592/2.+3.))
                             PHI(IX)=3. + dif*IX
    10      CONTINUE

              DO 20 ITER=1,5000
                             DO 15 IX=1,NSTEP-1
                                       PHIP=(PHI(IX-1)+PHI(IX+1)+S(IX))/2
                                       PHI(IX)=(1.-OMEGA)*PHI(IX)+OMEGA*PHIP
    15                      CONTINUE
    20       continue
               do 40 ix=1,NSTEP-1
                                 step=h*IX
                                 print*,step,PHI(IX)
    40        continue

               END

     

    Alpha fort77을 제외한 나머지 graph는 눈으로 차이를 확인할 수 없을 정도로 비슷한 형태로 출력되었다. graph에 대한 설명을 하겠다. 필자가 원한 graph는 REAL graph이다. 그리고 나머지 graph는 컴퓨터가 유추해낸 graph이다. 필자의 프로그래밍 실력이 부족(^^;)하여 완벽한 형태의 graph로 컴퓨터의 유추를 이끌어내지는 못하였다. 이제 data의 분석을 하겠다.
    아래의 data는 'data graph'의 리스트이다.

     

    ◆ 각 데이터 값 비교
     

    ㄱ)Solaris

    ㄴ)SparcLinux
    f77(Sun)

    ㄷ)SparcLinux
    fort77

    1.57080E-02   3.08720
    3.14159E-02   3.17382
    4.71239E-02   3.25985
    6.28318E-02   3.43529
    7.85398E-02   3.43012
    9.42478E-02   3.51433
        0.109956     3.59790
        0.125664     3.68083
        0.141372     3.76311
        0.157080     3.84472
        0.172788     3.92565
        0.188496     4.00590
        0.204203     4.08544
        0.219911     4.16427
        0.235619     4.24237
        0.251327     4.31974
        0.267035     4.39636
        0.282743     4.47222
        0.298451     4.54731
        0.314159     4.62162
        0.329867     4.69513

    1.57080E-02   3.08720
    3.14159E-02   3.17382
    4.71239E-02   3.25985
    6.28318E-02   3.43529
    7.85398E-02   3.43012
    9.42478E-02   3.51433
        0.109956     3.59790
        0.125664     3.68083
        0.141372     3.76311
        0.157080     3.84472
        0.172788     3.92565
        0.188496     4.00590
        0.204203     4.08544
        0.219911     4.16427
        0.235619     4.24237
        0.251327     4.31974
        0.267035     4.39636
        0.282743     4.47222
        0.298451     4.54731
        0.314159     4.62162
        0.329867     4.69513

    .0157080E-02   3.08719587
    .0314159E-02   3.1738162
    .0471239E-02   3.25985026
    .0628318E-02   3.43528804
    .0785398E-02   3.43011737
    .0942478E-02   3.51432514
      .109955721     3.59799991
      .125663683     3.6808331
      .141371638     3.7631104
      .157079607     3.84472156
      .172787562     3.92565393
      .188495517     4.00590561
      .204203486     4.08543777
      .219911441     4.16426802
      .235619411     4.24237061
      .251327366     4.31973696
      .267035335     4.39635658
      .282743275     4.47221708
      .298451245     4.54730749
      .314159214     4.62161514
      .329867154     4.69512892

    ㄹ)AlphaLinux
    fort77

    ㅁ)AlphaLinux NDP
    fortran77

    ㅂ)IntelLinux GNU
    g77

    Compile 실패

    1.5707960E-02   3.087193
    3.1415921E-02   3.173813
    4.7123879E-02   3.259846
    6.2831841E-02   3.435282
    7.8539796E-02   3.430110
    9.4247758E-02   3.514318
        0.1099557      3.597894
        0.1256637      3.680826
        0.1413716      3.763103
        0.1570796      3.844713
        0.1727876      3.925645
        0.1884955      4.005988
        0.2042035      4.085429
        0.2199114      4.164259
        0.2356194      4.242362
        0.2513274      4.319731
        0.2670353      4.396352
        0.2827433      4.472212
        0.2984512      4.547301
        0.3141592      4.621609
        0.3298672      4.695122

    0.0157079604   3.08719468
    0.0314159207   3.17381525
    0.0471238792   3.25985003
    0.0628318414   3.43528685
    0.0785398036   3.43011498
    0.0942477584   3.514323
    0.109955721     3.59789801
    0.125663683     3.68082976
    0.141371638     3.76310611
    0.157079607     3.8447156
    0.172787562     3.92564702
    0.188495517     4.00598942
    0.204203486     4.08542919
    0.219911441     4.16425705
    0.235619411     4.24236012
    0.251327366     4.31972647
    0.267035335     4.39634562
    0.282743275     4.47220564
    0.298451245     4.54729605
    0.314159214     4.62160254
    0.329867154     4.69511509


    위의 data list를 보면 참 재미있는 현상을 비교할 수 있다. 눈에 바로 들어오는 것이 바로 유효 자리수이다. 필자는 π값으로 3.141592로 소수 6자리까지 주었다. 그러나 각 컴파일러별로 기본 유효 자리수가 달랐다. NDP나 Sun f77은 유효자리수를 감안하여 출력을 하였다. GNU g77이나 fort77은 유효 자릿수 6자리를 넘어서까지 출력을 하였다. 그리고, 또 한 가지 흥미로운 것은 Sun f77은 NDP f77과 비교할 때, Sun f77이 소수 6자리의 값을 그냥 버리는 경향을 띠고 있다. 이 프로그램은 유효 자릿수에 대한 정의를 하지 않았음을 밝힌다.

     

4. Fast Fourier Transform(FFT)를 사용한 비교 분석

    소스는 너무 긴 관계로 생략하겠다. 이론은 간단하다. Delta Function 형태를 지닌 함수를 Fourier 변환을 취하여 plot한 graph를 비교한다. 그런데 보통의 Fourier 변환식을 그대로 프로그래밍하면, 오차율도 크고 쓸데없는 계산을 많이 한다. 그래서 FFT라는 것을 사용하여 프로그래밍한다.

     

    ◆ 각 데이터 값 비교

    이 프로그램 소스는 유효자리수 및 오차를 일으킬 부분을 미연에 방지하도록 제작된 소스이다. 필자가 보아서는 data의 차이가 없다. 위의 3개의 소스와 다른 점은 오차를 일으킬 부분에 대한 수정 루틴이 들어갔고, 유효 범위에 대한 정의를 내렸다. 그리고 다른 소스보다 몇 배 더 길다는 점이다. (만약, 이 data의 소스를 원하시는 분은 필자에게 e-mail을 보내시기 바랍니다.)
     

    ㄱ)Solaris

    ㄴ)SparcLinux
    f77(Sun)

    ㄷ)SparcLinux
    fort77

    507     2.7053816319
    508     2.7100114822
    509     2.7136235237
    510     2.7162096500
    511     2.7177634239
    512     2.7182817459
    513     2.7177634239
    514     2.7162096500
    515     2.7136235237
    516     2.7100114822
    517     2.7053816319

    507     2.7053816319
    508     2.7100114822
    509     2.7136235237
    510     2.7162096500
    511     2.7177634239
    512     2.7182817459
    513     2.7177634239
    514     2.7162096500
    515     2.7136235237
    516     2.7100114822
    517     2.7053816319

    507     2.7053816319
    508     2.7100114822
    509     2.7136235237
    510     2.7162096500
    511     2.7177634239
    512     2.7182817459
    513     2.7177634239
    514     2.7162096500
    515     2.7136235237
    516     2.7100114822
    517     2.7053816319

    ㄹ)AlphaLinux
    fort77

    ㅁ)AlphaLinux NDP
    fortran77

    ㅂ)IntelLinux GNU
    g77

    Compile 실패

    507     2.7053816319
    508     2.7100114822
    509     2.7136235237
    510     2.7162096500
    511     2.7177634239
    512     2.7182817459
    513     2.7177634239
    514     2.7162096500
    515     2.7136235237
    516     2.7100114822
    517     2.7053816319

    507     2.7053816319
    508     2.7100114822
    509     2.7136235237
    510     2.7162096500
    511     2.7177634239
    512     2.7182817459
    513     2.7177634239
    514     2.7162096500
    515     2.7136235237
    516     2.7100114822
    517     2.7053816319

     

    이제 정리를 하겠다. 위의 Data를 비교해보면 알겠지만, 고가 제품인 Sparc과 비교했을 때, Alpha나 Intel계열에서도 신뢰할 수 있는 값을 얻을 수 있다는 것을 알 수 있을 것이다. Linux를 탑재한 machine들은 수치 계산기로서 탁월한 성능을 발휘한다. 값비싼 Sun Microsystem사의 f77을 사용하지 않더라도 Linux를 사용하는 user들은 값싼 GNU tool들을 사용하여 수치계산을 할 수 있다. 그리고 여기서 한가지 더 주목할 만한 사항은, SparcLinux에서는 SunOS binary가 오류없이 잘 돌아간다는 사실을 알 수 있다. (Sun Fortran77이 SparcLinux에 설치되었는데, Sun f77은 SunOS binary이다) 이 작업을 하면서 몇 가지 아쉬운 점이 있었다. 한가지는 AlphaLinux에서 g77 설치에 실패하여 g77 tool들의 performance가 그렇게 좋지 않다는 것이다. 그래서 필자는 NDP fortran을 구하여 이렇게 테스트를 하게 된 것이다.
    NDP fortran은 AlphaLinux에서 돌아가는 상용 Fortran Compiler이다. 마지막으로 필자는 Linux가 수치 계산기로서 탁월한 성능을 발휘한다는 것을 강조하면서 분석을 마치겠다. 혹시, AlphaLinux에서 위의 컴파일을 실패하면서 나온 에러 메시지에 대한 뜻을 아시는 분은 연락을 주세요.
    필자의 E-mail :
    reduck96@landau.scu.ac.kr
                          
    reduck96@monster.scu.ac.kr
                          
    REDUCK96@hitel.net

    Compiler error line 18 of : floating exception during constant evaluation; cannot recover /usr/bin/fort77: aborting compilation

     

    참고문헌
    1. Numerical Recipes in FORTRAN The Art of Scientific Computing, Second Edition
    2. Classical dynamics of particles and system, Fourth edition, Marion
    3. Computational Physics Fortran edition, Steven E. Koonin/Dawn C. Meredith




▲ top

home으로...