Niedoszły konkurs "Bajtka" by Kaz 2009-03-12 18:43:57

Tomasz "TDC" Cieślewicz znany jest ze swoich ciągotek publicystycznych. Prowadzi własny blog, wygłasza prelekcje na konwentach i dzieli się swoją wiedzą o Atari. W starych czasach fascynacja Atari objawiała się przede wszystkim udziałem w przedsięwzięciu pod nazwą "Atari Magazyn", gdzie TDC występował jako jeden z członków redakcji pisma. Dzisiaj o mniej znanym epizodzie - próbie współpracy z "Bajtkiem", która ostatecznie się nie powiodła. Ale odnotowuję ją nie tylko z powodów historycznych. Sprawa tyczy się bowiem... "Action!", a więc doskonale się wpisuje w ostatnio modną na AtariOnline.pl popularyzację tego języka ;). Przekazuję głos Tomkowi:



"Do redakcji "Bajtka" przekazałem tekst z propozycją konkursu dla czytelników. Miało to miejsce w 1992 roku, kiedy redakcji "Atari Magazynu" jeszcze nie było, ale już się powoli tworzyła. Plik otrzymał Robert Chojecki, który był wówczas chyba jedyną osobą w "Bajtku" przychylną Atari - to właśnie jemu zawdzięczamy powstanie pisma "AM".



Tekst napisałem dla zabawy, nie mniej jednak chciałem, aby mieli na piśmie pomysł i w razie czego wcielono go w życie. Plik się chyba zawieruszył i pomysł nigdy nie ruszył z miejsca, a ja sam też po prostu o nim zapomniałem. Znaczenie miało też to, że nasza redakcja "Atari Magazynu" była nowa i biedna, więc o ewentualnych nagrodach konkursowych po prostu nigdy nie byłoby mowy. Oto zachowane fragmenty tego tekstu:

"Zadanie: napisz program w "Action!", bez najmniejszych wstawek asemblera. Program ma:

Z góry nie określamy czasu, w którym będziemy oceniać nadesłane programy. Wyniki będą zależały od nadesłanych prac. Podajemy wartość orientacyjną, która wynosi 30 sekund.

Istotnym faktem jest, iż w dodatku do "Bajtka" pod tytułem "C&A" czyli Commodore & Atari, przepraszam, oczywiście Commodore & Amiga numer 6/92 program liczący do 1 000 000 (miliona) napisany w asemblerze liczy przez 25 sekund."


To wszystko co się znajduje w tym tekście to była taka moja propozycja, która oczywiście miała być dostosowana już w praktyce do konkretnego konkursu, jego wymagań i dotychczasowych doświadczeń redakcji, które jeszcze nie były mi znane w momencie pisania tego tekstu. Tak naprawdę, to sam byłem ciekaw, co czytelnicy wymyślą – miałem nadzieję, że ktoś mnie czymś niezwykłym zaskoczy! Moje rozwiązanie (listing z załącznika do powyższej propozycji konkursu):

MODULE
; CZAS: OKOLO 27-28 SEK

BYTE
A=40000
,B=40001
,C=40002
,D=40003
,E=40004
,F=40005
,G=40006

BYTE ARRAY DIS=[112 112 112 112 112
66 64 156 65]

CARD AD1,DL=560

PROC AS()
POKE(559,33)POKE(712,5)
AD1=PEEKC(@ DIS)

DL=AD1

A=16
FOR B=16 TO 25 DO
FOR C=16 TO 25 DO
FOR D=16 TO 25 DO
FOR E=16 TO 25 DO
FOR F=16 TO 25 DO
FOR G=16 TO 25 DO
OD OD OD OD OD OD

A=17
FOR B=16 TO 25 DO
FOR C=16 TO 25 DO
FOR D=16 TO 25 DO
FOR E=16 TO 25 DO
FOR F=16 TO 25 DO
FOR G=16 TO 25 DO
OD OD OD OD OD OD

DL=39965
POKE(559,34)
[96]


To, co zaproponowałem, jest wyciśnięciem z "Action!" siódmych potów i jest to propozycja nieco nie fair wobec komodorowców. Używam tu rozwiązań niemożliwych do wykonania na przykład na C-64 oraz konstrukcji językowych, które są dobrze znane na Atari w "Action!", jednak na Commodore nie istnieją w żadnym języku programowania. Dodatkowo nie zapewniają one takiej hiper-prędkości, która jest porównywalna z asemblerem. Co widać w przysłowiowym załączonym obrazku. Wadą mojego rozwiązania jest to, że czasami są widoczne znaki „:”, ale na szczęście tylko przez ułamki sekund.

