Chiudi l'annuncio

Mike Ash dedicato sul suo blog le implicazioni pratiche del passaggio all'architettura a 64 bit nell'iPhone 5S. Questo articolo si basa sulle sue scoperte.

Il motivo di questo testo è dovuto principalmente alla grande disinformazione diffusa su cosa significhi realmente il nuovo iPhone 5s con processore ARM a 64 bit per gli utenti e per il mercato. Qui cercheremo di fornire informazioni oggettive sulle prestazioni, sulle capacità e sulle implicazioni di questa transizione per gli sviluppatori.

"64bit"

Ci sono due parti di un processore a cui può fare riferimento l'etichetta "X-bit": la larghezza dei registri degli interi e la larghezza dei puntatori. Fortunatamente, sulla maggior parte dei processori moderni queste larghezze sono le stesse, quindi nel caso dell'A7 ciò significa registri interi a 64 bit e puntatori a 64 bit.

Tuttavia, è altrettanto importante sottolineare cosa NON significa "64bit": Dimensioni dell'indirizzo fisico della RAM. Il numero di bit per comunicare con la RAM (quindi la quantità di RAM che un dispositivo può supportare) non è correlato al numero di bit della CPU. I processori ARM hanno indirizzi compresi tra 26 e 40 bit e possono essere modificati indipendentemente dal resto del sistema.

  • Dimensioni del bus dati. Anche la quantità di dati ricevuti dalla RAM o dalla memoria buffer è indipendente da questo fattore. Le istruzioni del singolo processore possono richiedere quantità diverse di dati, ma vengono inviate in blocchi o ricevono più del necessario dalla memoria. Dipende dalla dimensione del quanto di dati. L'iPhone 5 riceve già i dati dalla memoria in quanti a 64 bit (e ha un processore a 32 bit) e possiamo incontrare dimensioni fino a 192 bit.
  • Tutto ciò che riguarda la virgola mobile. La dimensione di tali registri (FPU) è ancora una volta indipendente dal funzionamento interno del processore. ARM utilizza FPU a 64 bit da prima di ARM64 (processore ARM a 64 bit).

Vantaggi e svantaggi generali

Se confrontiamo architetture a 32 bit e 64 bit altrimenti identiche, generalmente non sono così diverse. Questo è uno dei motivi della confusione generale del pubblico alla ricerca del motivo per cui Apple sta passando alla tecnologia a 64 bit anche sui dispositivi mobili. Tutto dipende però dai parametri specifici del processore A7 (ARM64) e dal modo in cui Apple lo utilizza, non solo dal fatto che il processore ha un'architettura a 64 bit.

Tuttavia, se osserviamo ancora le differenze tra queste due architetture, troveremo diverse differenze. Quello ovvio è che i registri degli interi a 64 bit possono gestire gli interi a 64 bit in modo più efficiente. Anche prima era possibile lavorarli su processori a 32 bit, ma questo di solito significava dividerli in pezzi lunghi 32 bit, il che causava calcoli più lenti. Quindi un processore a 64 bit può generalmente elaborare con tipi a 64 bit altrettanto velocemente che con quelli a 32 bit. Ciò significa che le applicazioni che generalmente utilizzano tipi a 64 bit possono essere eseguite molto più velocemente su un processore a 64 bit.

