Advertentie sluiten

Mike As gewijd op zijn blog de praktische implicaties van het overschakelen naar 64-bits architectuur in de iPhone 5S. Dit artikel is gebaseerd op zijn bevindingen.

De reden voor deze tekst is vooral te wijten aan de grote hoeveelheid verkeerde informatie die wordt verspreid over wat de nieuwe iPhone 5s met een 64-bit ARM-processor eigenlijk betekent voor gebruikers en de markt. Hier zullen we proberen objectieve informatie te verstrekken over de prestaties, mogelijkheden en implicaties van deze transitie voor ontwikkelaars.

"64-bits"

Er zijn twee delen van een processor waarnaar het "X-bit"-label kan verwijzen: de breedte van de gehele registers en de breedte van de wijzers. Gelukkig zijn deze breedtes op de meeste moderne processors hetzelfde, dus in het geval van de A7 betekent dit 64-bit integer registers en 64-bit pointers.

Het is echter net zo belangrijk om erop te wijzen wat "64bit" NIET betekent: Grootte van fysiek RAM-adres. Het aantal bits dat met RAM moet communiceren (dus de hoeveelheid RAM die een apparaat kan ondersteunen) is niet gerelateerd aan het aantal CPU-bits. ARM-processors hebben adressen tussen 26 en 40 bits en kunnen onafhankelijk van de rest van het systeem worden gewijzigd.

  • Grootte van databus. De hoeveelheid gegevens die wordt ontvangen van RAM of buffergeheugen is eveneens onafhankelijk van deze factor. Individuele processorinstructies kunnen verschillende hoeveelheden gegevens vragen, maar deze worden ofwel in stukjes verzonden of meer dan nodig uit het geheugen ontvangen. Het hangt af van de grootte van het datakwantum. De iPhone 5 ontvangt gegevens uit het geheugen al in 64-bits quanta (en heeft een 32-bits processor), en we kunnen formaten tot 192 bits tegenkomen.
  • Alles wat met drijvende komma te maken heeft. De grootte van dergelijke registers (FPU) is wederom onafhankelijk van de interne werking van de processor. ARM gebruikt 64-bit FPU sinds vóór ARM64 (64-bit ARM-processor).

Algemene voor- en nadelen

Als we verder identieke 32bit- en 64bit-architecturen vergelijken, zijn ze over het algemeen niet zo verschillend. Dit is een van de redenen voor de algemene verwarring bij het publiek dat zoekt naar een reden waarom Apple ook op mobiele apparaten overgaat op 64-bits. Het komt echter allemaal voort uit de specifieke parameters van de A7 (ARM64)-processor en hoe Apple deze gebruikt, en niet alleen uit het feit dat de processor een 64-bits architectuur heeft.

Als we echter nog steeds naar de verschillen tussen deze twee architecturen kijken, zullen we verschillende verschillen ontdekken. Het voor de hand liggende is dat 64-bits gehele getallen registers efficiënter met 64-bits gehele getallen kunnen omgaan. Zelfs voorheen was het mogelijk om ermee te werken op 32-bits processors, maar dit betekende meestal dat ze in 32-bits lange stukken moesten worden verdeeld, wat langzamere berekeningen veroorzaakte. Een 64-bits processor kan dus over het algemeen net zo snel rekenen met 64-bits typen als met 32-bits typen. Dit betekent dat applicaties die doorgaans 64-bits typen gebruiken, veel sneller kunnen draaien op een 64-bits processor.

Hoewel 64-bits geen invloed heeft op de totale hoeveelheid RAM die de processor kan gebruiken, kan het het gemakkelijker maken om met grote hoeveelheden RAM in één programma te werken. Elk afzonderlijk programma dat op een 32-bits processor draait, heeft slechts ongeveer 4 GB adresruimte. Als we er rekening mee houden dat het besturingssysteem en de standaardbibliotheken iets in beslag nemen, blijft er ergens tussen de 1 en 3 GB over voor applicatiegebruik. Als een 32-bits systeem echter meer dan 4 GB RAM heeft, is het gebruik van dat geheugen iets ingewikkelder. We moeten ons toevlucht nemen tot het dwingen van het besturingssysteem om deze grotere stukken geheugen voor ons programma in kaart te brengen (geheugenvirtualisatie), of we kunnen het programma opsplitsen in meerdere processen (waarbij elk proces theoretisch weer 4 GB geheugen beschikbaar heeft voor directe adressering).

Deze "hacks" zijn echter zo moeilijk en traag dat een minimum aan applicaties er gebruik van maken. In de praktijk zal elk programma op een 32-bits processor slechts 1-3 GB geheugen gebruiken, en kan er meer beschikbaar RAM-geheugen worden gebruikt om meerdere programma's tegelijkertijd uit te voeren of dit geheugen als buffer te gebruiken (caching). Deze toepassingen zijn praktisch, maar we willen graag dat elk programma gemakkelijk stukjes geheugen groter dan 4 GB kan gebruiken.