nowy język programowania - w lutym 1984 roku :)


Chciałem pokazać tu przede wszystkim, że Atari ma coś tak niezwykłego jak "Action!", chciałem aby czytelnicy wiedzieli, że mają do dyspozycji tak wydajny kompilator. Że coś, co jest niemożliwe do wykonania na innym komputerze, na Atari jest możliwe i należy to wykorzystywać. Szczególnie że "Action!" wspiera i ułatwia korzystanie z wielu unikalnych cech architektury malucha."

Na koniec oczywiście linka do pliku listingu w formacie ACT. A moje pytanie brzmi: może ktoś zechce dla zabawy podjąć rękawicę rzuconą przez TDC? Można podsyłać programy w asemblerze, jeśli ktoś chce pognębić miłośników "Action!". Wszystkie chwyty dozwolone ;).
sikor 2009-03-12 19:02:37

Hmm, nawet jeśli, to co oznacza stwierdzenie "liczyć do 2000000"? Dodawać co jeden? Mnożyć? Przesuwać bity? Dawać dowolne działanie? Jaka jest użyta metoda odczytu czasu? To są niby drobne niuanse, ale wnoszą do sprawy bardzo wiele i trzeba je sprecyzować.

Kaz 2009-03-12 19:05:56

Mozesz calkowac po drodze, jezeli Ci to przyspieszy obliczenia :D

sikor 2009-03-12 19:29:06

Kaz, ale nadal wyrażenie "liczyć do..." jest nieprecyzyjne. Nie ma tam nic, że co jeden (w samym sformułowaniu), niie ma nawet zakresu. Ja na przykład policzę (dodam jeden) od 1999999 do 2000000 i mój wynik będzie szybszy ;)

Kaz 2009-03-12 19:39:19

To prawda. Domyslamy sie bowiem, ze chodzi o liczenie od zera z krokiem 1, ale w zasadach tego nie ma. Wiec Twoj przyklad jak najbardziej moglby zasluzenie wygrac konkurs :).

Tylko, ze podejrzewam, ze dokladniejsze zasady sa opisane we wspomnianym C&A, bo do niego nawiazywala propozycja TDC. W koncu to nie konkurs drukowany w Bajtku, tylko propozycja konkursu. Ma ktos ten numer C&A i moglby podeslac skan?

sikor 2009-03-12 19:47:09

Spokojnie, Kaz. Ja z Basiciem (raczej) nie mam jak startować. Tylko - jak coś ogłaszamy, podajmy choć częściową precyzję.
Ja natomiast poproszę Tomka o dokładne komentarze do tego kodu. Bo - choć teoretycznie jest banalny - to właśnie dlatego może posłużyć za dobry przykład do nauki języka.
Co na przykład robi nam blok A=16, a co blok A=17? Poza tym co robi w funkcji peek znaczek @? Takie błahostki dla osób nieznających języka są ważne, kod często jest dostępny, niestety - często bez komentarzy. Więc dużo dobrego by było, jakby takie (krótkie, ale pełne) przykłady zamieszczać. I właśnie dobrze opatrzone komentarzami.

Yosh 2009-03-12 19:56:25

Podoba mi się :)

http://www.atariarchives.org/c1bag/chap4n3a.jpg

16 do 25 to anticowe offsety liczb 0 1 2 3 4 5 :)
A B C D E F G to zmienne których adresy są ustwione na pamięć ekranu :):):):)

wiec na ekranie jest
00000000000
00000000001 (zer nie liczylem)
00000000002

A=16 wyswietla pierwsze zero

kazdy FOR kreci osobno cyfrą

@ to adres zmiennej DIS, czyli pewnie display listę TDC przełączył :P:P na zawartość DIS

Kaz 2009-03-12 19:57:01

Ja nic nie oglaszam, a to nie jest konkurs tylko informacja o konkursie. Po prostu Tomek rzucil kiedys wyzwanie asemblerowcom z C64 i jak ktos bardzo chce to moze sprawdzic co dokladnie robi ten program na C64 i pokusic sie o dowolna wersje jezykowa na Atari, zeby sobie dla sportu powalczyc o szybkosc. Ale tak jak napisalem - to dla zabawy, dla intelektualnej rozrywki miedzy trzecia kawa a snem :).

A komentarze oczywiscie, ze sie przydadza.

Yosh 2009-03-12 20:07:00

znaczek @ to podpucha, działa DL=DIS (bez zmiennej AD1)

ptb 2009-03-12 23:03:20

No to tak dla zabawy wersja asm z xex i dla porównania
oryginalna wersja w action z xex :-)
http://tiny.pl/b191

inkognito 2009-03-12 23:11:25

