Hlavní navigace

Vlákno názorů k článku Pohled programátora na mikroprocesory ARM od Miloslav Ponkrác - 1) PC patří mezi běžné pracovní registry u...

  • Článek je starý, nové názory již nelze přidávat.
  • 13. 3. 2012 0:37

    Miloslav Ponkrác

    1) PC patří mezi běžné pracovní registry u x86 stejně jako u ARMu.

    Zkusíte-li si měnit r15 v řadě instrukcí, v řadě z nich to špatně dopadne. Pc/r15 je stejně výjimečný a trochu stranou jako u x86.

    Co se debilní u ARMu je to, že v r15 není de facto adresa PC, takže r15 není ve skutečnosti PC. V r15 je zhusta adresa instrukce ve fázi dekódování, takže v r15 je rozdíl mezi PC a r15.

    Pan Tišnovský na to ještě nepřišel, ale občas (dost často) je nutné získané hodnoty pc posouvat a to v závislosti na režimu – takové nalepováky se na x86 nedějí.

    2) To, že v nějakém režimu je přístup jen 16 registrům bych raději moc netvrdil.

    3) Rozšíření FLAGS -> EFLAGS řešilo u x86 hlavně to, aby něco nepřeplo režimy procesoru, jinak je to kompatibilní.

    U ARMu ovšem, když se pouštíte do kritiky x86 je jiná nectnost, a to, že nezaručuje, že při špatném čísle režimu sázeném do CPSR vám to celé nezbuchne a neuletí do křeníkového nebe, přesněji do nutnosti restartu.


    Na článku je příliš vidět, že pan Tišnovský to viděl hlavně teoreticky, ale v praxi by zjistil, že kritika x86, stejně jako jiná tvrzení jsou dost na hraně.

    V ARMu se pohybujete low level a řada hodnot přímo adresuje jednotky a nebo se táký nějaké části uvnitř. x86 hodně odstiňuje a je velmi komfortní.

    A to je ARM jeden z lepších procesorů.

    Co by rozhodně mělo být zmíněno jsou tři fakty:

    1) ARM má problémy s konstantami, díky fixed size délce instrukcí se mu do nich nevejdou všechny 32bitové konstanty a je třeba to obcházet. A to dost hnusně.

    2) ARM má problémy dosáhnout pointery na větší vzdálenost. Pointery do 12bitového offsetu se dají uložit do některých instrukcí přímo, dále musíte použít registr a přidat další instrukce.

    3) Load/store architektura je velmi čistá, ale řada věcí se tam řeší díky tomu přes ruku. Zpomaluje to výkon.

    Díky 1,2,3 je velmi těžké optimalizovat instrukční sadu a najít nejefektivnější kód. Trvalo mnoho let experimentů, než se našly konvence, které jsou nejefektivnější.

    Něco jiného je optimalizovat 4 instrukce a něco jiného delší kód, kde stačí jedna nevhodná hodnota konstanty a optimální kód instrukcí pak vypadá zcela jinak a vše je nutné překopat pokud jde o max. rychlost.

    Vzhledem k omezené délce pointerů (ad 2) a omezené možnosti hodnot konstant (ad 1) je nutné rozhazovat hdonoty konstant a pointerů nikoli do datového segmentu nebo read only segmentu programu, ale poměrně nečistě přímo ke kódu. A je nutné třeba hodnoty konstant uložit několikrát, aby byly blízko ke kódu, který je používá, aby tam dosáhly offsety pointerů.

    Teoreticky ARM vypadá jako príma a super, prakticky zjistíte, že je to maso, protože ARM v podstatě problémy hw architektury neřeší, ale hází je na krk přímo do strojáku ať je řeší programátor v asm. x86 naprosto tomu programátora od problémů dost odstiňuje a je mnohem luxusnější z pohledu asm.

  • 13. 3. 2012 4:06

    klusacek (neregistrovaný)

    (1) To vzniklo pipeliningem a snahou na ARM-1 setrit transistory. Kdyz prijde IRQ (asynchronne) tak procesor ulozi r15 do r14irq (a novjejsi verze CPU jeste CPSR do SPSRirq) a vstoupi do preruseni. Jenze v r15 tou dobou uz byla adresa popristi instrukce, takze z preruseni se nevraci pomoci mov r15,r14, ale jako subs r15,14,#4 aby to skocilo na pristi instrukci. Je to rychlejsi nez ji odecitat jeste pred vstupem do IRQ. Jestli se vam to nelibi, nadefinujte si makro iret jako
    subs pc,lr,14 a budete se citit temer jako doma (az na to ze v ABORT vyjimkach je ta konstanta myslim jina).

    Na novejsich ARMech to z hlediska HW uz asi neni tak vyhodne (pipeline je jinak dlouha) ale bylo to kodifikovano v ARM-ARchitecture reference manual, takze se to chova vsude stejne.

    Kdyz volate podprogram tak se do r14 dostane skutecne adresa instrukce na kterou se to ma vratit.

    (2) Pristup je prave k 16ti registrum ve vsech rezimech + CPSR a v privilegovanych rezimech tez k SPSR (ale k CPSR a SPSR se dostanete jen pomoci specialnich instrukci ktere presouvaji data mezi xPSR a beznymi registry). Ktere registry z tech 16ti se pouziji urcuje mod cinnosti. Navic je mozne (kvuli prepnuti kontextu) udelat LDM/STM ze zastinenych registru usermodu aby bylo mozne provest z privilegovaneho modu context-switch. Po pouziti takoveto instrukce se pak nasledujici takt nesmi pristupovat k zastinenym registrum. Uznanavam ze je to trochu slozitejsi, ale na druhou stranu to budete potrebovat jen pokud chcete psat OS. Ty komplikace vesmes vznikly pridanim registru CPSR/SPSR do puvodni ARM-2 architektury. V porovnani s prepnutim kontextu na Intelu je to ale stale snadne.

    (3) Do CPSR nemuzete v user modu zapsat spatne cislo, protoze muzete menit jen flagy ale ne mode. V privilegovanych modech kde zapisovat muzete cokoliv ma bezet jen OS u ktereho se programatori snazi aby to nedelal.

    (4) S konstantami mate pravdu, treba takovy mips s load-hi a load-lo je na tom asi lepe. Na ARMu se konstanta generuje 2ma instrukcemi pomoci ALU (ruznych posunu scitani) z 8mibitovych konstant, nebo jednou instrukci se nacta ze z pameti +-4KB do mista kde ji potrebujeme. Slusny assembler to udela za vas.

    (5) Pro cteni konstant to obcas vadi, ale pri beznem pouziti pointeru stejne mate adresu v registru, takze by to vadilo jen kdyby se pristupovalo ke struct{} jejiz sizeof() je vetsi nez 4KB a to neni prilis caste.

    (6) Pro load/store se snadneji generuje kod. Navic pokud load/store jednotka umi pracovat paralelne s vypocetni jednotkou jako treba v SPE of Cell je to i velmi rychle.

    (7) Najit nejefektivnejsi kod je nerozhodnutelny problem. Nicmene pokud je procesor jednoduchy je obvykle snazsi najit dobry kod, nez kdyz je slozity. U intelu (ale nejen u nej, tyka se to prakticky vsech out-of-order procesoru) je problem uz v tom ze staticky (tj. jen z kodu) lze jen tezko urcit jak dlouho bude trvat (protoze to zavisi na tom co CPU delal 100 taktu pred tim a co je a co neni v cache, apod.). V takove situaci se pak blbe optimalizuje protoze neni jasne ktera sekvence instrukci je vlastne lepsi (z hlediska vyuziti jednotek).
    Ten problem s konstatami ktery popisujete je oproti alokaci jednotek jeste celkem resitelny.
    Pokud konstatny nevygenerovatelne 2ma ALU instrukcema ulozite mezi funkce nebo za else v podminkach tak ani nepribyde dalsi jump kterym by se oblast konstant preskakovala. Obvykle na kazde 4KB je aspon jeden konec funkce nebo else.

    V assembleru jsou na to pseudoinstrukce, takze konstatnu normalne zapisete do kodu a kdyz pak vidite vhodne misto kde by mely lezet tak napisete .pool a je do toho mista ulozi. Nevidim na tom nic necisteho -- u intelu kdyz mate immediate operandy tak jsou taky ulozeny v code-segmentu a ne mezi konstantami.

    (8) Prevest problemy z runtimu CPU na programatora ASM byl zamer architektury RISC. Navic se od zacatku pocitalo s tim ze se pouzije optimalizujici kompilator, ne ze to budou lidi programovat rucne. Ten luxusni assembler of x86 myslite jako vtip? Nebo mate na mysli aspon x86-64?

  • 13. 3. 2012 4:23

    Pavel Lang

    No, byl jsem pomalejší, zato méně výstižný než tvoje odpověď, nemám výtky, fakticky si myslím je to bez chyby :-)

  • 13. 3. 2012 13:10

    Karel (neregistrovaný)

    (7) je jeden z důvodů, proč některé JIT překladače generují rychlejší kód než nativní kód v C nebo ASM. JIT překladače jsou zajímavý zdroj informací o fungování procesorů.

  • 13. 3. 2012 13:51

    Miloslav Ponkrác

    Jeden z důvodů, proč člověk když skočí okna padá nahoru a po nějaké době se dostane na povrch Měsíce.

    Jenom jsem parafrázoval, že můžu také tvrdit kdejakou hovadinu aniž bych jí podložil realitou.


    Navíc napsat, že JIT generují rychlejší kód, než v asm. Asm je právě od toho, aby člověk v něm mohl napsat nejrychlejší možný kód. Vezmete-li machra na asm/stroják v nějakém procesoru, tak rychlejší kód nedostanete, dáte-li mu dostatek času.

    A ano, už jsem se, zejména od Javistů, dozvěděl i takové hovadiny jako že JIT generuje rychlejší kód, než je storják procesoru, na kterém JIT běží.

    Měl byste tvrdit pouze promyšlené a podložené věci. Oni v Rudém právu o JIT napíší všelicos.

  • 13. 3. 2012 14:14

    Sten (neregistrovaný)

    Ono to může někdy vypadat, že JIT umí vygenerovat rychlejší kód, protože pokud použije hodně pokročilé run-time optimalizace, třeba vyhází branche, které na daném zařízení nebo za dané konfigurace nemohou nastat, tak ten kód bude rychlejší, než když se dané branche testují. Ale tyhle runtime optimalizace jdou samozřejmě dělat i v C (máme LLVM), C++ (kromě LLVM třeba i pomocí virtuálních metod) a assembleru (jako sebemodifikující kód).

  • 13. 3. 2012 14:49

    bez přezdívky

    To jste si vymyslel? Zatim jsem od žádnýho javisty neslyšel, že by JIT generoval rychlejší kód než stroják procesoru. IMHO je to kravina.
    Maximálně jsem se od Javistů dozvěděl, že JIT-HotSpot dokáže dělat optimalizace za běhu a zrychlit běh programu. A že v některých případech může být i rychlejší než stejný program napsaný v C/C++ bez nějakých hacků v assembleru. Asi tak.

  • 13. 3. 2012 18:43

    Karel (neregistrovaný)

    Jádro sporu je v tom "dáte-li mu dostatek času". I já dokážu v assembleru napsat nekomplikovanou funkci rychlejší, než sebelepší překladač. Otázkou je, jak dlouho mi tohle vydrží. Dříve nebo později začnu dělat chyby v predikcích skoků a u složitějších funkcí popíšu celý flipchart mapou dat. Jakmile se dostaneme k práci s FPU nebo polem dat, tak tady už já konkurenceschopný nebudu.

    Co se důkazů mého tvrzení týká, tak žádné nejsou. Respektive je jich plný internet, ale kdo by tomu věřil? Při tom množství programů a hlavně programátorů je to spíše o statistice a ne o důkazech.

    Pokud ale máte zájem, tak třebas s Javou a jejím JIT můžete experimentovat. Stačí jednoduché úlohy jako fraktály, komprese .jpg, FFT nebo třebas .mp3. Poměrně snadno se dokážete dostat do situace, kdy ta Java bude rychlejší než váš kód v assembleru. Nebo zkuste C/C++, kdo by se v assembleru psal s fpu. Výhoda JIT je v tom, že umí za běhu měřit a pak se podle toho rozhodovat. Kdysi jsme to ověřovali na distribuovaném algoritmu pro triangulaci planárních grafů. Solarisové stanice si hezky chrochtaly stálou rychlostí, zatímco ta s MS Windows po nějaké době zrychlovala. Ta měla jednu z prvních verzí HotSpotu a nakonec byla Java 1.3 rychlejší než to samé napsané v C a kompilované pomocí GCC s optimalizacemi. Prostě tomu sedla úloha - procházení grafu, porovnávat čísla a sem tam vypočítat pár součinů.

  • 13. 3. 2012 22:31

    Biktop (neregistrovaný)

    GCC zrovna efektivitou výsledného kódu příliš neoplývá. Výhoda GCC leží v tom, že generuje kód pro kde co a bylo portováno na kdejakou platformu. Použijete-li pro x86 platformu nějaký intelácký překladač, bude výsledný kód o dost lepší.

    Jak bude Java rychlejší při FFT než assembler, u toho bych chtěl vážně být. :-D Tenhle algoritmus už jsem implementoval v assembleru několika různých procesorů tolikrát, že by mě opravdu zajímalo, jaká kouzla s tím Java může ještě dělat, která normální assemblerista neudělá.

    A pokud bych chtěl opravdu rychlý kód pro nějakou náročnou úlohu, obvykle výpočetní, tak to napíšu ve Fortranu, jehož překladače, pokud je mi známo, stále ještě nekompromisně válcují v rychlosti výsledného kódu vše ostatní. A to přesto, že dnes už nejde o dominující jazyk, do vývoje jehož překladačů by se dávaly nějaké závratné prostředky.

  • 14. 3. 2012 11:24

    Marek Knápek

    A bude ten Váš Fortranní překladač optimalizovat pro SSE4 apod? Vsadím se že C/C++ překladač to bude dělat spíš.

  • 14. 3. 2012 22:32

    Biktop (neregistrovaný)

    Např. Intel Fortran to samozřejmě dělá. Fór je v tom, že C/C++ překladač není schopen některé optimalizace udělat už z podstaty toho, jak je ten jazyk koncipován. Fortranský překladač má k optimalizacím k dispozici mnohem více informací a prostoru. Když ve Fortranu napíšu např. FORALL místo DO (které by v C odpovídalo zhruba příkazu "for"), může překladač vesele optimalizovat, přerovnávat pořadí nebo rozhazovat na více procesorů. Tím, že Fortran je přeci jen komplexnější jazyk na vyšší úrovni než C, má překladač o těch objektech a operacích víc informací - ví, že to a to je pole a ne jen nějaký ukazatel, že to a to je maticové násobení a ne jen nějaká knihovní funkce pracující s nějakými ukazateli atp., tudíž ví, co si s těmi konstrukcemi může a nemůže dovolit udělat, aby to zrychlilo běh, ale aby to "na funkci nemělo vliv". :-)

  • 15. 3. 2012 15:42

    JSH (neregistrovaný)

    C++ překladače běžně zvládají přerovnávat a vektorizovat "normální" for cykly stejně, jako by pro ně byl speciální syntaktický výraz. Normálním myslím něco jako for(int i = 0; i < max; ++i)

  • 15. 3. 2012 18:57

    Biktop (neregistrovaný)

    Podle toho, co to znamená "běžně". Četl jsem asi tak před rokem článek na toto téma a neřekl bych, že "běžně" je to správné slovo. Občas se jim to v některých speciálních případech povede odhalit.

  • 15. 3. 2012 19:32

    Sten (neregistrovaný)

    GCC i Clang to umí odhalit snadno, ať už jde o iteraci pomocí indexu nebo pomocí iterátoru, pokud to je některá běžná forma, např. (VARIABLE = VALUE; VARIABLE COMPARISON VALUE2; INCREMENT/DECREMENT VARIABLE) nebo (VARIABLE = VALUE, VARIABLE2 = VALUE2; VARIABLE COMPARISON VARIABLE2; INCREMENT/DECREMENT VARIABLE/VARI­ABLE2). Dokonce umí celkem dobře odhalit, pokud je takový cyklus nekonečný nebo spoléhá na přetečení.

  • 13. 3. 2012 19:13

    atarist (neregistrovaný)

    Mozna bylo mysleno, ze JIT dokazou generovat lepsi kod, nez ten vytvorenej na zaklade staticke analyzy a nasledneho naprogramovani v C nebo ASM. To je jiz z principu nepopiratelne, protoze JIT ma k dispozici runtime informace ;-) v praxi to vsak neni tak horke, protoze malokdo si lajzne vytvorit implementaci cehokoli bez benchmarku na realnych datech.

    Obecne by to slo napsat tak, ze nekde do kodu napisu: sort(pole) a v idealnim(!) pripade teprve JIT rozhodne, jak ten sort ma vypadat, ze treba pro muj problem je nejvyhodnejsi pitomy bubble sort (to se klidne muze stat pri sortovani po jednom insertu).

    Ovsem to by musel byt hodne vysokourovnovy jazyk, nejake 4GL apod. a potom JIT se vsemi informacemi o kodu, protoze soucasne JIT nektere informace o algoritmu ztrati prekladem do bajtkodu (to je asi jejich nejvetsi nevyhoda).

    Nekde na puli cesty mezi kompilatorem, ktery vidi jen kod (tj. jen jedno z moznych priblizeni ke kyzenemu algoritmu) a plnohodnotnym JIT je napriklad nova funkcionalita gcc, ktery dokaze program spustit a nejak se poprat s runtime daty, co tim ziska.

  • 13. 3. 2012 20:13

    Mi. Chal.

    "Asm je právě od toho, aby člověk v něm mohl napsat nejrychlejší možný kód. Vezmete-li machra na asm/stroják v nějakém procesoru, tak rychlejší kód nedostanete, dáte-li mu dostatek času."

    To jsou často šířené povídačky fanatiků do assembleru. Teoreticky je to pravda, prakticky je ale otázka, jak velký projekt se tím dá reálně zvládnout. Pokud to bude hodně optimalizované, tak je to spíš write only jazyk, v kterém se někdo jiný bude těžko orientovat (po nějaké době to bude platit i pro autora kódu). Výsledkem je, že dokážete napsat o 5% rychlejší kód a strávíte tím 20x delší dobu než když to napíšete v nějakém vyšším jazyce

  • 13. 3. 2012 22:16

    Biktop (neregistrovaný)

    Ale no tak! To bych zase mohl já říct, že podobné povídačky šíří lidi, kteří místo aby přiznali, že jsou holt hloupější než jiní, tvrdí "ten assembler je na nic". V assembleru se (narozdíl od spousty jiných programovacích jazyků) neprogramovalo nikdy pouze teoreticky, ale prakticky v něm vznikly rozsáhlé programy, knihovny a systémy. A možná že ta nutnost postupovat v assembleru metodou KISS nebyla vůbec od věci - ty systémy většinou psalo méně lidí než dnes, stihli to rychleji než dnes, stálo to méně než dnes a relativně k HW to bylo rychlejší a spolehlivější než dnes. Osobně se domnívám, že vyšší jazyky představují pro spoustu problémů takovou dvojsečnou zbraň - umožňují snadněji řešit komplexnější a složitější problémy, takže vývojáře nemotivují k tomu, aby se řešení takových problémů v první řadě snažili zcela vyhnout.

  • 13. 3. 2012 23:33

    JSH (neregistrovaný)

    Tak tohle je pěkný blábol. Před assemblerem se překládalo ručně, programy se "vyšívaly" do ROM z feritových jader a taky v tom vzikly rozsáhlé programy.

    Nebylo to třeba taky tím, že ty systémy byly daleko jednodušší než dnes? Pokud je to moc složité, aby se to dalo napsat v assembleru, tak je lepší se na to vykašlat?

    V dnešní době se assembler hodí na velmi málo místech jako jsou kousíčky operačního systému, nebo pár kritických míst nějakého programu. Na většinu věcí je assembler mrhání času, lidské práce a tím i peněz.

  • 14. 3. 2012 1:07

    Biktop (neregistrovaný)

    A čo vy si, Kefalín, predstavujete pod takým pojmom "ďaleko jednoduchšie"?

  • 14. 3. 2012 14:46

    JS (neregistrovaný)

    Daleko jednodussi by v tomto kontextu mohlo znamenat, ze samotne programovani kladlo omezeni na pozadavky na vysledny program. Napr. omezeni na pocet neceho, na znakovou sadu, na delku jmen, na zpusob zpracovani.. atd.

  • 14. 3. 2012 8:27

    Mi. Chal.

    Proč by lidi nepracující v asm měli být hloupější než jiní? Neříkám, že assembler je k ničemu, ale že na většinu věcí se hodí vyšší jazyky a zvládne se to rychleji. Dneska je levnější mít o něco pomalejší sw, než čekat půl roku, než se to o trochu zrychlí (což nakonec třeba ani nikdo nepotřebuje), navíc se to dá dohnat rychlejším hw, který bude pořád levnější než půl roku vývoje.

    Co se týče spolehlivosti, tak to je dost sporné - assembler dělá přesně to, co člověk napíše, takže když tam naseká chyby, tak to nebude fungovat. U vyšších jazyků lze dělat i statickou analýzu kódu a řadu problémů odhalit, nemluvě o tom, že některé chyby tam ani udělat nejde (třeba počet předaných parametrů)

  • 14. 3. 2012 11:46

    Biktop (neregistrovaný)

    Já jsem nenapsal nepracující, ale odsuzující. Připadá mi to podobně směšné, jako kdyby mi nějaký truhlář řekl, že bez horní frézky a stolní pily se nedá nic udělat a "bludy", že nejjemnější finesy a detaily stejně nejlépe uděláte jedině s pomocí dlátek a vyřezávacích nožů, šíří jen jacísi fanatičtí zastánci ruční práce a že udělat nábytkový komplet bez elektrického nářadí je prakticky nad lidské síly. Nešlo by o problém toho nářadí, ale o to, že daný truhlář má obě ruce volšový, když je práce s klasickými truhlářskými nástroji nad jeho síly. Pak se procházíte nějakým zámkem a co místnost, to důkaz nesmyslnosti výše uvedeného tvrzení.

    Nikoho nenutím, aby něco dělal v assembleru, ale ať proboha netvrdí, že se v něm nějaký projekt nedá udělat pro přílišnou složitost nebo že vyšší jazyky ho překonávají v rychlosti či hustotě kódu.
    Povídačky o tom, kolikrát je programátor v assembleru méně produktivní, než jeho kolega pracující ve vyšším jazyce, jsou taky spíše z říše fantazie a obecně rozšířených nepravd lidí, kteří v assembleru v životě nic většího nenapsali.
    Hlavními výhodami programovacích jazyků je to, že jsou (1) přenositelné a (2) nevyžadují od vývojáře tak podrobné znalosti architektury. Do vývoje FORTRANu se nepouštěli kvůli tomu, že by programátoři v assembleru byli neproduktivní, ale aby si program na výpočet turbíny mohl napsat sám inženýr, který tomu rozumí, a nemusel to složitě vysvětlovat programátorovi a při přechodu na jiný počítač nemusel začít zase od nuly.
    Neříkám, že to jsou nějaké zanedbatelné výhody - naopak! Jsou to právě tyto dvě věci, jež činí assembler nedoporučovaným nástrojem, není-li jeho použití opravdu nezbytné. Ale určitě to není nějaká nižší produktivita práce v něm. Zvláště na architekturách, používajících algebraickou formu zápisu assembleru, je docela dobře vidět, že rozdíl mezi jím a např. v současnosti hojně užívaným jazykem C je mnohem menší, než si spousta lidí připouští.

  • 14. 3. 2012 12:06

    Nejchytřejší (neregistrovaný)

    Váš problém je v tom, že vy asi nechcete chápat rozdíl mezi
    a) nejde = je technicky nemožné a
    b) nejde = je ekonomicky nemožné

    V běžné diskuzi se slovo nejde používá v obou významech.

  • 17. 3. 2012 11:44

    homunculus (neregistrovaný)

    Jezis co furt vsichni mate? Vy jste asi fakt mentalne retardovani, kdyz si neumite predstavit, ze v asm se da normalne programovat, jako v cemkoliv jinym. Clovek si pripravi par maker, stanovi si pravidla jak vyuzivat registry a uz jede. Fakt nechapu, co vam na tom prijde tak svetobornyho. Tak radsi bezte delat metare nebo tak neco podobnyho, kdyz na prgani nestacite. OMG!

  • 17. 3. 2012 13:17

    zimiston (neregistrovaný)

    Předpokládám teda, že ty i Biktop se živíte jako programátoři a programujete v assembleru aplikace pro zákazníky a normálně se tím uživíte, protože vaše produktivita je srovnatelná s konkurencí. Je to tak?

  • 17. 3. 2012 14:16

    Mi. Chal.

    Neříkám nejde - na některé malé části nebo pro některá slabší zařízení bych to klidně použil. Ale podle mě je nemožné nebo příliš složité v tom napsat větší projekt a dokázat to udržovat a opravovat případné chyby. Kolik řádků kódu má např. nějaký větší projekt v asm, na kterém v práci děláte?

  • 17. 3. 2012 21:16

    atarist (neregistrovaný)

    Da, ale ma to smysl jen pro specialni projekty a urcite ne pro desktopove aplikace nebo servery. Protoze potom prijde sef se slovy "tak jsem ten tvuj skvelej program ukazal zakaznikovi a on si chce koupit licence na S390 a taky par na i586. Ty to sice mas psany pro x86_64, no ale to snad neni takovej problem to do pristiho tydne upravit, ne? Tak hodne stesti..." :-)

    Jak rikam, jsou specialni pozadavky, kde to ma mega smysl - mikroradice s par kilobajtama ROM a treba pul kilobajtem RAM, semtam nejakej kodek, ted se hodne resi kryptovani a urcite je toho vic, ale v pomeru k ostatnim aplikacim je to kolik? 0,1% trhu?

    Jinak s vasim pristupem - udelam par maker, reknu si, jake registry pro predavani parametru, jake pro vyrazy atd. to teda neudelate nijak velkou diru do sveta s vykonem - preji prijemne chvilky upravou pro superskalarni masiny, zjistovanim, co zase Intel zmenil v casovani instrukci (INC EAX je delsi nez ADD EAX,1 - no to me poser)... :-'

  • 18. 3. 2012 10:10

    JSH (neregistrovaný)

    "udelam par maker..."
    Vlastně si tím napsal hodně jednoduchý jazyk vyšší úrovně :)

    Jestli si dobře pamatuju, tak na některých AMDčkách byly některé instrukce rychlejší s ukazatelem do paměti než s registrem(pokud se trefily do cache). Myslím, že to bylo ADD, ale jistý si nejsem.

  • 18. 3. 2012 12:52

    homunculus (neregistrovaný)

    To je snad normalni nebo ne? To bych zrovna tak mohl rict ze definovanim procedur a datovych typu treba v Pascalu si "vlastne tvorim hodne jednoduchy jazyk ke svym potrebam". Jo to je mozny, v asm jsem pro x86 dlooouho nic neprgal. Ale zas - proc bych mel tunit kazdou instrukci kdyz vim, ze jde treba jen o nejaky jednorazovy hrabnuti do pameti? Snad u prgani myslim, ne? To jako protoze prgam v asm tak tim padem musim tunit kazdou instrukci jen protoze muzu?
    To nedokazete pochopit, ze nekdo dela v Jave, nekdo v C a nekdo ze proste muze delat v asm? Kdyz pisu soft pro nejaky embedecko tak si asi zrovna nemusim lamat hlavu s nejakou prenositelnosti. Posledni projekt na kterym delam ma nejakych 6000 radku a nerekl bych, ze se v tom nejak ztracim. To je prece otazka stabni kultury a ne jazyka OMG. Kdyz nekdo dela na nejakym projektu tak si to snad zorganizuje tak, aby se v tom vyznal a je jedno, jestli to dela v Lispu nebo v Brainfucku. Od ty doby co vynalezli komentare se da prehledne prgat v cemkoli. To muzete rovnou tvrdit ze od ty doby co jsou automaty je pitomost montovat manual do aut protoze je nad lidsky sily tocit volantem a jeste menit kvalty, ktery ma navic kazda kara trochu jinak.

  • 29. 3. 2012 15:14

    pc2005 (neregistrovaný)

    Hehe to jednorázový hrábnutí do paměti může trvat sice 1 takt, ale taky 400 :-D.

    Heh vlastně v případě, že dojde k TLB a D-Cache výpadku a data jsou swaplý na disku, tak se skoro vyplatí vzít papír a tužku a spočítat ručně (nadsázka). Ovšem pokud si těch milión instrukcí (nebo teda spíš 400) uděláš prefetch, tak tě to bude stát jen pár taktů.

  • 18. 3. 2012 11:58

    homunculus (neregistrovaný)

    Vzdyt to presne tu biktop psal - ze u asm je jediny problem, a to neprenositelnost. A navic kdo mluvil zrovna o intelu?

  • 29. 3. 2012 15:07

    pc2005 (neregistrovaný)

    Tento tvůj kód nebude nejrychlejší možný, dokonce bych měl podezření, že by byl často pomalejší než nejlepší překladač.

  • 17. 3. 2012 11:06

    Biktop (neregistrovaný)

    Soudě podle stylu vaší "argumentace" si troufám tvrdit, že bych to měl rychleji, než vy v tom nejnamakanějším vyšším jazyce.

  • 29. 3. 2012 15:21

    pc2005 (neregistrovaný)

    Dříve možná, dnešní OS s všeobecným sw vybavením se v assembleru prostě napsat nedá (a to ani nemluvím o výkonové optimalizaci).

  • 14. 3. 2012 19:51

    Rax (neregistrovaný)

    Žádný JIT překladač negeneruje obecně rychlejší kód v nativní kód v C/C++, opak jsou oblíbené pohádky Javistů. A na ASM se nehrabe ani C/C++, sice to sežere astronomické množství času při programování a to je velká nevýhoda ASM, ale jde se dostat na o dva řády rychlejší kód. Ve volné chvíli si můžeš nastudovat současnou implementaci funkce C/C++ memcpy, která je v čistém asm a představit si jak bys to psal v Javě :-)

  • 14. 3. 2012 20:17

    Nejchytřejší (neregistrovaný)

    No tak v ASM o dva řády rychlejší kód, než v C, jo? A pak jste se probudil, že? :-)

  • 14. 3. 2012 20:32

    Rax (neregistrovaný)

    Přesně tak, je to možné ale ne s postupy které se používaly před 20-ti lety, nýbrž je třeba se seznámit se soudobou realitou, od 80386 se událo skutečně hodně věcí.
    Jednak jsou nové instrukce, které se v kompilátoru vyššího jazyka používají obtížně, takže průměrný kompilátor na to kašle a také jsou úplně nové postupy například v oblasti cache a multi-channel memory controller.

  • 14. 3. 2012 20:56

    atarist (neregistrovaný)

    Ježiš, tak se spletl a namísto slova "procenta" použil slovo "řády" :-)

    Jestli to mysli vazne, sem s kodem, radi se podivame a porovname...

  • 13. 3. 2012 13:44

    Miloslav Ponkrác

    (1) Já vím, proč to vzniklo, ale upozornil jsem na to, že v r15 neobsahuje nutně vždy adresu pc.

    A také jsem upozornil na to, že v řadě instrukcí či v řadě případů je měnění r15 „undefined“, tedy není radno to dělat.

    Tedy r15 není stejně univerzální registr jako jiné. Tedy, že na x86 i na ARM je s registrem zacházeno speciálně – a že pan Tišnovský se nechá zmást pouhým pojmenováním, kdy v ARMu prostě dostane registr pořadové číslo a už se tvrdí, že je pc stejný registr jako jiné – mně zklamalo.

    (2) Jinak řečeno povtvrzujete co jsem psal já.

    (3) Do CSPR můžete, sice ne v user modu, ale pokud do něj můžete zapsat číslo, klidně to může zbuchnout. To se na x86 nestane, reagoval jsem tím na pana Tišnovského a jeho kritiku EFLAGS.

    Nenápadně tím naznačuji, že ARM nehlídá špatné instrukce, což je další nevýhoda proti x86, které špatné instrukce hlídá velmi důkladně.

    (4) Já vím jak se generují konstanty, ale upozorňuji, že to není přímá věc. A že se tím zbytečně vkládají další instrukce.

    A protože ARM nemá paralelní vykonávání instrukcí jako má x86, tak každá instrukce znamená zpomalení kódu.

    Navíc nutnost sáhnutí do paměti pro vyzvednutí konstanty, které by jinak na x86 mohlo být přímou součástí instrukce znamená další přistup do paměti navíc a zase další zpomalení kódu.

    (5) Znovu, vadí to a je to omezení ARM architektury.

    (6) Pro load/store se snadněji generuje kód. Ale platí to co jsem napsal u bodu 4.

    Tam, kde x86 udělá operaci jedinou strojovou instrukcí, tam ARM potřebuje tři instrukce. Navíc ARM nemá paralelní provádění instrukcí jako sofistikovanější ROSC procesory, tudíž load/store architektura znamená pomalejší kód v případě ARMu.

    Ostatně pověstná je u ARMu také pomalost reakce na přerušení a vůbec pomalost zpracování I/O podnětů.

    Load/store architektura bez paralelní zpracování instrukcí je vždy výkonnostní mínus jako hrom. A to u ARMu je.

    Přestože se pro load/store generuje lépe matematickými metodami kód.

    Mimochodem, právě load/store architektura si vynutila obrovské množství módů a režimů, protože neexistuje způsob, jak uložit v obecném případě hodnoty registrů někam do paměti, třeba při přerušení, nebo v podprogramu aniž byste nějaký nezměnili. Tudíž musel pomoci sám procesor a vymyslel režimy a různé další věci.

    (7) Najít optimální kód je prostě věc matematických algoritmů, pokud to dělá kompilátor. Ovšem v případě ARMu a jeho asymetrie třeba v případě konstant, pointerů, atd. to není tak čisté a jednoduché, jak popisuje.

    Já vím, jak se dělá v assembleru. Myslím, že je zřejmé, že jsem s ARMem trváil nejen teoreticky.

    (8) Ne, záměrem RISCu nebylo to co píšete. Záměrem RISCu bylo udělat primitivně jednoduchý procesor – a tím rychlejší. Tedy zjednodušením instrukční sady procesoru zjednodušit architekturu procesoru samotnou. To bylo relevantní v době, kdy procesory přímo vykonávaly instrukce, ne v dnešní době, kde vykonávají mikroinstrukce.

    Ano, s luxusní sadou x86 to myslím vážně. Ochechule s konstantami, nebo s tím, zda pointer dosáhne dostatečně daleko, nebo s tím, zda náhodou nepoužijete instrukce, který má „undefined“ chování, protože ARM to nekontroluje a mnohé další lahůdky na x86 nezažijete.


    Jinak já nekritizuji ani tak ARM, jako spíše velmi teoretický článek o ARMu od pana Tišnovského.

  • 13. 3. 2012 14:11

    Pavel Tišnovský

    Nechapu co porad mate proti te zmene PC. Vsechny ARMy (minimalne od 7) se v tomto ohledu chovaji stejne a dost casto se jeho zmena pouziva pri emitu kodu v JIT a to bez problemu - opet rikam, staci se mrknout do zdrojaku, pro jednodussi cteni doporucuju zacit s interpretrem misto JIT: cppInterpreter_as­m.S pro ARM, je to okomentovany a dobre citelny.

  • 13. 3. 2012 14:34

    Sten (neregistrovaný)

    Vyvrátím jenom těch pár chyb, kterých jsem si hned všiml:

    3) Špatný zápis do kontrolních registrů x86 sice vyhodí hardwarovou výjimku, ale chtěl bych vidět operační systém, kde to potom nezbuchne.

    4) To řeší datová cache. A třeba takové dynamické linkování taky používá tabulky ukazatelů (jejich používání je AFAIK mnohem častější než používání konstant větších než 4096) a tam má ARM výhodu.

    6) ARM superskalární frontu (paralelní provádění instrukcí) má.

  • 13. 3. 2012 15:52

    klusacek (neregistrovaný)

    (1) r15 nemuze byt uplne jako universalni registr -- vzdyt zapisem do nej provedete skok! To se projevi vyprazdnenim pipeliny, prinejmensim. Takze semantickemu rozdilu neuniknete. Nevim co Vam porad vadi -- to ze bezi o 2 instrukce posunuty?

    (2) Kdyz si do konfiguracnich registru AMD K10 napisete v privelegovanym modu blby cislo tak to taky nebude fungovat --- videl jste nekdy bootup sekvenci? -- takovou tu co provadi BIOS? Jak nejdriv cache CPU se zkonfiguruje jako lokalni RAM, pak zjistite pres SPI co mate za RAMku, zkonfigurujete radic RAMky, atd.... pak prekonfigurujete cache zase zpet a zapnete RAM. Kdyz neco z toho udelate blbe (zapisete nekam blby cislo) tak to taky nebude fungovat.
    Proste do modu procesoru zapisujte spravny cisla, pokud pisete OS, a bezny programator to nemuze udelat takze to nezbuchne.

    (3,5) Vy jste nejak posedlej symetrii. Ale kdyz chcete 32bit konstatnu tak byste musel mit delsi nez 32bitove instrukce. Na intelu se taky rozlisuje jestli je ta konstanta kratka nebo dlouha --- pak je ulozena tesne za instrukci (jako immediate operad). Na ARMu se to lisi jen tim ze je ulozena trochu dal (a muze byt sdilena vice instrukcemi). Tohle maji v nejake forme vsechny RISC procesory, krome tech s harwardskou architekturou (napr. PIC), ktere to resi tim ze delka instrukce je vetsi nez delka nativnich dat procesoru a program je v jine pameti nez data (coz je ponekud neprakticke, komplikuje to zavadeni programu z vnejsi pameti).

    (6) Obcas zase tam kde ma i86 3 instrukce potrebuje ARM jedinou. Vetsina programu ale pristupuje ke svym datum lokalne. Proto funguje cache a spousta registru a load/store se neprovadi tak casto.

    Jak myslite pomalost reakce na preruseni? Mate predstavu kolik na i86 trva taktu nez se zacne zpracovavat IRQ handler? ARM ma celkem rychlou reakci na preruseni --- dokonci instrukci vstoupi do preruseni (zavede instrukci z 'vektoru preruseni', kde je obvykle skok (ale FIQ, ktery je na konci muze byt rovnou obsluha)). Nejdelsi instrukce kterou by musel dokoncit (LDM) ma na ARM7 zhruba 20 taktu + 3 takty na ten skok + 2 takty na synchronizaci --- tedy nejpozdeji za 25 taktu (+- nejake drobne, nechci to ted hledat v manualu) se provadi handler preruseni. Uznavam ze jsou CPU s jeste mensi latenci, treba MIPS, kde ani nedojde k vyprazdneni pipeliny (jestli se dobre pamatuju), ale 25 taktu v nejhorsim pripade neni vubec spatna hodnota. Navic mate bankovane registry a v nich uz muzete mit pripravena data, cimz usetrite mnoho pristupu do pameti, takze driver preruseni muze driv zacit delat uzitecnou praci.

    Ad load/store:
    Mate na mysli ARM architekturu obecne nebo nejaky konkretni ARM procesor? Treba ARM7 by bylo fairove porovnavat nanejvys s 286kou, a ta take nema paralelni load/store a vypocty. Naproti tomu treba A8 Cortex je 13stage-pipeline dual issue machine. Takze ten load/store muze delat zaroven s jinou instrukci.

    http://www.design-reuse.com/articles/11580/architecture-and-implementation-of-the-arm-cortex-a8-microprocessor.html

    Pak uz v load/store a x86 neni takovy rozdil -- AMD si stejne vnitrne preklada instrukce do load/store jazyka ktery pak provadi, a takovy inc memory se prelozi do 3 instrukci.

    (7) Tak znovu: Neexistuje algoritmus ktery obecne najde optimalni kod (ve smyslu ze ten kod je nejkratsi mozny nebo ze bezi nejkratsi moznou dobu). Ale muzete se snazit najit kratky kod (obecne), nebo v pripade ze v tom kodu nejsou skoky tak jde najit i ten optimalni. Asymetrie konstant prilis nevadi, mnohem horsi je kdyz nevite jak dlouho bude co trvat + omezeni na pouzitelne registry (coz MUL a DIV na intelu nemylim-li se stale maji).

    (8) Dovoluji si upozornit ze v dobe kdy vznikl RISC vykonavaly procesory mikroinstrukce -- dokonce IBM mela jednu dobu takvou predstavu ze z mikroinstrukci vytvori tak komplexni assembler, ze se vyrovna vyssim jazykum. Myslim ze o tom pan Tisnovsky taky psal.

    To ze to jde bez mikroinstrukci mnohem rychleji byl tehdy dost dulezity objev.

    (9) Nedefinovane instrukcni kody na ARMu zpusobi vyjimku. To co myslite vy je, ze nejaka kombinace operandu je 'zakazana', (pripadne je zakazano pristupovat k nejakemu registru, pokud se pred tim provedla urcita instrukce) ale procesor to netestuje -- vysledek operace je nedefinvan. To neznamena ze to vzdy zbuchne, to jen znamena ze na ruznych implementacich to muze dopadnout ruzne (vcetne treba vyjimky na lepsich procesorech). Uz zde byl priklad s tim ze 8086 se lisila od 286 tim, ze kdyz jste si prepsal ponasledujici instrukci tak 8086 provedla tu novou, kdezto 286 tu starou, protoze uz mela tu puvodni ve fronte.
    Takze moderni teminologii by tato operace byla (v ramci architektury) nedefinovana.

    Urcite ma Intel vic podobnych vlastnosti. Nyni treba AMD (nedobrovolne) zavadi, ze mezi pop;pop;pop; a ret se musi vlozit nop (u 64bit modu je to bug, ale v 32/64 bit modu je to regulerni pozadavek na programatora popsany v dokumentaci).

    Me mnohem vic vadi nedefinovane chovani v norme Ccka a to jak ho moderni kompilatory zneuzivaji --- v Ccku je napsano, ze jakmile program pouzije nedefinovaou konstrukci (treba x<<y) kde nejde zarucit, ze 0<=y<31, tak je cely program (ne jen ta jedna operace) spatne a muze delat cokoliv (treba zformatovat harddisk). Takze jestli zkousnete tohle, tak to ze nektere konstrukce v assembleru arch ref manual zakazuje je uplny detail.

  • 13. 3. 2012 18:56

    atarist (neregistrovaný)

    uz ti neodpovi :)

    Ale s tim posunem je to zajimavy, ze v Jave je presne to chovani popsano (konkretne se vzdy druhy operand pocita % 32). Takze pozor na to v pripade longu :)

  • 13. 3. 2012 19:45

    Pavel Tišnovský

    ad 8) to je pravda, tech projektu bylo dokonce vice - existovala takova myslenka, ze by se zmensila semanticka mezera mezi assemblerem a vyssim programovacim jazykem, samozrejme tim, ze by se assembler (a tim padem i instrukcni sada) upravily tak, ze by primo podporovaly nektere vysokourovnove konstrukce.

    Z tech komercne uspesnejsich reseni to bylo IBM 360 a taky VAX, ktery sel s myslenkou CISC snad uplne nejdal. Nektere snahy jsou videl i na architekture x86, viz napriklad instrukce ENTER, LEAVE (asi pro pascalovske zasobnikove ramce a cally?), mozna bych sem zaradil i BOUNDS a castecne take vsechny MOVS...

    Kdyz do tohoto prostredi prisla myslenka RISC, navic podporena funkcnim cipem, tak to zpusobilo dost rozruch :-)

  • 13. 3. 2012 20:10

    zimiston (neregistrovaný)

    No ta myšlenka byla např. v projektu iAPX 432 (http://en.wikipedia.org/wiki/IAPX_432), která stála Intel málem život.
    Po létech vývoje to nakonec bylo 4x pomalejší než 80286.

  • 14. 3. 2012 22:53

    Pavel Tišnovský

    Presne, vsak pisu "z tech komercne uspesnejsich" :-) Jinak Intel porad zkousi ruzne alternativy k x86, napriklad (kdyz jsme u tech RISCu) i860 a i960, dale pak IA-64 s EPIC atd. Nakonec je zajimave, ze se naslednikem x86 stala x86_64 od konkurence :-)

  • 30. 3. 2012 0:05

    pc2005 (neregistrovaný)

    3)
    "Nenápadně tím naznačuji, že ARM nehlídá špatné instrukce, což je další nevýhoda proti x86, které špatné instrukce hlídá velmi důkladně."

    f00f? :-P a ze současné doby teďka něco s překladačem gcc.

    6)
    "Tam, kde x86 udělá operaci jedinou strojovou instrukcí, tam ARM potřebuje tři instrukce."

    Myslíš jednu mikrooperaci x86? Jiné porovnávání je nadržování x86.

    "Navíc ARM nemá paralelní provádění instrukcí jako sofistikovanější ROSC procesory"

    Laskavě si přečti datasheet posledních 2 verzí (minimálně) ARMu. Poslední Cortex má některé z paralelní pajpy dokonce zdvojené.

    "Ostatně pověstná je u ARMu také pomalost reakce na přerušení a vůbec pomalost zpracování I/O podnětů."

    To píšeš pokaždý, můžeš napsat v čem je přesně problém (nejlépe s příkladem kódu na přesně definovaných platformách).

    8)
    "Ochechule s konstantami, nebo s tím, zda pointer dosáhne dostatečně daleko, nebo s tím, zda náhodou nepoužijete instrukce, který má „undefined“ chování, protože ARM to nekontroluje a mnohé další lahůdky na x86 nezažijete."

    Zato tam jsou "lahůdky", kdy je v manuálu skoro desítka řádků pseudokódu jak se která instrukce v daném módu x86 chová.

  • 13. 3. 2012 4:11

    Pavel Lang

    Nechci být "první", ale... load store architektura je pro překladače transparentnější, tudíš efektivnější - a to platí i o "čtverečných metrech" (přímá implikace), to platí i o taktování, není třeba mnhoha taktů pro zpracování komlexní instrukce, ale o poznání méně taktů v RISC architekruře. Bez HW "tweaků" kolik cyklů trvá zpracování instrukce v CISC architekruře?

    PC ať je to registr speciální nebo jen "obyčený", stejně je to paměťový prostor přímý (hardwarowě) k CPU (tím myslím přžímo těch pár křemíkových hradel), u RISC architektury (ARM, AVR nebo komplexnější) je to stejně pár čárek; u CISC to tak přímé nikdy být nemůže..

    Háčky, jak lze přistupovat k registrům se dělaly kvůli kompatibilitě "odjakživa", tvrdit, že to jde automaticky lépe lze, ale není to pravda, stojí to sice méně než mikrosekundu, ale musí se to tak dělat.

    load/store architektura, zejména AVR, která má jakýsi "barrel shifter" přímo v jádru instrukce, není schopná uchovat všechny konstanty v jádru programu, což se z hlediska vyšších programovacích jazyků může zdát neuspokojivé. Z hlediska často používaných algoritmů je to však v pořádku :-)

    Jakýkoliv překladač nemá problém překládat volání externích procedur/metod/pod­programů, existuje několik různých techik jak zavolat vzdálený kód, proto se ostatně začalo v minulosti mluvit o swapu...

    Strojová opimalizace kódu pro CISC architektury je mnohem optížnější (matematicky prokazatelně), stačí si jen uvědomit fakt, že existuje několik instrukcí v sekvenci, které vyřesí daný problém; je možné sai celý problém kvantifikovat do množství operací, které musejí hradla v obvodu provést, aby se vyřešila instrukce, to je sice optížnější na představivost, ale jako model pro výuku použitelnější a dnešní "grafiky" do dokážou znázornit, pokud si dají (učitelé|lekto­ři|pedagogové|pro­fesoři a kantoři) práci :-)

    Optimalizace "nevhoné" konstanty spočívá právě v načtení datového prostoru z jiného "datového" (paměťového) prostoru, tudíž ta instrukce není o nic delší datově, ale je třeba adresace a trvá déle. Nicméně je to pořád zanedbatelná obstrukce vůči translaci některých komplexních instrukcí u CISC architektur.

    Ano, překladač je nucen "překládat" nikdo nechtěl po strojovém kódu zpětnou přeložitelnost, to je jen implikace naivního výkladu opkódů CISC architektur. Sám jsem si pár programů v assembleru napsal, používal jsem návěští na adresy (jmp), ale stejně po dekompilaci jsem se v tom nevyznal. Děrné štítky jsem nepoznal, ale kdo by je dneska chtěl číst??

    ARM neřeší problémy kodéra, ale "křemíku" a to kompromisní formou.

  • 13. 3. 2012 13:53

    Miloslav Ponkrác

    Znovu:

    Matematická generace kódu je nejefetkivnější pro SYMETRICKÉ instrukční sady. Tedy sady, kde všechno jde se vším bez omezení. Kdy registry mají stejnou váhu, všechny konstanty mají stejnou váhu, atd.

    Load/store architektura není obecně matematicky lépe optimalizovatelná.

    Hlavní požadavek pro snadné zpracování je symetričnost.

  • 13. 3. 2012 14:26

    zimiston (neregistrovaný)

    Naskýtá se otázka - x86 je ukázkou symetričnosti? Jak vám tohle přijde symetrické?
    Example:
    MOV EBX,DS:[100000] / ADD EBX,DS:[100004] ; 12 bytes
    Reduce to:
    MOV EAX,100000 / MOV EBX,[EAX] / ADD EBX,[EAX+4] ; 10 bytes

    Podívejte se někdy na optimization manuály...

    A by neměly být LOAD/STORE symetrické?

  • 13. 3. 2012 14:35

    zimiston (neregistrovaný)

    PUSH 200 ; 5 bytes
    PUSH 100 ; 2 bytes

    ADD EBX,128 ; 6 bytes
    SUB EBX,-128 ; 3 bytes

  • 13. 3. 2012 14:49

    Pavel Tišnovský

    To mate naprostou pravdu, ovsem v praxi by to pravdepodobne vedlo k triadresovym kodum, mozna trosku podobnym tomu, co ma MIPS a ten trpi malou densitou kodu (no jeste symetrictejsi by asi byl triadresovy kod primo s adresami v pameti, ale to s dnesni technologii nehrozi, uz jen kvuli sbernici - proto take ten opruz s registry ;-).

    V praxi je asi nutne zvolit nejaky kompromis mezi tim nejobecnejsim triadresovym kodem a sirkou instrukci, jednotlive architektury se k tomu dostavaji z ruznych stran.

  • 30. 3. 2012 0:15

    pc2005 (neregistrovaný)

    ehm
    out dx,al
    out 0x80,al ; číslo portu může být natvrdo v instrukci jen do určité hodnoty!
    natvrdo určený registr CX ve smyčkách a v části shiftování
    natvrdo určený registr(y) v násobení/dělení
    natvrdo určený registr ve string operacích

  • 13. 3. 2012 9:26

    Pavel Tišnovský

    PC na 8086 nebyl bezny registr, dobastlovalo se to az zhruba 8 roku po uvedeni teto architektury na trh. A mimochodem, nikde v clanku neni x86 porovnavano s ARMy z hlediska PC ;-) To, co r15 obsahuje je na ARMu popsano v dokumentaci, s tim neni vetsi problem (nebo jsme na nej zatim nenarazili).

    S konstantami je to na prvni pohled pravda, na druhy pohled to v praxi neni vubec tak horke, protoze vetsina pro informatiku "typickych" konstant se da do registru nacpat pres konstantu+posun, tj. jednou instrukci. Priznam se ale, ze jsem nevidel, kolik % konstant je zapotrebi nacitat z kodu (ovsem do kodu jsem konstanty sazel i na x86 ;-) ostatne to tak delaji i prekladace).

    Osobni vytky si nechme nekde k pivu, mohl jsem se seznamit (do vetsich detailu, nez je mi mile:-) s implementaci HotSpotu pro x86 (blee) a pomerne citelnou implementaci JITu na ARM - no zdrojaky jsou open source, staci dohledat.

    Jinak si porad myslim, ze je mnohem lepsi nechat resit optimalizace prekladacem, nez aby to delal hardware v runtime. to uz je lepsi obetovat ty tranzistory na druhe jadro :-)

  • 13. 3. 2012 13:58

    Miloslav Ponkrác

    Co byl PC na 8086 je irelevantní. Jsme v době o 20 let dále. Dnešní x86 procesory jsou zcela jinde.

    To co je r15 je popsáno v dokumentaci, ale mělo to být také zméíněno v článku, když chvalozpěvujete, že pc a r15 jedno jest.

    Ad druhý odstavec, s těmi konstantami je to pravda. A každý kdo něco napsal v ARM asm, si to zažije rychle na vlastní kůži.

    Každý ARM asm kompilátor je nucen to řešit. Dokonce existuje speciální pseudoinstrukce, která narve do registru konstantu, a sama rozhodne, zda to jde přímo, nebo konstantu uloží do paměti a vyzvedne a nebo jinak.

    Já jsem nepsal osobní výtky, já jsem psal, že tam chybí podstatné informace.

    Ale jak chcete, příště budu psát jenom, že jste skvělý a geniální.

  • 13. 3. 2012 14:37

    Pavel Tišnovský

    O chvalozpevu na PC v tom clanku nic neni, schvalne jsem si to jeste jednom prolitl (a ze je vyhodny mit PC v ramci pracovnich registru je pravda, viz reseni callu a returnu, threaded kodu kdyz uz nic jineho).

    O problemech s konstantami se vsude pise, ale jak rikam, nemam po ruce zadnou statistiku, kolikrat se v kodu muselo nacteni konstanty rozepsat na dve instrukce nebo na nacteni konstanty nekde z kodu (jestli je to nekde pod % tak to neresim, to fakt neni problem, to uz na ARMech jsou jine vetsi problemy).

    Nejsem skvely ani genialni, ale bohuzel vy jste zacal s nejakymi domenkami ;-) Ja prece nemuzu za to, jak se x86 lepilo dohromady a jsem dalek toho zakryvat problemy teto architektury (x86_64 to opet jen zalepilo).

  • 13. 3. 2012 14:46

    bez přezdívky

    Holt Ponkrác. Dycky podsouvá nějaké vykonstruované argumenty, polopravdy. Příde mi jako docela kontroverzní člověk.

  • 13. 3. 2012 21:14

    _dworkin (neregistrovaný)

    Ja jsem rad za rozpoutany flame. .) Vetsinou byva jen u obecnych clanku a tady je i k veci.

  • 30. 3. 2012 0:18

    pc2005 (neregistrovaný)

    "Jinak si porad myslim, ze je mnohem lepsi nechat resit optimalizace prekladacem, nez aby to delal hardware v runtime. to uz je lepsi obetovat ty tranzistory na druhe jadro :-)"

    No když jsem si četl informace o pomocných funkcích na x86 (branch prediction/cache/tlb­/ucode dekoder) tak by se imho dostalo i na třetí jádro ;-D.