Nu komen we bij de veel voorkomende (eigenlijk onjuiste) bewering dat zonder meer dan 4 GB geheugen een 64-bits architectuur nutteloos is. Een grotere adresruimte is zelfs handig op een systeem met minder geheugen. Memory-mapped bestanden zijn een handig hulpmiddel waarbij een deel van de inhoud van het bestand logisch wordt gekoppeld aan het geheugen van het proces zonder dat het hele bestand in het geheugen hoeft te worden geladen. Zo kan het systeem bijvoorbeeld stapsgewijs grote bestanden verwerken die vele malen groter zijn dan de RAM-capaciteit. Op een 32-bits systeem kunnen dergelijke grote bestanden niet betrouwbaar in het geheugen worden toegewezen, terwijl dit op een 64-bits systeem een ​​fluitje van een cent is, dankzij de veel grotere adresruimte.

Het grotere formaat van pointers brengt echter ook één groot nadeel met zich mee: anders hebben identieke programma's meer geheugen nodig op een 64-bits processor (deze grotere pointers moeten ergens opgeslagen worden). Omdat pointers vaak onderdeel zijn van programma's, kan dit verschil de cache belasten, wat er op zijn beurt voor zorgt dat het hele systeem langzamer werkt. Dus in perspectief kunnen we zien dat als we alleen de processorarchitectuur zouden veranderen naar 64-bit, dit het hele systeem feitelijk zou vertragen. Deze factor moet dus worden gecompenseerd door meer optimalisaties op andere plaatsen.

ARM64

De A7, de 64-bits processor die de nieuwe iPhone 5s aandrijft, is niet zomaar een gewone ARM-processor met bredere registers. ARM64 bevat belangrijke verbeteringen ten opzichte van de oudere, 32-bits versie.

Apple A7-processor.

register

ARM64 bevat twee keer zoveel gehele registers als 32-bits ARM (pas op dat u het aantal en de breedte van de registers niet verwart - we hadden het over de breedte in de sectie "64-bits". Dus ARM64 heeft zowel twee keer zo brede registers als twee keer zoveel registers). De 32-bits ARM heeft 16 gehele registers: één programmateller (PC - bevat het nummer van de huidige instructie), een stackpointer (een pointer naar een lopende functie), een linkregister (een pointer naar de return na het einde van de functie), en de overige 13 zijn voor applicatiegebruik. De ARM64 heeft echter 32 integer-registers, waaronder één nulregister, een linkregister, een framepointer (vergelijkbaar met een stackpointer) en één gereserveerd voor de toekomst. Dit laat ons 28 registers over voor applicatiegebruik, meer dan het dubbele van de 32-bits ARM. Tegelijkertijd verdubbelde de ARM64 het aantal drijvende-kommagetalregisters (FPU) van 16 naar 32 registers van 128 bits.

Maar waarom is het aantal registers zo belangrijk? Het geheugen is over het algemeen langzamer dan CPU-berekeningen en lezen/schrijven kan erg lang duren. Hierdoor zou de snelle processor moeten blijven wachten op geheugen en zouden we de natuurlijke snelheidslimiet van het systeem bereiken. Processors proberen deze handicap te verbergen met bufferlagen, maar zelfs de snelste (L1) is nog steeds langzamer dan de berekening van de processor. Registers zijn echter geheugencellen direct in de processor en het lezen/schrijven ervan is snel genoeg om de processor niet te vertragen. Het aantal registers betekent praktisch de hoeveelheid snelste geheugen voor de berekeningen van de processor, wat een grote invloed heeft op de snelheid van het hele systeem.

Tegelijkertijd heeft deze snelheid goede optimalisatieondersteuning nodig van de compiler, zodat de taal deze registers kan gebruiken en niet alles in het algemene applicatiegeheugen (het langzame) geheugen hoeft op te slaan.

Instructie set

ARM64 brengt ook grote veranderingen in de instructieset met zich mee. Een instructieset is een reeks atomaire bewerkingen die een processor kan uitvoeren (bijvoorbeeld 'ADD register1 register2' telt de getallen in twee registers op). De functies die beschikbaar zijn voor individuele talen zijn samengesteld uit deze instructies. Complexere functies moeten meer instructies uitvoeren, waardoor ze langzamer kunnen zijn.

Nieuw in ARM64 zijn instructies voor AES-encryptie, SHA-1 en SHA-256 hashfuncties. Dus in plaats van een complexe implementatie zal alleen de taal deze instructie aanroepen - wat een enorme versnelling zal opleveren in de berekening van dergelijke functies en hopelijk extra veiligheid in applicaties zal toevoegen. Bijvoorbeeld de nieuwe Touch ID gebruikt deze instructies ook bij het versleutelen, waardoor echte snelheid en veiligheid mogelijk zijn (in theorie zou een aanvaller de processor zelf moeten aanpassen om toegang te krijgen tot de gegevens - op zijn zachtst gezegd onpraktisch gezien de miniatuurgrootte).