takie małe: "ja rzucam pomysł, a wy go łapcie" :)

Kaz 2009-03-12 23:20:29

inkognito - dokladnie tak! zazwyczaj jest odwrotnie, ale na programowaniu, jeszcze optymalizacyjnym ja sie nie znam :)

Kaz 2009-03-12 23:24:05

ptb - ladne :). Asembler - okolo 8 sekund (nie mam stopera pod reka), a Action - okolo 28 sekund.

Pytajnik 2009-03-12 23:36:42

Jeszcze sie da wylaczyc ekran dla przyspieszenia obliczen?

tdc 2009-03-13 04:04:28

Sikor - jak mówię to była właściwie notatka a nie regulamin konkursu. Zakładałem, że jak przyjdzie czas to wtedy się wszystko ustali i doprecyzuje.

Kaz - ja powinienem mieć gdzieś ten numer C&A - ale skaner mi padł...

Sikor - opis. Masz rację kod jest prosty i właśnie miał służyć jako forma edukacji. Yash zwrócił uwagę że nie trzeba używać dodatkowej zmiennej - racja, ja ten kod specjalnie pisałem "ładnie" aby był w miarę czytelny. Dodatkową zmienną i skok do funkcji PEEK bym na pewno pominął jeśli byłby w pętli aby nie spowalniać, natomiast tu właśnie każdy nawet jakiś 10 latek miał mieć czytelny kod. Ja zwykle nie piszę takiego ładnego kodu ;) Ostatnio jak przeglądałem moje stare źródła wraz z Mikerem to naprawdę miałem sporo kłopotu aby się połapać :D :D

Oto mój opis kodu:
MODULE
- rozpoczęcie modułu

; CZAS: OKOLO 27-28 SEK
- komentarz

BYTE
A=40000
,B=40001
,C=40002
,D=40003
,E=40004
,F=40005
,G=40006
- zadeklarowanie kolejnych zmiennych typu BYTE tak aby ich adresy znajdowały się w pamięci obrazu. Umyślnie każda zmienna znajduje się w oddzielnej linijce bo w ten sposób wystarczy napisać jedną linijkę powielić ją i zmienić tylko numer na końcu i nazwę zmiennej. Czyli oszczędność z wykorzystaniem możliwości edytora Action!

BYTE ARRAY DIS=[112 112 112 112 112
66 64 156 65]
- tablica typu BYTE, wartości to kolejne instrukcje dla Antica. Jak zauważył Yosh DIS to w skrócie w moich programach displaylist.

CARD AD1,DL=560
- deklaracja dwóch zmiennych 16 bitowych. Jedna wskazuje na adres 560 czyli wskaźnik początku displaylist, druga pełni rolę pomocniczą (dla klarowności źródła).

PROC AS()
+ rozpoczynamy główną procedurę, która będzie uruchomiona. Moja minimalizacja powoduje że bardzo łatwo z klawiatury wpisuje się "as" lub "qw" lub "zx" itp. wpisanie procedury "a" chyba powodowałoby konflikt ze zmienną "a".

POKE(559,33)POKE(712,5)
- ustawianie rejestrów, w pierwszym przypadku powoduje zmniejszenie wyświetlanego ekranu - co nieco dodaje wydajności małemu Atari, choć w tym wypadku raczej mało istotne.

AD1=PEEKC(@ DIS)
- pobranie adresu tablicy DIS

DL=AD1
- przypisanie do zmiennej która przechowywana jest w adresie 560, czyli jednym słowem ustawiamy Anticowi nowy program display list.

A=16
- pokazanie na ekranie pierwszego zera, inne pojawią się automatycznie po rozpoczęciu następnych pętli:

FOR B=16 TO 25 DO
FOR C=16 TO 25 DO
FOR D=16 TO 25 DO
FOR E=16 TO 25 DO
FOR F=16 TO 25 DO
FOR G=16 TO 25 DO
OD OD OD OD OD OD
- przeliczenie pierwszego miliona

A=17
- zwiększenie z zero na jeden

FOR B=16 TO 25 DO
FOR C=16 TO 25 DO
FOR D=16 TO 25 DO
FOR E=16 TO 25 DO
FOR F=16 TO 25 DO
FOR G=16 TO 25 DO
OD OD OD OD OD OD
- przeliczenie następnego miljona

DL=39965
- powrót do wcześniejszego programu displaylist.

POKE(559,34)
- poszerzenie ekranu z wcześniej ustawionego wąskiego. Dzięki obu operacjom przed wyjściem z programu ekran będzie wyświetlany z standardowymi parametrami.

[96]
+ kod w asm jest równoznaczny z "return" lub RTS. Jednak "[96]" się krócej pisze ;):):)

