Zavřít reklamu

Mike Ash se na svém blogu věnoval praktickým implikacím přechodu na 64bitovou architekturu v iPhonu 5S. Tento článek čerpá z jeho poznatků.

Důvodem tohoto textu je převážně velké množství šířících se dezinformaci o tom, co ve skutečnosti nový iPhone 5s s 64bitovým ARM procesorem znamená pro uživatele a trh. Zde se budeme snažit přinést objektivní informace o výkonu, schopnostech a následcích tohoto přechodu pro vývojáře.

„64 bitů“

V procesoru jsou dvě části, na které se označení „X-bit“ může vztahovat – šířka celočíselných registrů a šířka ukazatelů. Naštěstí jsou u většiny moderních procesorů tyto šířky totožné, v případě A7 to tedy znamená 64bitové celočíselné registry a 64bitové ukazatele.

Neméně důležité je však poukázat na to, co „64bit“ NEznamená: Velikost fyzické adresy RAM. Počet bitů pro komunikaci s RAM (tím pádem množství RAM, které může zařízení podporovat) nesouvisí s počtem bitů CPU. ARM procesory mají kdekoliv mezi 26- a 40bitovými adresami a lze je měnit nezávisle na zbytku systému.

  • Velikost datové sběrnice. Množství dat přijatého od RAM nebo vyrovnávací paměti jsou podobně na tomto faktoru nezávislé. Jednotlivé instrukce procesoru si mohou vyžádat různá množství dat, ale z paměti se buď pošlou po částech, nebo se jich přijme více, než je potřeba. Závisí to na velikosti datového kvanta. Již iPhone 5 přijímá data z paměti v 64bitových kvantech (a má 32bitový procesor) a můžeme se setkat až s velikostmi do 192 bitů.
  • Cokoliv souvisejícího s plovoucí desetinnou čárkou. Velikost takových registrů (FPU) jsou opět nezávislé na vnitřním fungování procesoru. ARM používá 64bitové FPU už od doby před ARM64 (64bitový ARM procesor).

Obecné výhody a nevýhody

Pokud porovnáme jinak identické 32bit a 64bit architektury, obecně nejsou až tak rozdílné. To je jeden z důvodů obecného zmatení veřejnosti hledajícího důvod, proč se Apple přesouvá na 64bit i v mobilních zařízeních. Vše však plyne z konkrétních parametrů A7 (ARM64) procesoru a toho, jak ho Apple využívá, ne pouze z toho, že procesor má 64bit architekturu.

Avšak když se přesto podíváme na rozdíly těchto dvou architektur, několik rozdílů nalezneme. Ten očividný je, že 64bitové celočíselné registry umí efektivněji pracovat s 64bitovými celými čísly. I předtím s nimi šlo pracovat na 32bitových procesoru, avšak většinou to znamenalo je rozdělit na 32bitů dlouhé kusy, což způsobovalo pomalejší výpočty. 64bitový procesor tedy obecně dokáže počítat s 64bitovými typy stejně rychle jako s 32bitovými. Z toho plyne, že aplikace valně využívající 64bitové typy mohou pracovat mnohem rychleji na 64bitovém procesoru.

Ačkoliv 64bit nijak neovlivňuje celkové množství RAM paměti, kterou může procesor využít, může zjednodušit práci s velkými částmi RAM paměti v jednom programu. Každý jeden program běžící na 32bitovém procesoru má pouze asi 4 GB adresního místa. Když vezmeme v úvahu, že operační systém a standardní knihovny něco zaberou, zůstane programu někde mezi 1–3 GB k aplikačnímu použití. Jestliže má však 32bitový systém více než 4 GB RAM, využití této paměti je trochu složitější. Musíme se uchýlit k donucení operačního systému, aby mapoval tyto větší části paměti pro náš program (virtualizace paměti), či můžeme rozdělit program na více procesů (kde má každý proces opět teoreticky 4 GB paměti k dispozici k přímému adresování).

Tyto „hacky“ jsou však natolik náročné a pomalé, že je minimum aplikací používá. V praxi si na 32bitovém procesoru každý program využije jen svých 1–3 GB paměti a více dostupné RAM můžeme uplatnit v běhu více programů zároveň či využití této paměti jako vyrovnávací (cachování). Tato použití jsou praktická, avšak chtěli bychom, aby mohl každý program jednoduše využít větší kusy paměti než 4 GB.

