( hg2ecz | 2020. 03. 26., cs - 09:08 )

Szerkesztve: 2020. 03. 26., cs - 09:28

Érdekességként megjegyzem, hogy
1. FORTH alapból nem támogat floating pointot, ezért ha FORTH-ban is szeretném ugyanezt az algoritmust, az integeres aritmetikával lesz.
2. Rust-ban próbaképpen integeres aritmetikára áttérve 1,75-szörös tempó Ivy bridge architektúrán.
        AArch64 architektúrán (Odroid-C2) sokkal nagyobb a különbség az integer és float között. Integer kb. x86 laptop proci tempóval szalad.
             - Integer 1250 msec, double 5160 msec

$ rustc -O pi_integer.rs   # lefordítjuk
$ time ./pi_integer
900 millisec
Pí közelítés: 3.1415927
real    0m0,905s

use std::time::Instant;

fn main() {
    let mut result: i32 = 0; // összegváltozó
    let mut nevezo = 1; // nevező
    let mut sign = 800_000_000; // számláló

    let t0 = Instant::now();
    for _i in 0..300_000_000 {
        result += sign / nevezo;
        nevezo += 2;
        sign = -sign;
    }
    let elapsed_time = t0.elapsed();

    println!("{} millisec", elapsed_time.as_millis());
    println!("Pí közelítés: {}\n", result as f64/200_000_000.);
}

Következő lépésként jöhet a múltbeli szépséggel való játék. Vajon hogyan néz ki ez az egyszerű algoritmus FORTH-ban?
A gforth program 64 bites előjeles típussal dolgozik. Lássuk:

$ time ./pi_forth.fth
3141592650181456395
real    0m10,460s

#! /usr/bin/gforth

VARIABLE RESULT
VARIABLE NEVEZO
VARIABLE SSIGN

: PICALC
    0 RESULT !
    1 NEVEZO !
    8000000000000000000 SSIGN !

    300000000 0 DO
        SSIGN @ NEVEZO @ / RESULT +!
        2 NEVEZO +!
        0 SSIGN @ - SSIGN !
    LOOP
    RESULT @ 2 / .
;

PICALC
cr
bye

De az iménti FORTH program tovább optimalizálható, ha eljáráshívások helyett az alacsony szintű stack aritmetikára erőteljesebben támaszkodunk.

$ time ./pi_forth_opt.fth
3141592650181456395
real    0m8,884s            # előbbi 10,460s helyett

#! /usr/bin/gforth

VARIABLE RESULT
VARIABLE NEVEZO

: PICALC
    0 RESULT !
    1 NEVEZO !
    8000000000000000000 \ ez nem SSIGN regiszterbe kerül, hanem a stackbe

    300000000 0 DO
        DUP
        NEVEZO @ / RESULT +!
        2 NEVEZO +!
        0 SWAP -
    LOOP
    RESULT @ 2 / .
;

PICALC
cr
bye

és hasonlóképpen a többi változót (amely engedi magát) ahogy stack-esre átírjuk, úgy lesz
   1.) átláthatatlanabb
   2.) ám gyorsabb futású