Na koniec to naprawdę nie jestem przekonany, że to najszybsza wersja być może da się to zrobić w Action! nieco szybciej ;)


Pytajnik: w tym programie został zastosowany kompromis pomiędzy wyłączeniem ekranu, a wyświetlaniem. Chodzi o to że wyświetlać na ekranie się musi bo taka jest zasada, jednak zbudowanie takiej displaylisty w której jest tylko 1 linijka powoduje zaoszczędzenie dużej ilości czasu (prawie takiej jakby wyłączyć ekran).

tdc 2009-03-13 04:12:11

Kaz: co do tego C&A to z tego co pamiętam to nie był konkurs tylko oni sobie coś tam programowali na commodore, jednak z jakiegoś powodu czas był istotny bo w tekście podali ile czasu trwa zamieszczony kod w asm.

Kaz 2009-03-13 04:15:13

Fajny opisik, dzieki - ale go sobie poczytam rano, z swieza glowa :).

sikor 2009-03-13 06:38:33

Tdc: dzięki za opis. Jednak w zasadach konkursu kłamałeś ;) Dałeś tu assembler!!! Mam Cię!!! (ten kod [96] )
A swoją drogą - większości się domyślałem, ale nie byłem pewien. Chcemy cyklu i więcej takich prostych przykładów. Od podstaw, prosimy, od podstaw...

Tdc 2009-03-13 09:07:10

Sikor: ach Ty kombinatorze !;):)
Ale nie masz mnie bo: zadaniem programu jest liczyć, a [96] nic nie liczy;) Druga sprawa, że moje rozwiązanie nie miało się znaleźć w tekście w Bajtku, tylko miały się tam znaleźć rozwiązania czytelników. Ja ten kod napisałem dla własnej zabawy i satysfakcji - inna sprawa, że jako młody współpracownik pisma musiałem się niejako uwiarygodnić jako osoba, która faktycznie potrafi coś wklepać ;)

Cykl już właściwie jest (dzięki przychylności i zainteresowaniu Kaza) i myślę że wspólnie z Yosh się to uda. Ja zastanawiam się nad jakimś większym przykładem gry, choć bardzo prostym, na którym widać jak programować tak jak w Basicu.


ps. nigdy na oczy nie widziałem czerwonego carta z Action! :-/

freesh 2009-03-13 09:17:07

Moja wersja programu w asm http://odsiebie.com/pokaz/1809601---5f8d.html

freesh 2009-03-13 09:33:10

spacja odpala program

ptb 2009-03-13 10:28:02

@freesh fajny pomysł, aby przekopiować charset :-)

larek 2009-03-13 10:28:37

Zaprezentowany program pokazuje dość specyficzne właściwości Action! i jako przykład możliwości tego języka jest świetny.

Jednak wcale bym nie powiedział, że liczy on do 2 milionów.
On wyświetla tylko cyferki. Według mnie to nie jest liczenie. Efektem liczenia powinna być zliczona wartość, której tu nie ma. Program tylko kręci cyferkami (lub innymi dowolnymi znakami), ale czy zlicza? Nie!

Poza tym, to 2000000 nigdy się tu nie pojawi...
Uwaga Sikora o użyciu j.m. też jest słuszna.
Gdyby konkurs wystartował w Bajtku, to byłby niezły obciach, gdyby program autora konursu został zdyskwalifikowany za nieprzestrzeganie jego warunków ;-)

urborg 2009-03-13 11:52:15

A moim zdaniem program zlicza. Chwilowy jak i końcowy wynik jest przecież przechowywany w zmiennych A,B,C,D,E,F i G. Kodowanie może trochę i nietypowe, ale fakt faktem że wartość jest przechwywana w pamięci, a nie tylko wyświetlana. Choć z drugiej strony nawet gdyby tak nie było, to przecież wszystko co znajduje się na ekranie - znajduje się również w pamięci obrazu, więc samo wyświetlanie też należałoby uznać za zliczanie.

Jedyne co możnaby zarzucić to fakt że program zlicza do 1999999 zamiast do 2 milionów.

sikor 2009-03-13 11:59:28

Nowinka napisała: "Zadanie: napisz program w "Action!", bez najmniejszych wstawek asemblera. "
TDC napisał: "[96]
+ kod w asm jest równoznaczny z "return" lub RTS. Jednak "[96]" się krócej pisze ;):):) "
TDC napisał: "Ale nie masz mnie bo: zadaniem programu jest liczyć, a [96] nic nie liczy;)"
Jednym słowem: albo Nowinka kłamie, albo TDC kłamie. Bez dwóch zdań ;)