Nyní se dostáváme k častému (fakticky špatnému) tvrzení, že bez více než 4 GB paměti je 64bitová architektura zbytečná. Větší adresní prostor je totiž užitečný i na systému s menším množstvím paměti. Soubory zmapované do paměti jsou praktický nástroj, kdy je část obsahu souboru logicky propojena s pamětí procesu, aniž by celý soubor musel být načten v paměti. Systém tak může např. postupně zpracovávat velké soubory i mnohokrát větší, než je kapacita RAM. Na 32bitovém systému takto velké soubory nelze spolehlivě namapovat do paměti, oproti tomu na 64bitovém je to hračka, díky mnohem většímu adresnímu prostoru.

Větší velikost ukazatelů však přináší i jednu velkou nevýhodu: jinak identické programy potřebují více paměti na 64bitovém procesoru (někam se tyto větší ukazatele totiž musí ukládat). Jelikož jsou ukazatele častou součástí programů, tento rozdíl může zatížit cache, která na oplátku způsobí pomalejší chod celého systému. Z perspektivy tedy vidíme, že pokud bychom pouze změnili architekturu procesoru na 64bitovou, ve skutečnosti by se celý systém zpomalil. Tento faktor tedy musí být vyvážen větším množstvím optimalizací na jiných místech.

ARM64

A7, 64bitový procesor pohánějící nový iPhone 5s, není jen běžný ARM procesor s širšími registry. ARM64 obsahuje zásadní vylepšení oproti starší, 32bitové verzi.

Procesor Apple A7.

Registry

ARM64 pojímá dvojnásobný počet celočíselných registrů než 32bitový ARM (pozor, neplést počet a šířku registrů – o šířce jsme mluvili v sekci „64 bitů“. ARM64 tedy má jak dvakrát širší registry, tak jich má dvakrát více). 32bitový ARM má 16 celočíselných registrů: jeden programový čítač (PC – obsahuje číslo aktuální instrukce), stack ukazatel (ukazatel na probíhající funkci), link registr (ukazatel na návrat po skončení funkce), a zbylých 13 jsou k aplikačnímu použití. ARM64 má však 32 celočíselných registrů, z toho jeden nulový registr, link registr, ukazatel na rámec (podobný jako stack ukazatel) a jeden rezervovaný do budoucna. To nám nechává 28 registrů k aplikačnímu použití, více než dvojnásobek 32bitového ARMu. Zároveň ARM64 zdvojnásobil počet registrů pro čísla s plovoucí desetinnou čárkou (FPU) z 16 na 32 128bitových registrů.

V čem je však počet registrů tak důležitý? Paměť je obecně pomalejší než výpočty procesoru a čtení/zápis mohou trvat velmi dlouho. Tím by musel rychlý procesor stále čekat na paměť a narazili bychom na přirozenou hranici rychlosti systému. Procesory se tento handicap snaží skrýt vrstvami vyrovnávacích pamětí, avšak i ta nejrychlejší (L1) je stále pomalejší než výpočet procesoru. Registry jsou však paměťové buňky přímo v procesoru a jejich čtení/zápis jsou dostatečně rychlé na to, aby procesor nezpomalovaly. Počet registrů tedy prakticky znamená množství té nejrychlejší paměti pro výpočty procesoru, čímž značně ovlivňuje rychlost celého systému.

Tato rychlost zároveň potřebuje dobrou podporu optimalizace od kompilátoru, aby jazyk uměl tyto registry využít a nemusel vše ukládat do obecné aplikační (té pomalé) paměti.

Instrukční sada

ARM64 také přináší zásadní změny instrukční sady. Instrukční sada je množina atomických operací, které procesor umí vykonat (např. ‚ADD registr1 registr2‘ sečte čísla ve dvou registrech). Funkce dostupné jednotlivým jazykům jsou složené z těchto instrukcí. Složitější funkce musí vykonat více instrukcí, mohou být proto pomalejší.

Novinkami v ARM64 jsou instrukce pro AES šifrování, SHA-1 a SHA-256 hashovací funkce. Místo složité implementace tedy bude pouze jazyk volat tuto instrukci – což přinese obrovské zrychlení výpočtu takových funkcí a doufejme i přidanou bezpečnost v aplikacích. Např. nové Touch ID v šifrování také využívá tyto instrukce, čímž umožňuje opravdovou rychlost a bezpečnost (pro napadení by teoreticky musel útočník pozměnit samotný procesor, aby se k datům dostal – což je přinejmenším nepraktické vzhledem k jeho miniaturním rozměrům).