Sebbene 64 bit non influenzi la quantità totale di RAM che il processore può utilizzare, può rendere più semplice lavorare con grandi quantità di RAM in un programma. Ogni singolo programma in esecuzione su un processore a 32 bit ha solo circa 4 GB di spazio di indirizzi. Considerando che il sistema operativo e le librerie standard occupano qualcosa, al programma rimangono tra 1 e 3 GB per l'utilizzo dell'applicazione. Tuttavia, se un sistema a 32 bit ha più di 4 GB di RAM, l'utilizzo di tale memoria è un po' più complicato. Dobbiamo ricorrere a forzare il sistema operativo a mappare questi blocchi di memoria più grandi per il nostro programma (virtualizzazione della memoria), oppure possiamo dividere il programma in più processi (dove ogni processo ha ancora teoricamente 4 GB di memoria disponibile per l'indirizzamento diretto).

Tuttavia, questi "hack" sono così difficili e lenti che un minimo di applicazioni li utilizza. In pratica, su un processore a 32 bit, ogni programma utilizzerà solo i suoi 1-3 GB di memoria, e la RAM più disponibile potrà essere utilizzata per eseguire più programmi contemporaneamente o utilizzare questa memoria come buffer (caching). Questi usi sono pratici, ma vorremmo che qualsiasi programma fosse in grado di utilizzare facilmente blocchi di memoria più grandi di 4 GB.

Veniamo ora alla frequente (in realtà errata) affermazione secondo cui senza più di 4 GB di memoria, un'architettura a 64 bit è inutile. Uno spazio di indirizzi più ampio è utile anche su un sistema con meno memoria. I file mappati in memoria sono uno strumento utile in cui parte del contenuto del file è logicamente collegato alla memoria del processo senza che l'intero file debba essere caricato in memoria. Pertanto, il sistema può, ad esempio, elaborare gradualmente file di grandi dimensioni molte volte più grandi della capacità della RAM. Su un sistema a 32 bit, file così grandi non possono essere mappati in memoria in modo affidabile, mentre su un sistema a 64 bit è un gioco da ragazzi, grazie allo spazio degli indirizzi molto più grande.

Tuttavia, la dimensione maggiore dei puntatori comporta anche un grosso svantaggio: altrimenti programmi identici necessitano di più memoria su un processore a 64 bit (questi puntatori più grandi devono essere memorizzati da qualche parte). Poiché i puntatori sono una parte frequente dei programmi, questa differenza può gravare sulla cache, il che a sua volta rallenta l'esecuzione dell'intero sistema. Quindi, in prospettiva, possiamo vedere che se cambiassimo semplicemente l'architettura del processore a 64 bit, rallenterebbe effettivamente l'intero sistema. Quindi questo fattore deve essere bilanciato da ulteriori ottimizzazioni in altri luoghi.

ARM64

L'A7, il processore a 64 bit che alimenta il nuovo iPhone 5s, non è solo un normale processore ARM con registri più ampi. ARM64 contiene importanti miglioramenti rispetto alla versione precedente a 32 bit.

Processore Apple A7.

registro

ARM64 contiene il doppio dei registri interi rispetto a ARM a 32 bit (fai attenzione a non confondere il numero e la larghezza dei registri: abbiamo parlato della larghezza nella sezione "64 bit". Quindi ARM64 ha sia registri larghi che il doppio registri). L'ARM a 32 bit ha 16 registri interi: un contatore di programma (PC - contiene il numero dell'istruzione corrente), un puntatore allo stack (un puntatore a una funzione in corso), un registro di collegamento (un puntatore al ritorno dopo che la funzione è stata completata). finito) e i restanti 13 sono per uso applicativo. Tuttavia, l'ARM64 ha 32 registri interi, incluso un registro zero, un registro di collegamento, un puntatore al frame (simile a uno stack pointer) e uno riservato per il futuro. Questo ci lascia con 28 registri per l'uso dell'applicazione, più del doppio dell'ARM a 32 bit. Allo stesso tempo, l'ARM64 ha raddoppiato il numero di registri dei numeri in virgola mobile (FPU) da 16 a 32 registri a 128 bit.

Ma perché il numero dei registri è così importante? La memoria è generalmente più lenta dei calcoli della CPU e la lettura/scrittura può richiedere molto tempo. Ciò costringerebbe il processore veloce a continuare ad attendere la memoria e raggiungeremmo il limite di velocità naturale del sistema. I processori cercano di nascondere questo handicap con strati di buffer, ma anche quello più veloce (L1) è comunque più lento dei calcoli del processore. Tuttavia, i registri sono celle di memoria direttamente nel processore e la loro lettura/scrittura è sufficientemente veloce da non rallentare il processore. Il numero di registri indica praticamente la quantità di memoria più veloce per i calcoli del processore, che influisce notevolmente sulla velocità dell'intero sistema.

Allo stesso tempo, questa velocità necessita di un buon supporto di ottimizzazione da parte del compilatore, in modo che il linguaggio possa utilizzare questi registri e non debba memorizzare tutto nella memoria generale dell'applicazione (quella lenta).

Set di istruzioni

ARM64 apporta anche importanti modifiche al set di istruzioni. Un set di istruzioni è un insieme di operazioni atomiche che un processore può eseguire (ad esempio 'ADD registro1 registro2' aggiunge i numeri in due registri). Da queste istruzioni sono composte le funzioni disponibili per le singole lingue. Le funzioni più complesse devono eseguire più istruzioni, quindi possono essere più lente.

Una novità di ARM64 sono le istruzioni per la crittografia AES e le funzioni hash SHA-1 e SHA-256. Quindi, invece di un'implementazione complessa, solo il linguaggio chiamerà questa istruzione, il che porterà un'enorme accelerazione al calcolo di tali funzioni e, si spera, una maggiore sicurezza nelle applicazioni. Per esempio. anche il nuovo Touch ID utilizza queste istruzioni nella crittografia, consentendo una reale velocità e sicurezza (in teoria, un utente malintenzionato dovrebbe modificare il processore stesso per accedere ai dati, il che è a dir poco poco pratico date le sue dimensioni miniaturizzate).

Compatibilità con 32 bit