larek 2009-03-13 12:40:09

Jakie liczenie? Do zmiennej A są podstawione gotowe wartości, a nie liczone. Najpierw jest to 0, a później 1, a w zasadzie, to nawet nie 0 i 1 tylko 16 i 17! W zmiennych ABCDEFG wcale nie ma liczby 2000000. Zmienne te przyjmują wartości od 16 do 25. Żeby dojść do tych 2 mln. to trzeba te wartości z tych zmiennych dopiero odpowiednio PRZELICZYĆ.

Nadal oczywiście uważam, że przykład jest the best. Choć w TBXL (i AB) też się takie coś da napisać i nie wiem, czy ktoś uznałby ten program za liczący do 2 mln.:

0 POKE 559,33:FOR X=DPEEK(560) TO DPEEK(560)+22:POKE X+6,0:NEXT X:CLS
1 POKE 48192,16
2 FOR B=16 TO 25:POKE 48193,B
3 FOR C=16 TO 25:POKE 48194,C
4 FOR D=16 TO 25:POKE 48195,D
5 FOR E=16 TO 25:POKE 48196,E
6 FOR F=16 TO 25:POKE 48197,F
7 FOR G=16 TO 25:POKE 48198,G
8 NEXT G:NEXT F:NEXT E:NEXT D:NEXT C:NEXT B
9 POKE 48192,17
10 FOR B=16 TO 25:POKE 48193,B
11 FOR C=16 TO 25:POKE 48194,C
12 FOR D=16 TO 25:POKE 48195,D
13 FOR E=16 TO 25:POKE 48196,E
14 FOR F=16 TO 25:POKE 48197,F
15 FOR G=16 TO 25:POKE 48198,G
16 NEXT G:NEXT F:NEXT E:NEXT D:NEXT C:NEXT B
17 POKE 48192,18
18 GET KEY

Od razu zastrzegam, że nie wiem ile trwa to niby liczenie w TBXL, bo dotrwałem tylko do stu kilkudziesięciu tysięcy :D

larek 2009-03-13 13:06:59

w zasadzie, to linia 17 powinna wyglądać tak:
17 POKE 48192,18: POKE 48193,16: POKE 48194,16: POKE 48195,16: POKE 48196,16: POKE 48197,16: POKE 48198,16

;)

urborg 2009-03-13 13:13:48

Pętle FOR zwiększają wartości w poszczególnych zmiennych o jeden przy każdym przebiegu pętli więc jest to liczenie raczej a nie podstawianie.

Co do wartości z zakresu 16 do 25 - przeliczaniem tego na zrozumiałą postać zajmuje się kod ATASCII - genialne rozwiązanie optymalizacyjne. Bardziej eleganckim byłaby podmiana znaków graficznych, tak aby jedynce odpowiadała graficzna jedynka itd. Ale w sumie przecież program dalej robiłby to samo.

Co do długości liczenia w TB, wystarczy pomnożyć czas na który starczyło ci cierpliwości przez około 20 i będzie wiadomo ;)
Ciekawe czy zapisanie całego programu w jednej linijce przyśpieszyłoby program?

larek 2009-03-13 13:38:07

Pętle zmieniają wartość zmiennych BCDEFG, wartość zmiennej A jest podstawiona, a nie wyliczona. Pewnie, że można być się sprzeczać, bo wartości zmiennych BCDEFG w pętli też są podstawiane, tyle że przez licznik pętli. Jednak nadal twierdzę, że nie jest to "rasowe" zliczanie.
Przekażesz mi wynik tego zliczania na końcu programu do zmiennej np. WYNIK, aby można go było wykorzystać przy kolejnych obliczeniach?
Pewnie, że się da, tylko że nie w takiej postaci, jak jest teraz.

Ten program to iluzja. TDC genialnie to zrobił. Program pokazuje nam to, co chcieliśmy zobaczyć - latające cyferki, jak w liczniku...

Oczywiście napisanie takiego programu zliczającego w asemblerze też na tym by polegało (bo komórki mogą przechowywać tylko określone wartości), jednak liczba dwa miliony, to dwa miliony, a nie dwa, zero, zero, zero, zero, zero, zero. Pewnie każdy powie: to kwestia interpretacji tego zapisu. No i będzie miał rację!

Pozdrawiam!
A przykład TDC jest naprawdę genialny!

larek 2009-03-13 15:55:20

Zrobiłem pewien eksperyment.
Napisałem program w TBXL, który w zasadzie bazuje na pomyśle TDC ;-)
Całość do pobrania tu:
http://arsoft.netstrefa.pl/pliki/SuperCOUNTER.7z

