Delphi - rýchlosť práce Integer/ShortInt pri Win32
Ak použijem hodnoty 0..7 bude práca rýchlejšia v Integer alebo ShortInt (Byte)?
Ak použijem hodnoty 0..7 bude práca rýchlejšia v Integer alebo ShortInt (Byte)?
Zpět do poradny Odpovědět na původní otázku Nahoru
Ja by som použil BYTE, určite bude rýchlejšia práca s premennou, ale to ani nepostrehneš.
Súvisí to so šachmi, takže ja to síce nepostrehnem, ale ak sa bude pracovať s Integer miesto ShortInt aspoň 1000000x, tak to už postrehnem. Ale na druhej strane, dá sa to zistiť aj pri odľaďovaní. Ja by som tiež radšej použil ShortInt, ale tlačia mi všade do hlavy rôzne knihy a podobne, že práca s Integer je rýchlejšia, pretože sa jedná o 32 bitový hardware.
Poznámka: Slovo hardware nie je celkom na mieste. Ono je vlastne Windows 32-bitový "software", ale v skutočnosti je to zosúladené s hardware počítača a to tak, že procesor je prepnutý do 32 režimu a pri assembleri má tá istá inštrukcia rozdielny význam:
Znamená v 16-bitovom móde, že do registra ax načíta hodnotu 0000h, ale v 32-bitovom móde je to hodnota 00000000h. Aby sa docielilo načítania 16-bitovej hodnoty, musí sa dať pred inštrukciu prefix, ktorý vlastne brzdí procesor a tým môže dôjsť k zníženiu výkonu oproti vykonávaniu tej istej ištrukcie v 16-bitovom móde.
Poznámka 2: Neberte predchádzajúcu poznámku, akoby som niekoho poučoval, ja tu len vysvetľujem aby tomu rozumel každý a z čoho pramenia moje obavy, že to bude pomalšie.
Niecim podobnym ako je napisane vyssie sa zaoberaju tu: optimdelphi.html
S těma 16/32 registrama to není zas tak jednoznačné (EAX - AX - AH a AL). Pro rychlost záleží, jak je to či ono konkrétně napsané. Nejlíp to poznáš z výpisu přeloženého programu v assemleru debugerem. Tam uvidíš, co a jak Delphi přeložilo. Můžeš si zkusit proměnnou typu Integer a byte, co to z kódem udělá. Uvidíš, že v některých případech bude rychlejší Integer a jinde zase byte. Zdůrazňuji, že překladač je opravdu velice chytrý. Třeba když jsem pro rychlost dělal nějaké sekvence v assembleru, tak to Delphi obvykle zvladly stejně dobře. Pro zvýšení rychlosti je spíš lepší zakázat všechny možné kontroly runtime (přetečení, indexy mimo, ...) - ale až po odladění .
Presne tak. Rozdil v rychlosti nepostrehnes, navic pri nejakych operacich si to Delphi stejne premapuje na integer.
Jinak ShortInt neni Byte.
Takže kľudne Byte, dobre teda.
Viem:
Byte: 0..255
ShortInt: -128..127
Jednalo sa mi o 8-bitové čísla.
Taketo veci je najlepsie vyskusat.
Tiež ma to napadlo. Počas ladenia zameniť Integer za ShortInt a odmerať čas, čo bude rýchlejšie. Pri hĺbke 8 polťahov pri Minimaxe by to mohlo byť merateľné.
Na x86 pre 32bitovy program je optimalne 8bitove alebo 32bitove. 8bitove je lepsie ak mas tam moc konstant. Najhorsie su 16bitove (pred instrukciou musi byt prefix, zbytocne to predlzuje kod).
P.S. u optimalizacie je najdolezitejsie to, ako je ten program napisany, zaoberas sa menej podstatnymi vecami.
Áno, assembler mi nie je cudzí, takže tiež mi vŕtalo hlavou, že 8-bitvé asi majú rovnaký zápis.
- co tym myslis ??? 8bitove instrukcie maju specialne OPcode takze aj v 32bit programe su bez prefixov, vyhoda oproti 32bit moze byt ze maju kratsi operand ak je operand konstanta. Rozdiel v rychlosti bude ale relativne maly, omnoho vyraznejsie sa prejavi to ako je program napisany a to ze je prekladany pascal-like compilerom co do kodu strka dodatocne nezmysly napr. pri praci s polom.
Tak to myslím, že ak napíšem
tak to bude v 16 aj 32-bitovom režime znamenať to istí, čiže 00h.
Procesor stejně přečte 4 byte a pak z nich vybere ten jeden, takže rozdíl v rychlosti mezi Byte a Longint není, tedy pokud použiješ zarovnávání aspoň na 4 byte. Raději bych se zaměřil na optimalizaci logiky kódu - zkrácení kódu ve smyslu zmenšení počtu instrukcí a podobně.
Jestli se začneš zabývat zkoumáním, jestli je lepší xor ax,ax; mov bx,ax nebo xor ax,ax; xor bx,bx, tak s tím do smrti neskončíš... jako já.
Ono to nie je uplne to iste, procesor neprecita 4byte ptz ta instrukcia ma len 2byty. Aj keby precital naraz 4byty tak zvysne 2byty su uz z dalsej instrukcie (instrukcie nie su zarovnavane), co moze byt (nemusi) vyhoda.
Ak by pouzil integer tak to bude
mov eax,0
a tato instrukcia ma 5 bytov takze moze(nemusi, zavisi od vnutornej architektury CPU a od konkretneho stavu cache apod.) to trvat dlhsie.
P.S. tiez si myslim ze sa zaobera nie moc podstatnymi vecami, a ktovie ako je napisany algoritmus (a najvacsie mnozstvo optimalizacie sa da urobit hlavne v algoritme, sposobe ulozenia dat atd., to su podstatne veci).
Procesor skutečně přečte vždy 4 byte, míň prostě neumí. Když další dva byte nepotřebuje, v tichosti je ignoruje. Proto je důležité zarovnávání adres, aby to přečetl jedním taktem.
PS: Tak ale programovat opravdu, ale opravdu nejde. Dřív, než takový optimální algoritmus někdo vyprodukuje, přijde rychlejší procesor a námaha vyzní nadarmo .
Instrukcie (a konstanty v nich) sa nezarovnavaju. Zarovanavaju sa data aby bol optimalnejsi pristup k pamati (ak instrukcia ma jeden operand niekde v RAM).
Argumentovat tym ze procesor "precita 4byte" nie je namieste, tato tema je omnoho komplikovanejsia a zavisi od konkretneho CPU. Pekne citanie o optimalizacii je v Pentium developers manual, volume 3, kapitola 24 "Optimizations".
Co sa tyka toho mov, pozrel som si specifikaciu instrukcie MOV a obe (mov ah,0 aj mov eax,0) by mal pentium spracovat za jeden takt (takze ak pises "CPU precita 4byte" tak ako je mozne ze 2bytova a 5bytova instrukcia trva rovnako? ), ale ze je v specifikacii ze obe trvaju jeden takt neznamena, ze vzdy za kazdych okolnosti to trva uplne rovnako, ak tam staci byte pouzil by som byte, uz len preto ze to bude zrat menej RAM a kodu a teda menej spozdeni pri pripadnych nacitavaniach do cache atd.
k tomu P.S: ale ide, staci predtym ako clovek zacne pisat program trochu rozmyslat Cas co venuje tejto diskusii (ktora ani nema velky zmysel ptz. ak bude medzi tym byte a integer rozdiel tak bude IMHO minimalny alebo ziaden) mohol venovat rozmyslaniu o ulozeni dat(mam na mysli celkovo, nielen ze ci integer alebo byte) a optimalnom algoritme. Tusim Quake alebo Doom alebo co to bolo bol dobry prave kvoli tomu, ze bol na svoju dobu (pomale grafiky a PC) perfektne optimalizovany, jeden z autorov bol tusim specialista na optimalizacie.
A myslíš, že o algoritme nerozmýšľam? Už mi ide hlava prasknúť. Generátor ťahov je najrýchlejší, ak najprv otestujem blokované figúrky v závislosti od polohy kráľa, potom postupne prejdem šachovnicu a kontrolujem, či už dané políčko bolo testované. Takto by som mal vygenerovať najrýchlejšie ťahy a nemusím testovať šach. Lenže je tu ďalší problém a to je, že ak chcem prejsť šachovnicu len raz (to je rýchlejšie), tak môžem do generátora pridať aj ohodnocovaciu funkciu. Lenže, ak ju nebudem potrebovať v danej chvíli (jediný ťah z pozície, hľadanie ťahov, kde sa berie (kvôli braniu jazdca, chráneného pešiakom, strelcom) a podobne), tak bude iba zdržovať. Ak budem testovať, či ju potrebujem alebo nie, tak to bude na viacerých miestach a tým brzdím algoritmus. Čiže toto chcel Rce povedať, že takto sa programovať nedá. Myslím, že najskôr niečo asi vyprodukujem a potom to zrýchlim, kde sa bude dať.
kazdy tah musis ohodnotit ptz za nim mozu nasledovat rozne tahy supera a tvoje atd. P.S. Optimalizacia je velmi komplexna vec, najprv si treba premysliet zhruba zaklad, a potom zavisi aj od toho ako ten program bude napisany (konkretne ciastkove veci). Samozrejme ze si nemozes vymysliet uplne vsetko do poslednych detailov predtym ako zacnes programovat. Optimalizovat sa da aj pri pisani a aj po napisani programu :)
Vlastne máš pravdu, kľudne môžem dať ohodnocovanie do generátora. Takto bude hneď dostupná hodnota každého ťahu. Čítam ten seriál na article.php, ale občas mám z toho hlavu ako balón, keď nad tým, čo tam píše rozmýšľam. Ale postupne tomu chápem viac a viac.
Necital som clanky ziadne, ale ono sranda je aj v tom, ze kam sa budu odkladat tie vnorene dalsie tahy, ak sa testuje viac tahov "do buducnosti", musi sa pamatat cela historia od momentalneho tahu. Najjednoduchsia pre programatora je rekurzia, ale ta je aj najmenej optimalna ak by sa mala presuvat v rekurzii ako parameter cela sachovnica, atd., to su veci ktore velmi ovplyvnuju rychlost. Dilema BYTE vs. INTEGER je nepodstatna.
Na nerekurzívnu rekurziu som tiež myslel. Vyriešim to tak, že sa uloží buď šachovnica alebo ťahy od koreňa a takto sa to zopakuje pre všetky ťahy, ktoré hodnotím. Potom sa zoberie prvá šachovnica (ťahy) a zistia sa ťahy pre túto situáciu. Zasa sa uloží šachovnica a prejde sa na ďalšiu. Takto dokola a keď sa vyčerpajú, tak zas dokola.
No, urob ako chces, ja len ze v tomto je kamen urazu, nie v byte/integer. Je tam dost "sa ulozi sachovnica", mozno sa to da aj menejkrat ukladat, resp. pouzit to co uz mas z predch tahu a zmenit len 2byte apod., to uvidis aj ked to budes pisat/mat napisane, ze co by sa tam dalo este optimalizovat. Dalsia dolezita vec je aj napr. ze ako sa urobi "kopirovanie" sachovnice, fcia typu "memcpy" je omnoho rychlejsia ako nejaky cyklus s priradovanim po jednom (nova[x][y] = stara[x][y]), apod...
Aj nad tým som rozmýšľal. Na ťah stačia 4 byte:
1. Odkiaľ, kam
2. Odkiaľ, kam (veža rošáda)
3. Braná figúra + branie mimochodom
4. Premena pešiaka
Edit: Dokonca 3, ale kvôli rýchlosti keď to budú aj 4:
1. Odkiaľ, kam
2. Braná figúra + branie mimochodom
3. Premena pešiaka alebo odkiaľ kam veža pri rošáde
Není vůbec třeba přenášet celou šachovnici ani všechny tahy, stačí přenášet jeden tah. Pak stačí mít jednu globální šachovnici a seznam tahů.
Ohodnocení pozice je tak složité, že náklady na přenášení v podstatě jakýchkoli dat jsou vedle toho zcela zanedbatelné. Třeba jen zjišťování, jestli není šach. A vyhledání všech přípustných odpovědí soupeře. A potom rozhodování, jestli variantu ukončit nebo ještě pár tahů pokračovat.
// edit na tah stačí jeden word - byte odkud a byte kam
Práce takéto riešenie nechcem kvôli zadávaniu času rozmýšľania. Pri rekurzii by to nebolo dobré. Niektoré ťahy by neotestovalo a mojím spôsobom by postupne prechádzalo do väčšej hĺbky.
Naklady na prenasanie dat nie su zanedbatelne, ak to prenasanie je sucast "ohodnocovania" tahu (ak testujes sach tak vpodstate testujes "dalsi mozny tah" a ak by to bolo navrhnute blbo, ze by sa kvoli jednemu ohodnoteniu 64-krat preniesla sachovnica do dalsieho bufferu cyklom po bytoch, mohla by to byt hlavna brzda). To ze ci mat len jednu sachovnicu a zoznam tahov apod. nie je vzdy tak jasne, neda sa to cele prediskutovat v prispevku v poradni. Vseobecne moze byt aj paradox ze efektivnejsi algoritmus sa da urobit ak sa obsadi viac pamate napr. pre "medzisachovnice", apod., zavisi to vzdy od konkretneho algoritmu.
Mozme zadefinovat nejaky sposob hodnotenia tahu a urobit sutaz o najoptimalnejsie(najrychlejsie) .exe (bez grafiky len ohodnotenie jedneho tahu)
P.S: nestaci ukladat odkial-kam, ptz. ak tym tahom vyhodis figurku, potom nevies urobit "vrattahzpatky", len z povodnej sachovnice urobenim vsetkych doterajsich tahov, co tiez nie je optimalne...
na win32 platformách je najrýchlejšia práca s integermi.
Ešte sa chcem všetkým poďakovať za odpovede.
Až budeš mít ten program hotový, tak nám ho půjč na vyzkoušení .
Jj, za to se primlouvam...taky bych chtel zkusit jak to bude hrat...
Jasné. To je aj motívom k rýchlemu dokončeniu.