Kompatibilita s 32bit

Je důležité zmínit, že A7 umí plně běžet v 32bitovém režimu bez potřeby emulace. Znamená to, že nový iPhone 5s umí spustit aplikace kompilované na 32bitový ARM bez jakéhokoliv zpomalení. Avšak potom nemůže využít nových funkcí ARM64, tudíž se vždy vyplatí udělat speciální build právě pro A7, který by měl běžet mnohem rychleji.

Runtime změny

Runtime se nazývá kód přidávající programovacímu jazyku funkce, které je schopen využít během chodu aplikace, až po překladu. Jelikož Apple nepotřebuje zachovat kompatibilitu aplikací (že by 64bit binárka běžela na 32bit), mohli si dovolit učinit pár dalších vylepšení jazyka Objective-C.

Jednou z nich je tzv. tagged pointer (označený ukazatel). Běžně se objekty a ukazatele na tyto objekty ukládají v odlišných částech paměti. Avšak nové typy ukazatelů umožňují třídám s málo daty ukládat objekty přímo v ukazateli. Tento krok eliminuje potřebu alokovat paměť přímo pro objekt, stačí vytvořit ukazatel a objekt v něm. Tagged pointers jsou podporovány pouze v 64bitové architektuře také kvůli tomu, že v 32bitovém pointeru už není dost místa na uložení dostatku užitečných dat. Proto iOS, na rozdíl od OS X, prozatím tuto funkci nepodporovalo. S příchodem ARM64 se to však mění a iOS se i v tomto ohledu srovnalo s OS X.

Ačkoliv jsou ukazatele dlouhé 64 bitů, na ARM64 se využije pouze 33 bitů na vlastní adresu ukazatele. A pokud jsme schopni spolehlivě odmaskovat zbytek bitů ukazatele, můžeme toto místo využít na uložení dalších dat – jak v případě zmíněných tagged pointers. Koncepčně jde o jednu z největších změn v historii Objective-C, přestože to není marketingově využitelná funkce – většina uživatelů se tedy nedozví, jak kupředu Apple Objective-C táhne.

Co se týče užitečných dat, které se dají uložit do zbylého místa takového tagged pointeru, Objective-C ho například nově využívá pro uložení tzv. reference count (počtu referencí). Dříve se reference count ukládal v odlišném místě v paměti, v hashovací tabulce pro to připravenou, avšak to v případě velkého množství alloc/dealloc/retain/release volání mohlo celý systém zpomalovat. Tabulka se totiž musela kvůli vláknové bezpečnosti zamykat, tudíž dvěma objektům ve dvou vláknech nemohl být zároveň měněn reference count. Avšak nově se tato hodnota vloží do zbytku tzv. isa ukazatele. Jde o další nenápadnou, avšak do budoucna obrovskou výhodu a zrychlení. To by však v 32bitové architektuře nikdy nemohlo být dosaženo.

Do zbylého místa ukazatelů na objekty se také nově vkládají informace o asociovaných objektech, zda-li je objekt referencován slabě, zda-li je třeba vygenerovat pro objekt destruktor atd. Runtime Objective-C je díky těmto informacím schopen zásadně zrychlit běh, což se projeví v rychlosti každé aplikace. Z testování to znamená asi 40–50% zrychlení všech memory management volání. Jen přechodem na 64bitové ukazatele a využitím tohoto nového prostoru.

Závěr

Ačkoliv se budou konkurenti snažit rozšířit názor, že přechod na 64bitovou architekturu je zbytečný, vy už budete vědět, že jde jen o velmi neinformovaný názor. Je pravda, že samotný přechod na 64bit, aniž byste tomu přizpůsobili jazyk či aplikace, opravdu nic neznamená – ba dokonce celý systém zpomalí. Ale nový A7 využívá moderní ARM64 s novou instrukční sadou a Apple si dal práci zmodernizovat celý jazyk Objective-C a využít nové možnosti – z toho plyne slibované zrychlení.

Zde jsme zmínili velké množství důvodů, proč je 64bitová architektura správným krokem kupředu. Jde o další revoluci „pod kapotou“, díky které se Apple bude snažit nadále udržet na špici nejen designem, uživatelským rozhraním a bohatým ekosystémem, ale hlavně nejmodernějšími technologiemi na trhu.

Zdroj: mikeash.com
.