Opis plików na dyskietce:
SC.BAS - program SuperCounter w Turbo-Basic XL
SC.CTB - j.w. w wersji skompilowanej
SC.COM - j.w. w wersji do uruchomienia z DOS

reszta to standardowe pliki:
TB.COM - to oczywiscie Turbo-Basic XL
R2.COM - biblioteka TB
C.COM - kompilator
DOS - DOS ;)

Do tej pory nie chce mi się wierzyć w szybkość wersji skompilowanej. Gdzie jest błąd? ;-)

Kaz 2009-03-13 16:12:50

A jakie sa wyniki w sekundach dla wersji niekompilowanej i kompilowanej (nie mam w tej chwili jak samemu sprawdzic)?

urborg 2009-03-13 16:55:03

He he he, fajny programik! W tym wypadku faktycznie mamy do czynienia z wyświetlaniem , a nie zliczaniem. Ale mniejsza z tym, bo w sumie efekt jest identyczny jak w programie TDC. Różnica szybkości na korzyść wersji skompilowanej jest faktycznie szokująca. Po kompilacji program zlicza do 2 000 000 w czasie 39 sekund! Mniej więcej w tym czasie wersja nieskompilowana jest w stanie doliczyć zaledwie do 50 000. Oznacza to że program po kompilacji jest 40 razy szybszy! 8-)

Próbowałem przyśpieszyć program poprzez wciśnięcie programu w mniejszej liczbie linijek. W nieskompilowanym programie zysk szybkości jest mniej więcej 5-10%. Po skompilowaniu zysk znika.

urborg 2009-03-13 17:40:52

Tak sobie jeszcze myśle o tym programiku. Wydaje mi się że taki wzrost prędkości wynika z tego że program wykonuje praktycznie tylko bardzo proste niskopoziomowe polecenia POKE. Nie ma potrzeby przeprowadzania żadnych obliczeń matematycznych więc nie ma też potrzeby częstego korzystania z pakietu zmiennoprzecinkowego. W wersji nieskompilowanej większość czasu zabiera więc interpreter który musi znaleźć kolejną instrukcję do wykonania i "zrozumieć" ją, po czym samo jej wykonanie trwa już dosyć krótko.

tdc 2009-03-13 19:10:53

Nie spodziewałem się że ten temat wywoła tyle emocji;) Ale dziękuję za wszystkie emocje i opinie ;)

Sikor: Nie no oczywiście, że chodzi o mnie ! ;) To ja się taki urodziłem ;):) jako „kłamca, kłamca, kłamca” ;):)

Urborg: „Bardziej eleganckim byłaby podmiana znaków graficznych, tak aby jedynce odpowiadała graficzna jedynka itd.”
Nic prostszego w Action! to kilka linijek kodu.

Co do uwag, że program nic nie zlicza itp. to zgadzam się że to jest specyficzne ujęcie tematu, jednak zwróćmy uwagę na to że wstawiając zmienną np. X do środka pętli to program naprawdę zliczy. Jeśli na początku programu X=1 to na końcu będzie 2000000. Problem w tym że Action! Nie ma takiego typu danych, który by taki wynik pomieścił ;)
Więc tak czy inaczej i tak trzeba kombinować i tak.

Larek: „Pętle zmieniają wartość zmiennych BCDEFG, wartość zmiennej A jest podstawiona, a nie wyliczona.”

To się nazywa algorytm heurystyczny – wszyscy wiedzą że tak ma być – nikt nie wnika dlaczego i jak to zostało zaimplementowane, istotne jest to że wszystko się zgadza ;)

„Przekażesz mi wynik tego zliczania na końcu programu do zmiennej np. WYNIK, aby można go było wykorzystać przy kolejnych obliczeniach?”

Świta mi tu w głowie pewna myśl: jak brakuje zakresu bajtu to w obliczeniach dodajemy następny bajt, potem następny itp. Tu różnica polega na tym, że z wymogu optymalizacji (a często się tak robi) ja zbyt wcześnie biorę sobie nowy bajt.

„Ten program to iluzja.”

To jest cecha istotna przy optymalizacji – potrafić spojrzeć na wydawałoby się prosty problem w świetle zupełnie nowym. Na tym polega pisanie super gierek na 8 bitowych komputerach (np. Bomb Jack itp.) oraz pisanie demek.

„Oczywiście napisanie takiego programu zliczającego w asemblerze też na tym by polegało”

I tu dochodzimy do cechy Action! on jest bliski asemblerowi i jak widać to mu służy;)

„Napisałem program w TBXL, który w zasadzie bazuje na pomyśle TDC”

