home *** CD-ROM | disk | FTP | other *** search
- /* Another pi-calc program.
- A good example of what optimizing using inline assembly can do:
- The E source is a translation of the original C source,
- which did 48 seconds on 250 decimals, the E version did 30 seconds.
- Then, the innermost loop was translated to inline assembly,
- this version (E+Asm) timed only 10 seconds (all on 7mhz).
- Only a small part needed to be translated to assembly,
- as that is where 99% of the calculation is performed */
-
- DEF m,k,n,p,i,max,nr,handle,out,num[50]:STRING,a:PTR TO LONG
-
- PROC main()
- WriteF('PI calc\n#of decimals (try 50-250): ')
- ReadStr(stdout,num)
- IF (nr:=Val(num,NIL))=0 THEN stop('Illegal #!\n')
- WriteF('Busy ... press CtrlC to abort.\n\n')
- max:=nr*16
- IF (a:=New(max))=NIL THEN stop('No mem!\n')
- m:=nr
- k:=m|*3.321-1|
- WriteF('\d\c',k,13)
- FOR n:=k TO 1 STEP -1
- a[0]:=a[0]+2
- p:=n*2+1
- MOVEQ #0,D7 /* D7=c */
- MOVE.L a,A0 /* A0=a array */
- MOVE.L m,D4 /* D4=i counter */
- MOVE.L p,D2
- MOVE.L n,D3
- l: MOVE.L D7,D0 /* this loop is hyper-optimized. */
- LSL.L #3,D0
- ADD.L D7,D0 /* the following is the original E equivalent */
- ADD.L D7,D0
- MOVE.L (A0),D1 /* c:=0 */
- MULU D3,D1 /* x:=a */
- ADD.L D1,D0 /* FOR i:=0 TO m */
- DIVU D2,D0 /* c:=10*c+(n*^x) */
- MOVE.L D0,D7 /* ^x:=c/p */
- EXT.L D0 /* c:=c-(^x*p) */
- MOVE.L D0,(A0) /* x:=x+4 */
- SWAP D7 /* ENDFOR */
- EXT.L D7
- ADDQ.L #4,A0
- DBRA D4,l
- IF (n AND $F)=0 /* not every loop */
- WriteF('\d \c',n,13)
- IF CtrlC() THEN stop('\n*** Calculation interrupted!\n')
- ENDIF
- ENDFOR
- FOR i:=m TO 1 STEP -1
- IF a[i]>9
- a[i]:=a[i]-10
- a[i-1]:=a[i-1]+1
- ENDIF
- ENDFOR
- handle:=Open('ram:pi.txt',1006)
- IF handle<>NIL
- out:=SetStdOut(handle)
- writenum()
- SetStdOut(out)
- Close(handle)
- WriteF('\n\nSee ram:pi.txt for output.\n')
- ELSE
- WriteF('Could not open file!\n')
- ENDIF
- WriteF('\n')
- writenum()
- ENDPROC
-
- PROC stop(messy)
- WriteF(messy)
- CleanUp(5)
- ENDPROC
-
- PROC writenum()
- WriteF('pi=3.')
- FOR i:=1 TO m DO WriteF('\d',a[i])
- WriteF('\n')
- ENDPROC
-