Compatibiliteit met 32bit

Het is belangrijk om te vermelden dat de A7 volledig in 32-bits modus kan werken zonder de noodzaak van emulatie. Het betekent dat de nieuwe iPhone 5s zonder enige vertraging applicaties kan draaien die zijn gecompileerd op 32-bit ARM. Maar dan kan hij de nieuwe ARM64-functies niet gebruiken, dus het is altijd de moeite waard om speciaal voor de A7 een speciale build te maken, die veel sneller zou moeten werken.

Runtime-wijzigingen

Runtime is de code die functies toevoegt aan de programmeertaal, die deze kan gebruiken terwijl de applicatie draait, tot na de vertaling. Omdat Apple de compatibiliteit van applicaties niet hoeft te handhaven (dat een 64-bits binair bestand op 32-bits draait), zouden ze het zich kunnen veroorloven nog een paar verbeteringen aan te brengen in de Objective-C-taal.

Eén daarvan is de zgn getagde aanwijzer (gemarkeerde indicator). Normaal gesproken worden objecten en verwijzingen naar die objecten opgeslagen in afzonderlijke delen van het geheugen. Dankzij nieuwe pointertypen kunnen klassen met weinig gegevens echter objecten rechtstreeks in de pointer opslaan. Deze stap elimineert de noodzaak om direct geheugen aan het object toe te wijzen; maak gewoon een pointer en het object daarin. Gelabelde pointers worden alleen ondersteund in 64-bits architectuur, ook vanwege het feit dat er niet langer voldoende ruimte is in een 32-bits pointer om voldoende bruikbare gegevens op te slaan. Daarom ondersteunde iOS, in tegenstelling tot OS X, deze functie nog niet. Met de komst van ARM64 is dit echter aan het veranderen, en ook in dit opzicht heeft iOS OS X ingehaald.

Hoewel pointers 64 bits lang zijn, worden op de ARM64 slechts 33 bits gebruikt voor het eigen adres van de pointer. En als we de rest van de pointerbits op betrouwbare wijze kunnen ontmaskeren, kunnen we deze ruimte gebruiken om aanvullende gegevens op te slaan – zoals in het geval van de genoemde getagde pointers. Conceptueel gezien is dit een van de grootste veranderingen in de geschiedenis van Objective-C, hoewel het geen verkoopbare functie is - dus de meeste gebruikers zullen niet weten hoe Apple Objective-C vooruit helpt.

Wat betreft de nuttige gegevens die kunnen worden opgeslagen in de resterende ruimte van een dergelijke getagde aanwijzer: Objective-C gebruikt deze nu bijvoorbeeld om de zogenaamde referentie aantal (aantal referenties). Voorheen werd de referentietelling op een andere plek in het geheugen opgeslagen, in een daarvoor voorbereide hashtabel, maar bij een groot aantal alloc/dealloc/retain/release-aanroepen kon dit het hele systeem vertragen. De tabel moest vanwege de veiligheid van de threads worden vergrendeld, zodat de referentietelling van twee objecten in twee threads niet tegelijkertijd kon worden gewijzigd. Deze waarde wordt echter nieuw ingevoegd in de rest van de zogenaamde isa indicatoren. Dit is weer een onopvallend, maar enorm voordeel en versnelling in de toekomst. Dit zou echter nooit kunnen worden bereikt in een 32-bits architectuur.

Informatie over geassocieerde objecten, of er zwak naar het object wordt verwezen, of het nodig is om een ​​destructor voor het object te genereren, enz., wordt ook nieuw ingevoegd in de resterende plaats van verwijzingen naar de objecten. runtime kan de runtime fundamenteel versnellen, wat tot uiting komt in de snelheid van elke applicatie. Uit tests blijkt dat dit een versnelling van ongeveer 40-50% betekent van alle geheugenbeheeroproepen. Gewoon door over te schakelen naar 64-bit pointers en deze nieuwe ruimte te gebruiken.

Záver

Hoewel concurrenten zullen proberen het idee te verspreiden dat de overstap naar een 64-bits architectuur niet nodig is, weet je al dat dit slechts een zeer ongeïnformeerde mening is. Het is waar dat het overstappen naar 64-bit zonder je taal of applicaties aan te passen eigenlijk niets betekent; het vertraagt ​​zelfs het hele systeem. Maar de nieuwe A7 gebruikt een moderne ARM64 met een nieuwe instructieset, en Apple heeft de moeite genomen om de hele Objective-C-taal te moderniseren en te profiteren van de nieuwe mogelijkheden - vandaar de beloofde versnelling.

Hier hebben we een groot aantal redenen genoemd waarom een ​​64-bits architectuur de juiste stap voorwaarts is. Het is weer een revolutie "onder de motorkap", waardoor Apple zal proberen voorop te blijven lopen, niet alleen met design, gebruikersinterface en rijk ecosysteem, maar vooral met de modernste technologieën op de markt.

Bron: mikeash. com
.