Wyniki są fascynujące. To że kompilowany TBXL jest niewiele wolniejszy od Action! oznacza, że kompilator dorzuca jakąś zbędną instrukcję której Action! nie dokłada. Po drugie tak drastyczna różnica w prędkości TBXL kompilowanego i nie, wynika najprawdopodobniej z prostych operacji jakie program (zrobiony na wzór mojego) wykonuje, co zauważył urborg. Może to oznaczać, że specyfika zagadnienia powoduje że jest to jeden z najciekawszych przykładów wydajności kompilatora TBXL (*40!). Po trzecie oznacza to że pisząc wydajne programy w TBXL trzeba pisać je w taki sposób aby potem się łatwo zamieniały na proste operacje asemblerowe ;)
Czyli zarówno z Action! jak i z TBXL dotarliśmy do tego samego celu: asemblera ;):)

Kaz 2009-03-13 19:26:49

@Larek:
„Przekażesz mi wynik tego zliczania na końcu programu do zmiennej np. WYNIK, aby można go było wykorzystać przy kolejnych obliczeniach?”

Poniewaz celem programu jest doliczenie do dwoch milionow to wiemy, jaki bedzie koncowy wyniki i bardzo prosto mozna go przekazac do zmiennej (WYNIK=2000000) :D

urborg 2009-03-13 21:56:39

TDC - rzuć okiem jeszcze na pliki BAS do których linki dał Arek. Program w TB jest tak szybki gdyż został bardzo sprytnie uproszczony. Wersja którą Arek dał powyżej (proste przepisanie tego samego na TB) byłaby dużo wolniejsza z racji użycia pętli for i zmiennych. Inkrementacja zmiennej w TB to wyższa matemyka bo potrzbny byłby pakiet zmiennoprzecinkowy. Arek obszedł to poprzez likwidację zmiennych i wywoływanie kolejnych instrukcji POKE w procedurach. Ten program naprawdę już tylko wyświetla :), ale dzięki temu jest taki szybki.

larek 2009-03-13 23:31:09

Jak to mój program "już tylko wyświetla"? ;)
Odpowiem na to cytatami:

1. Urborg> A moim zdaniem program zlicza. Chwilowy jak i końcowy wynik jest przecież przechowywany [...] Kodowanie może trochę i nietypowe, ale fakt faktem że wartość jest przechwywana w pamięci, a nie tylko wyświetlana.
2.Urborg> przeliczaniem tego na zrozumiałą postać zajmuje się kod ATASCII - genialne rozwiązanie optymalizacyjne
3.TDC> To się nazywa algorytm heurystyczny – wszyscy wiedzą że tak ma być – nikt nie wnika dlaczego i jak to zostało zaimplementowane, istotne jest to że wszystko się zgadza
4.larek> Ten program to iluzja
5.TDC> To jest cecha istotna przy optymalizacji – potrafić spojrzeć na wydawałoby się prosty problem w świetle zupełnie nowym. Na tym polega pisanie super gierek na 8 bitowych komputerach (np. Bomb Jack itp.) oraz pisanie demek.
---koniec cytatów---

Wszystko czym bronił się program napisany przez TDC pasuje, jak ulał do mojego programu. Mało tego. Uważam, że mój program spełnia wszystkie kryteria konkursu (no, oprócz tego, że nie jest w Action!).
1. Nie zawiera żadnych, nawet najmniejszych wstawek w asemblerze
2. Liczy faktycznie do 2 000 000 (dwóch milionów)
3. Każda zmiana o 1 jest widoczna na ekranie (liczy się każde odwołanie do ekranu)
dodatkowo - nie wyświetla znaku ":" jako cyfry (skąd się to wzięło?)

Napisałeś, że zlikwidowałem zmienne. Ja bym to ujął w inny sposób - po optymalizacji programu stały się zbędne :D
Poza tym, zapis w Action!:

BYTE
A=40000

A=16

to dokładnie to samo, co zapis w Basicu (i w Action! też!)

POKE 40000,16

więc dlaczego tego nie zapisać w ten sposób?

Nadal uważam, że zarówno jeden, jak i drugi program, to takie wielkie oszustwo, ale w pozytywnym znaczeniu tego słowa - jeśli takie istnieje ;-)
Jak widać i tak nie pokonałem szybkości Action! A byłoby to jeszcze trudniejsze, gdyby mój program przepisać i uruchomić w Action!

Osiągnięty wynik w kompilowanym Basicu jest całkiem przyzwoity :)
Choć nie jest to zasługa kompilatora, tylko szatańskiego algorytmu :D
Ważne, że efekt jest taki, jaki powinien być. Prawda?

tdc 2009-03-14 10:35:11