È importante ricordare che l'A7 può funzionare completamente in modalità 32 bit senza la necessità di emulazione. Ciò significa che i nuovi iPhone 5s possono eseguire applicazioni compilate su ARM a 32 bit senza alcun rallentamento. Tuttavia, in questo caso non è possibile utilizzare le nuove funzioni ARM64, quindi vale sempre la pena realizzare una build speciale solo per l'A7, che dovrebbe funzionare molto più velocemente.

Modifiche all'esecuzione

Il runtime è il codice che aggiunge funzioni al linguaggio di programmazione, che è in grado di utilizzare mentre l'applicazione è in esecuzione, fino a dopo la traduzione. Poiché Apple non ha bisogno di mantenere la compatibilità delle applicazioni (che un binario a 64 bit funziona su 32 bit), potrebbe permettersi di apportare qualche ulteriore miglioramento al linguaggio Objective-C.

Uno di questi è il cosiddetto puntatore contrassegnato (puntatore contrassegnato). Normalmente, gli oggetti e i puntatori a tali oggetti vengono archiviati in parti separate della memoria. Tuttavia, i nuovi tipi di puntatore consentono alle classi con pochi dati di memorizzare oggetti direttamente nel puntatore. Questo passaggio elimina la necessità di allocare memoria direttamente per l'oggetto, basta creare un puntatore e l'oggetto al suo interno. I puntatori con tag sono supportati solo nell'architettura a 64 bit anche perché in un puntatore a 32 bit non c'è più spazio sufficiente per memorizzare dati utili sufficienti. Pertanto, iOS, a differenza di OS X, non supportava ancora questa funzionalità. Tuttavia, con l'arrivo di ARM64, la situazione sta cambiando e anche iOS ha raggiunto OS X in questo senso.

Sebbene i puntatori siano lunghi 64 bit, sull'ARM64 vengono utilizzati solo 33 bit per l'indirizzo proprio del puntatore. E se siamo in grado di smascherare in modo affidabile il resto dei bit del puntatore, possiamo utilizzare questo spazio per memorizzare dati aggiuntivi, come nel caso dei puntatori con tag menzionati. Concettualmente, questo è uno dei più grandi cambiamenti nella storia di Objective-C, sebbene non sia una funzionalità commerciabile, quindi la maggior parte degli utenti non saprà come Apple sta facendo avanzare Objective-C.

Per quanto riguarda i dati utili che possono essere memorizzati nello spazio rimanente di un puntatore con tag, Objective-C, ad esempio, li utilizza ora per memorizzare i cosiddetti numero di riferimento (numero di referenze). In precedenza, il conteggio dei riferimenti veniva archiviato in un posto diverso della memoria, in una tabella hash predisposta per esso, ma ciò poteva rallentare l'intero sistema nel caso di un numero elevato di chiamate alloc/dealloc/retain/release. La tabella doveva essere bloccata per motivi di sicurezza del thread, quindi il conteggio dei riferimenti di due oggetti in due thread non poteva essere modificato contemporaneamente. Tuttavia, questo valore viene nuovamente inserito nel resto del cosiddetto isa indicatori. Questo è un altro vantaggio e accelerazione poco appariscente, ma enorme in futuro. Tuttavia, ciò non potrebbe mai essere raggiunto in un'architettura a 32 bit.

Nel posto rimanente dei puntatori agli oggetti vengono nuovamente inserite anche le informazioni sugli oggetti associati, se l'oggetto ha riferimenti deboli, se è necessario generare un distruttore per l'oggetto, ecc.. Grazie a queste informazioni, Objective-C runtime è in grado di accelerare sostanzialmente il runtime, il che si riflette nella velocità di ciascuna applicazione. Dai test, ciò significa un aumento di velocità di circa il 40-50% di tutte le chiamate di gestione della memoria. Semplicemente passando ai puntatori a 64 bit e utilizzando questo nuovo spazio.

Conclusione

Anche se i concorrenti cercheranno di diffondere l'idea che il passaggio ad un'architettura a 64 bit non sia necessario, saprai già che si tratta solo di un'opinione molto disinformata. È vero che passare a 64 bit senza adattare la lingua o le applicazioni non significa nulla, anzi rallenta l'intero sistema. Ma il nuovo A7 utilizza un moderno ARM64 con un nuovo set di istruzioni e Apple si è presa la briga di modernizzare l'intero linguaggio Objective-C e sfruttare le nuove funzionalità, da qui l'accelerazione promessa.

Qui abbiamo menzionato un gran numero di ragioni per cui un'architettura a 64 bit è il giusto passo avanti. Si tratta di un'altra rivoluzione “sotto il cofano”, grazie alla quale Apple cercherà di rimanere all'avanguardia non solo con design, interfaccia utente e ricco ecosistema, ma soprattutto con le più moderne tecnologie presenti sul mercato.

Fonte: mikeash.com
.