atarionline.pl Action! (+ benchmarks comparision) - Forum Atarum

    Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

    • :
    • :

    Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

      • 1: CommentAuthorzbyti
      • CommentTime26 Feb 2020 18:02 zmieniony
       
      Real Sieve Turbo Basic XL

      Millfork              YoshPlus:41921 iterations in 100 ticks
      CC65 YoshPlus:41844 iterations in 100 ticks
      Mad Pascal YoshPlus:35572 iterations in 100 ticks
      Action! YoshPlus:33239 iterations in 100 ticks
      Quick 2.2 YoshPlus:21320 iterations in 100 ticks
      Quick 1.6 YoshPlus:16242 iterations in 100 ticks
      PL65 YoshPlus: 4708 iterations in 100 ticks
      FastBasic FBI YoshPlus: 2427 iterations in 100 ticks
      fig-Forth 1.1 YoshPlus: 715 iterations in 100 ticks
      CLSN Pascal YoshPlus: 487 iterations in 100 ticks

      Millfork Chessboard: 79 iterations in 150 ticks
      CC65 Chessboard: 76 iterations in 150 ticks
      Mad Pascal Chessboard: 40 iterations in 150 ticks
      Action! Chessboard: 35 iterations in 150 ticks
      Quick 2.2 Chessboard: 27 iterations in 150 ticks
      Quick 1.6 Chessboard: 16 iterations in 150 ticks
      PL65 Chessboard: 12 iterations in 150 ticks
      • 2: CommentAuthoremka
      • CommentTime27 Feb 2020 00:02
       
      Tak patrzę na ten algorytm liczenie sita Eratostenesa i wydaje mi się że sprawdzanie liczb parzystych czy są pierwsze jest trochę bez sensu. Niewielka zmiana algorytmu omijająca liczby parzyste dla ACTION! wygląda mniej więcej tak.
      BYTE RTCLOK2=19,RTCLOK3=20
      BYTE ARRAY FLAGS(8192)
      CARD COUNT,I,END,KROK

      PROC SIEVE()
      RTCLOK2=0
      RTCLOK3=0
      COUNT=1

      FOR I=1 TO 8191 STEP 2
      DO
      FLAGS(I)=1
      OD
      FOR I=3 TO 91 STEP 2
      DO
      IF FLAGS(I) THEN
      ; PRINTF("%U ",I)
      END=I*I
      KROK=I+I
      WHILE (END < 8192)
      DO
      ; PRINTF("%U ",END)
      FLAGS(END)=0
      END==+KROK
      OD
      FI
      OD
      END=RTCLOK2*256+RTCLOK3
      FOR I=3 TO 8191 STEP 2
      DO
      IF FLAGS(I)THEN
      COUNT==+1
      ; PRINTF("%U ",I)
      FI
      OD
      PRINTF("%E %U LICZB PIERWSZYCH W CZASIE",COUNT)
      PRINTF("%E %U RAMEK",END)
      RETURN

      Daje to całkiem niezłe przyspieszenie ale w benchmarkach to chyba nie ma znaczenia. Tam ważne jest by wszyscy używali tego samego algorytmu.
      • 3: CommentAuthorzbyti
      • CommentTime27 Feb 2020 00:02
       
      @emka BRAWO! :D
      • 4: CommentAuthorzbyti
      • CommentTime27 Feb 2020 02:02 zmieniony
       
      MMG Basic Compiler 2.0 [Int]
      ABC BASIC Compiler 1.05
      U-BASIC
      • 5: CommentAuthorzbyti
      • CommentTime27 Feb 2020 11:02 zmieniony
       
      Wyłonił się najszybszy z BASIC-ów na małe Atari FasBasic 4.0 FBI z najmniejszym chyba kodem wynikowy po kompilacji.

      FastBasic użyłem natywnie ale też jest crosscompilator.

      Dorzuciłem wyniki @drac030 dla U-BASIC.

      ? "STARTING FASTBASIC..."
      STIME = TIME
      DIM FLAGS(8190) BYTE
      MSET ADR(FLAGS), 8190,0
      FOR N=2 TO 91
      IF NOT FLAGS(N)
      FOR K=N*N TO 8190 STEP N
      FLAGS(K)=1
      NEXT K
      ENDIF
      NEXT N
      ETIME = TIME
      ? "JIFFIES: ";ETIME-STIME
      COUNT=0
      FOR N=2 TO 8191
      IF NOT FLAGS(N)
      COUNT=COUNT+1
      ENDIF
      NEXT N
      ? "PRIMES: ";COUNT

      EDIT:
      Sprawdziłem jeszcze:
      ./fastbasic-int RESIEVE.FBI fbisieve.asm
      cl65 -t atari -C fastbasic.cfg fbisieve.asm -o fbisieve.xex fastbasic-fp.lib

      i w wyniku uzyskałem 314 ticks na jeden obieg.
      • 6: CommentAuthorzbyti
      • CommentTime27 Feb 2020 14:02 zmieniony
       
      Jako, że skończyłem swoje testy to małe podsumowanie z mojej strony.

      Jak zacząłem tę zabawę to myślałem o jakimś art. na AOL skompilowanym z wypowiedzi szanownych ekspertów udzielających się na tym forum, jednak wraz z rozwojem wątku udzielający się panowie zaspokoili moją ciekawość albo zalinkowali strony gdzie doczytałem co mnie interesowało.

      REAL SIEVE nie kontynuuję bo widać, że nie zachwiał on jakoś dramatycznie stosunku szybkości między językami (bo niby dlaczego?) i jest tylko dodatkowym porównaniem.

      Bardzo spodobał mi się FORTH, ale jak to ktoś skomentował, ten program robi z człowieka parser ;) Jego wydajność ~20x szybsza od Atari BASIC'a nie skłoniła mnie do dalszej zabawy. Doczytam tylko o nim to co mi zostało w Tajemnicach Atari.

      Jak pisać w BASIC-u to są realnie tylko dwie opcje: FastBasic - najlepiej jako corsscompilator (mały runtime w stosunku do innych) albo Advan Basic z jego optymalizatorem który przybliża prędkość wykonywania kodu do tej znanej z Action! :]

      Co dalej?

      Nauczę się Action! i w nim trochę po programuję, tylko w jednym celu: by się oswoić z mapą pamięci Atari. Sam język wymaga jednak wiedzy co nie działa w jego kompilatorze (modulo na CARD etc.).

      Docelowo będę pisał w Mad Pascalu (silnik szachów mogę pisać we Free Pascalu a potem bez bólu przenieść na A8), nie wymaga on ode mnie tyle specyficznej wiedzy co CC65 kosztem odrobinę mniejszej wydajności, a przecież @tebe nie powiedział jeszcze ostatniego słowa! :]

      Może zechcę też kiedyś wrócić do C64 to tam jest Rascal, więc będę miał z górki ;)

      Honourable mention: PL65 wydaje się być kompletny i dość szybki.

      Rozczarowanie roku: Qucik 2.2 ;) ale i tak pewnie jeszcze do niego wrócę ;)

      Na emeryturze: ASM :]
      • 7:
         
        CommentAuthorjhusak
      • CommentTime27 Feb 2020 17:02
       
      Gratulacje że Ci się chciało być pionierem w dziedzinie owianej mglistym mistem.
      Jestem pod wrażeniem i dało mi to kopa do dalszego rozkminiania.
      • 8: CommentAuthorzbyti
      • CommentTime27 Feb 2020 18:02 zmieniony
       
      @jhusak fajnie, że Cię to pobudziło do myślenia nad tą materią :] Kto wie, może coś się z tego urodzi w Twojej głowie? :]

      Na AtariAge twórca Basic++ podesłał swoje wyniki dla Real Sieve, za jakiś czas uzupełnię o nie tabelę i wstawię tutaj wraz z arkuszem do dalszego uzupełniania.

      thorfdbg:

      Basic++, with Os++ gives me 3874 jiffies, 1028 primes. You are likely using the original Os, with the original (slow) mathpack.

      With the mathpack patch, it is down to 2726 jiffies.

      Actually, this is version 1.08, but this should not make much of a difference.

      Faktycznie nie podmieniałem OS na OS++.
      • 9: CommentAuthorzbyti
      • CommentTime27 Feb 2020 18:02 zmieniony
       
      Millfork              YoshPlus:41921 iterations in 100 ticks
      CC65 YoshPlus:41844 iterations in 100 ticks
      Mad Pascal YoshPlus:35572 iterations in 100 ticks
      Action! YoshPlus:33239 iterations in 100 ticks
      Quick 2.2 YoshPlus:21320 iterations in 100 ticks
      Quick 1.6 YoshPlus:16242 iterations in 100 ticks
      PL65 YoshPlus: 4708 iterations in 100 ticks
      FastBasic FBI YoshPlus: 2427 iterations in 100 ticks
      fig-Forth 1.1 YoshPlus: 715 iterations in 100 ticks
      CLSN Pascal YoshPlus: 487 iterations in 100 ticks

      Millfork Chessboard: 79 iterations in 150 ticks
      CC65 Chessboard: 76 iterations in 150 ticks
      Mad Pascal Chessboard: 40 iterations in 150 ticks
      Action! Chessboard: 35 iterations in 150 ticks
      Quick 2.2 Chessboard: 27 iterations in 150 ticks
      Quick 1.6 Chessboard: 16 iterations in 150 ticks
      PL65 Chessboard: 12 iterations in 150 ticks

      • 10: CommentAuthorxxl
      • CommentTime27 Feb 2020 20:02
       
      gdzie mozna zobaczyc zrodlo dla atari basica dajace te 7484 ticks ?
      • 11: CommentAuthorzbyti
      • CommentTime27 Feb 2020 20:02 zmieniony
       
      @xxl z 10x wklejałem jako zrzut ekranu. Wersja dla TBA i kompilatorów to ten sam kod.

      10 A=4096*5:C=8190:B=A+C:COUNT=0
      20 POKE 20,0:POKE 19,0
      30 FOR I=A TO B:POKE I,0:NEXT I
      40 FOR N=2 TO 91
      45 Z=N+A
      50 IF PEEK(Z)=1 THEN 90
      60 FOR K=N*N TO 8190 STEP N
      70 POKE K+A,1
      80 NEXT K
      90 NEXT N
      95 TIME=PEEK(20)+256*PEEK(19)
      100 PRINT TIME;" JIFFIES"
      200 FOR N=2 TO 8191
      210 IF PEEK(N+A)=0 THEN COUNT=COUNT+1
      215 NEXT N
      220 PRINT COUNT;" PRIMES"

      Tylko dla Atari BASIC'a A=4096*2 chyba ;)

      Chociaż teraz regularnie wyrzuca mi 7711 ciekawe dlaczego? Nie będę już poprawiał tabelki bo aż tak to nie wpływa na ostateczny wyinik.
      • 12: CommentAuthorxxl
      • CommentTime27 Feb 2020 20:02
       
      daje 1027 primes - to jest prawidlowy wynik?
      • 13: CommentAuthorzbyti
      • CommentTime27 Feb 2020 20:02 zmieniony
       
      @xxl wyedytowałem źródło. Wrzuć jeszcze raz. Pętla zliczającą miała o 1 za małą górną granicę.

      Prawidłowy wynik to 1028.

      Wcześniej miałem :



      Ciekawe skąd ta różnica prawie 300 ramek... PAUSE?

      Jedyna różnica, że wtedy wklepałem a teraz wgrałem za pomocą:

      ENTER "H6:plik.bas"

      I mam już 7711 :D
      • 14: CommentAuthorxxl
      • CommentTime27 Feb 2020 20:02
       
      dajac ta poprawke o ktorej pisalem ten algorytm wyciaga dla atari basic standardowy fp:

      j: 4344
      primes: 1028
      • 15: CommentAuthorzbyti
      • CommentTime27 Feb 2020 20:02 zmieniony
       
      @xxl wklej kod to uzupełnię tabelkę z info o Twojej poprawce tutaj i na Atari Age :]

      Oczywiście zaktualizuję TBA i inne kompilowane.

      Wpis na na AA zacznę tak "Notorious @xxl made a good improvement and speed up my code." ;)
      • 16:
         
        CommentAuthorKaz
      • CommentTime27 Feb 2020 20:02
       

      Zbyti:

      Jak zacząłem tę zabawę to myślałem o jakimś art. na AOL skompilowanym z wypowiedzi szanownych ekspertów udzielających się na tym forum, jednak wraz z rozwojem wątku udzielający się panowie zaspokoili moją ciekawość albo zalinkowali strony gdzie doczytałem co mnie interesowało.


      Chciałeś pytać ekspertów o opinie, a sam zostałeś większym ekspertem :). Artek podsumowujący byłby jednak i tak bardzo fajnym zwieńczeniem testów!
      • 17: CommentAuthorzbyti
      • CommentTime27 Feb 2020 21:02 zmieniony
       
      @Kaz niestety ekspertem nie zostałem, tylko wiem więcej niż na początku ;)

      @tebe, @jhusak, @ilmenit, @pirx, @mono pewnie także @mgr_inz_rafal wciąż mają wiedzę ode mnie większą o przynajmniej 2 rzędy wielkości w kwestii tego jak działają kompilatory :]

      @laoo i @antrykot to też widać niebanalni koderzy którzy mogą coś wiedzieć na ten temat więcej (ode mnie na pewno) :]

      @xxl pewnie wie ale nie powie ;P

      Gdyby zechcieli odpowiedzieć na parę tych samych pytań drogą pocztową (nie tutaj, by się nie sugerować nawzajem i nie wszczynać od razu dyskusji) to może bym coś z tego skompilował, sam nie czuję się na siłach.
      • 18:
         
        CommentAuthorKaz
      • CommentTime27 Feb 2020 21:02
       
      Zapodaj pytania, będziemy ich nękać o odpowiedzi :D
      • 19: CommentAuthorzbyti
      • CommentTime27 Feb 2020 21:02 zmieniony
       
      @Kaz przemyślę je pod kątem ew. artykułu (a nie tego co sam chciałem wiedzieć) i jak spiszę dam znać :]
      • 20:
         
        CommentAuthormav
      • CommentTime27 Feb 2020 21:02
       
      Czyli pewnie za ~2 godzinki będzie :>
      • 21: CommentAuthorzbyti
      • CommentTime27 Feb 2020 21:02 zmieniony
       
      @mav dobra, przekonałeś mnie, pytania będą na poniedziałek dziś idę w OFF ;)
      • 22: CommentAuthorxxl
      • CommentTime27 Feb 2020 21:02
       
      optymalizacje z AtariBasic z ksiazki wydanej przez Duddieo:

      j: 3527
      primes: 1028
      • 23: CommentAuthorzbyti
      • CommentTime27 Feb 2020 22:02
       
      There are two ways to clean out the string. The program below simply DIMensions a string to 1000 and then fills the string with "*" using a FOR/NEXT loop. Then it prints the string.

      100 DIM B$(1000)
      110 FOR A=1 TO 1000
      120 B$(A,A)="*"
      130 NEXT A
      140 PRINT B$

      The next program does the same thing a little differently and much more effeciently.

      100 DIM B$(1000)
      110 B$="*":B$(1000)="*":B$(2)=B$
      120 PRINT B$

      String Arrays ->link<-
      • 24: CommentAuthorxxl
      • CommentTime27 Feb 2020 22:02
       
      3 dni temu...

      xxl:

      no ale skoro optymalizowac to zamiast:

      f.i=1to8191:flag$(i,i)="T":n.i

      prosze zapisac:

      flag$="T":flag$(8191)=flag$:flag$(2)=flag$

      zdaje sie od zawsze ten trik dziala...
      • 25: CommentAuthorzbyti
      • CommentTime27 Feb 2020 22:02 zmieniony
       
      Wiem, że trzy dni temu ale dla kogoś kto nie czytał o tym tricku jest to niezrozumiałe.

      Dopiero nie podając teraz kodu a tylko wyniki zmusiłeś mnie ;) do poszukania o co chodzi.

      Tej książki od Duddiego nie mam i nie czytałem. Basica w sumie to nigdy nie używałem na poważnie.

      10 POKE 20,0:POKE 19,0:COUNT=0
      20 DIM F$(8191):F$="F":F$(8191)="F":F$(2)=F$
      30 FOR N=2 TO 91
      40 IF F$(N,N)="T" THEN 80
      50 FOR K=N*N TO 8190 STEP N
      60 F$(K,K)="T"
      70 NEXT K
      80 NEXT N
      90 TIME=PEEK(20)+256*PEEK(19)
      100 PRINT TIME;" JIFFIES"
      200 FOR N=2 TO 8191
      210 IF F$(N,N)="F" THEN COUNT=COUNT+1
      220 NEXT N
      230 PRINT COUNT;" PRIMES"

      Musiałeś coś więcej pokombinować bo mi wyrzuca 5659 ramek.

      Jeżeli odrzucałeś parzyste to nie zaliczam do kategorii benchmarku który mogę użyć ;)
      • 26: CommentAuthorxxl
      • CommentTime27 Feb 2020 22:02
       
      a kolejny krok?

      flags=adr(flag$)

      ?
      • 27:
         
        CommentAuthormav
      • CommentTime27 Feb 2020 22:02
       
      Ciekawe, wkleiłem to w altirrę i wyszło
      2169 JIFFIES
      1028 PRIMES

      mam ustawione 65xe/130xe i Altirra 8K BASIC 1.51
      • 28: CommentAuthorxxl
      • CommentTime27 Feb 2020 22:02
       
      altirra os altirra basic

      J:1098
      • 29: CommentAuthorzbyti
      • CommentTime28 Feb 2020 00:02 zmieniony
       
      No nie mam pojęcia jak to przyspieszyłeś do 3527 zachowując ten sam algorytm.

      Naprawdę nie opuszczasz parzystych? Mnożenie jakoś przyspieszasz?

      Wrzuciłem jeszcze screen z TB XL interpretowany.

      10 POKE 20,0:POKE 19,0:COUNT=0
      20 DIM F$(8192):F$="F":F$(8192)=F$:F$(2)=F$:X=ADR(F$)
      30 FOR N=2 TO 91
      40 IF PEEK(N+X)=1 THEN 80
      50 FOR K=N*N TO 8190 STEP N:POKE K+X,1
      70 NEXT K
      80 NEXT N
      90 TIME=PEEK(20)+256*PEEK(19)
      100 ? TIME;" TICKS"
      200 FOR N=2 TO 8191
      210 IF PEEK(N+X)=70 THEN COUNT=COUNT+1
      220 NEXT N
      230 ? COUNT;" PRIMES"
      • 30: CommentAuthorzbyti
      • CommentTime28 Feb 2020 00:02 zmieniony
       
      Jedno jest pewne...

      W każdym języku powinno się zadeklarować tablicę i ją w pętli wypełnić. Bo tak to jedne języki mają specjalizowane funkcje inne nie i to zaburza wynik.

      Może dla tych najszybszych języków zrobię taki uspójniony test bez korzystania z ficzerów danego języka (o ile tak zrobiłem, przypominam sobie tylko coś takiego w FastBasic) i wtedy ewentualnie podam wyniki jeszcze raz.

      @xxl namieszałeś ;) ale dzięki :D Kodu nie podajesz jak rozumiem bym go nie piracił? :D ;P

      EDIT: dobra ja już kończę w tym wątku, nie ma co się rozdrabniać. Warto rozmawiać o kompilatorach w dedykowanym wątku.
      • 31: CommentAuthorzbyti
      • CommentTime28 Feb 2020 01:02 zmieniony
       
      • 32: CommentAuthorxxl
      • CommentTime28 Feb 2020 09:02 zmieniony
       
      jaki basic, jaki rom?

      tu jest atari basic ale OSROM Altirra:



      gdzie mozna pobrac OSROM z podmienionymi procedurami matematycznymi?

      ===
      jest coraz lepiej. podejrzana byla taka dysproporcja jak na poczatku w tabeli porownawczej.
      • 33: CommentAuthorxxl
      • CommentTime28 Feb 2020 09:02
       
      ciekawe...
      XLOS v4 (xlgs) = 3528
      XLOS v4 (a800xl) = 3524
      • 34: CommentAuthorzbyti
      • CommentTime28 Feb 2020 10:02 zmieniony
       
      @xxl nie podmieniałem OS. Wszystko w standardzie.

      -----------------------------

      Aby wyniki benchmarka były porównywalne trzeba by:

      1. BASIC zmienić trick na powrót w pętelkę (w sumie oznacza to olać wyniki powstałe po ostatniej tabelce)
      2. CC65 memset(flags, true, sizeof(flags)) na pętelkę
      3. FastBasic MSET ADR(FLAGS), 8190,0 na pętlekę
      4. Advan Basic w ogóle zrobić taką pętlę.
      5. Mad Pascal fillchar(flags, sizeof(flags), true);

      W reszcie języków jest zachowany ten krok. Niepotrzebnie napisałem, że idziemy na szybkość...
      • 35: CommentAuthorxxl
      • CommentTime28 Feb 2020 10:02
       
      jak chcesz wkazac ze interpretery sa wolniejsze to po co robic jakies wszukane algorytmy... zrob petle for z mnozeniem :-) wynik proporcjonalny bedzie taki sam ;-)

      jesli chcesz robic test szybkosci jezykow to musisz w ramach alorytmu korzystac ze specyficznych cech tych jezykow...
      • 36: CommentAuthorzbyti
      • CommentTime28 Feb 2020 10:02 zmieniony
       
      Algorytm nie jest wyszukany tylko oddaje poprawną ilość liczb pierwszy w przedziale od 0 do 8191 włącznie. Pierwszy tego nie robił.

      A samo benchmark z "pracą" w pętli był i nazywa się YoshPlus :]

      Wystarczy, że w wyżej wymienionych językach zrobię tak jak w pozostałych przygotowanie tablicy do pracy.

      Jak idziemy na szybkość to opuszczajmy parzyste tak jak zapozorował to @emka.

      ->link<- tutaj autor zapełnia ekran w GR8 jako test bo SIEVE mu się nie podoba.
      • 37: CommentAuthorzbyti
      • CommentTime28 Feb 2020 10:02 zmieniony
       
      • 38: CommentAuthorxxl
      • CommentTime28 Feb 2020 10:02
       
      niczego nie opuszczalem.

      --
      oczywiscie mozesz przyotowac testy tak, zeby jezyki interpretowane zamiast zajmowac sie zadaniem bily sie z interpretacja listingu ;-) i porownywac wyniki z jezykami kompilowanymi :-)
      • 39: CommentAuthorzbyti
      • CommentTime28 Feb 2020 10:02 zmieniony
       
      Wiesz co zrobię?

      Wyrzucę ten dyskusyjny krok zapełniani tablicy wartością domyślną po za mierzenie czasu.

      Czas będę mierzył tylko dla głównego fora ustawiającego flagi.

      Do rzucę jeszcze do tych jiffies końcowe zliczanie liczb pierwszych i będzie mi się zgadzało w kwestii testowania obciążenia :D
      • 40: CommentAuthorxxl
      • CommentTime28 Feb 2020 11:02
       
      a moze przed PRINT i mierzyc czas operacji I/O ?

      spoko... po prostu nie wiem co chcesz mierzyc, bo narazie nic nie wskazuje na to ze sprawnosc tych jezykow.
      • 41: CommentAuthorzbyti
      • CommentTime28 Feb 2020 11:02 zmieniony
       
      @xxl jestem otwarty na propozycje, jaki test napisać by miarodajnie przeprowadzić dla tych języków test wydajności.

      Założenia:

      - operacje tylko na liczbach całkowitych
      - tylko dodawanie
      - if-y i wszelkie loops.

      To chyba oprócz tych BASIC-ów gdzie nie nie można wymusić intów będzie bez kontrowersji?

      YoshPlus spełniał te warunki :]

      Osobno mnożna zrobić test z mnożeniami bo z tego co czytam, rożnie sobie z tym autorzy kompilatorów radzą.

      ----------------------------

      EDIT:
      Po prostu po wszystkim jestem trochę mądrzejszy jak to zrobić bardziej miarodajnie :]

      Trzeba było się wtedy (na początku) odzywać a nie teraz ;P Ale lepiej późno niż wcale... :]
      • 42: CommentAuthorzbyti
      • CommentTime28 Feb 2020 11:02 zmieniony
       
      Dobra...

      Dzięki (albo przez) @xxl założę osobny wątek gdzie YoshPLus uzupełnię o BASIC-i.

      W teście na szybkość mnożenia będzie obliczanie silni bez rekurencji bo nie wszystkie języki mają.

      EOT :]