Urborg: aaaaaa widzisz! To wszystko zmienia, ja nie byłem świadomy tego, myślałem że cały czas rozmawiamy o tym widocznym programie w TBXL. Wpadłem tu tylko na chwilkę i nie sprawdzałem tych wszystkich plików.

larek: "Wszystko czym bronił się program napisany przez TDC pasuje, jak ulał do mojego programu."

Tak... prawie demko napisałeś !:):)
Wystaw je na Grzybsoniadzie ;):)

"dodatkowo - nie wyświetla znaku ":" jako cyfry (skąd się to wzięło?) "

Właśnie też mnie to mocno martwiło - nie wiedziałem co się dzieje. Chodzi o to że w Action! po wyjściu z pętli "FOR B=16 TO 25 DO OD" wartość zmiennej B=26 - pech chciał że to faktycznie sporadycznie jest widoczne na ekranie.
- przychodzi wam tu do głowy jeszcze jedna optymalizacja ??? :D :D

"Napisałeś, że zlikwidowałem zmienne. Ja bym to ujął w inny sposób - po optymalizacji programu stały się zbędne :D "

Dobre :D :D

Co prawda ja miałem kilka założeń i pewnie w ostatecznej wersji regulaminu by się znalazły: zakładałem np. że jednak będą jakieś zmienne, pętle oraz inkrementacje (procedury mogą być).

"to dokładnie to samo, co zapis w Basicu (i w Action! też!) "

No właśnie w Action! To nie jest to samo, bo w Action! jest jeszcze parę innych ciekawych rzeczy.

To co tu jest widoczne nie jest równoznaczne bo też mogę napisać "POKE(40000,16)" jednak to będzie dużo wolniejsze od A=16. To ostatnie jest zamieniane przez kompilator Action! na LDA i STA, czyli nic szybszego już się zrobić nie da, natomiast "POKE()" to jest skok do procedury bibliotecznej - dość wydajnej ale będzie znacznie wolniejsze (da się to obejść).

"A=16" to jest przykład w którym Action! jest równie szybki jak asm - czyli dość wyjątkowy przykład, co prawda w Action! nie ma dużo podobnych sytuacji - jednak inne kompilatory na całym świecie nie mogą się poszczycić pisaniem programów takich jak ten czy jemu podobnych.

"Nadal uważam, że zarówno jeden, jak i drugi program, to takie wielkie oszustwo, ale w pozytywnym znaczeniu tego słowa - jeśli takie istnieje ;-)"

:D

"Jak widać i tak nie pokonałem szybkości Action! A byłoby to jeszcze trudniejsze, gdyby mój program przepisać i uruchomić w Action!"

Otóż to wtedy program by się całkowicie składał z LDA i STA ;):)
Teraz w Action! spowalniają go pętle, które nie są tak super wydajne, ale też narzekać nie można (o ile pamiętam na pececie w Turbo Pascalu 6.0 pętla zajmowała ponad 100 cykli :D :D).

"Ważne, że efekt jest taki, jaki powinien być. Prawda?"

W demoscenicznym światku zostaniesz zrozumiany ;) W końcu jak pisali kiedyś chłopaki od Numena, player muzyki tam po prostu wstawia wartości do rejestrów POKEYa - aby szybkość była maksymalna ;)

urborg 2009-03-14 21:47:32

Arku - twój program jest genialny, moim zdaniem jak najbardziej spełnia warunki konkursu. Tyle że... zarzucałeś TDC że jego program nie zlicza, a tymczasem twój robi jeszcze mniej. :P Powtarzam jednak jeszcze raz - genialny przykład optymalizacji kodu :)

larek 2009-03-15 00:00:51

A pewnie, że nie liczy :D
Skoro jednak program TDC wg mnie nie liczy, ale wszyscy - łącznie ze mną - na własne oczy widzą, że liczy, to nie pozostało nic innego, aby też coś takiego napisać. Tu znów muszę zacytować:
"Chwilowy jak i końcowy wynik jest przecież przechowywany w". Koniec cytatu. Zmiennych tu nie ma, ale można dopisać: "komórkach 48195-48201". I znów wszystko jest ok, bo wartości tych komórek można przecież odczytać, a tym samym program... zlicza :))
No dobrze. Jak już pisałem oba programy, to taka sztuczka magiczna, która pokazuje nam dokładnie to, czego oczekujemy.

tdc 2009-03-17 11:19:51

larek: „Jak już pisałem oba programy, to taka sztuczka magiczna, która pokazuje nam dokładnie to, czego oczekujemy.”

Posłużę się tu klasykiem: „bo Atari jest jak z gąbki, jeszcze wiele się da z niego wycisnąć” ;)