Windows 11 su Arm: Prism può raddoppiare il numero di istruzioni eseguite

Il comportamento tenuto da Prism mostra cosa accade quando Windows 11 traduce software x86-64 per Arm: più istruzioni, overhead su AVX e memoria, ma le CPU Snapdragon più moderne riescono ad assorbire una parte significativa del costo.
Windows 11 su Arm: Prism può raddoppiare il numero di istruzioni eseguite

Dietro la compatibilità offerta da Windows 11 on Arm c’è un lavoro molto pesante: il codice compilato per l’architettura x86 deve essere analizzato, tradotto in Arm64, adattato alle diverse regole di accesso alla memoria e infine eseguito cercando di contenere il più possibile il costo della trasformazione. In diversi workload il chip Arm arriva a eseguire grossomodo il doppio delle istruzioni rispetto al programma x86-64 originale: ne parliamo più avanti.

Nel 2012 Surface RT tentò di portare Windows su processori Arm affidandosi a Windows RT e a un NVIDIA Tegra 3, ma la compatibilità con il vastissimo catalogo Win32 rimase uno dei problemi più evidenti della piattaforma. Windows 10 on Arm introdusse poi l’emulazione delle applicazioni x86 a 32 bit; Windows 11 estese il meccanismo al software x64.

Con Windows 11 24H2 Microsoft ha compiuto un altro passo importante introducendo Prism, il nuovo traduttore progettato per ridurre consumo di CPU e perdita di prestazioni. Nel 2026, chip come lo Snapdragon X2 Elite Extreme raggiungono frequenze fino a 5 GHz e integrano 18 core, mentre sempre più applicazioni dispongono ormai di versioni Arm64 native. Resta però una quantità enorme di software Windows compilato esclusivamente per x86-64: programmi aziendali, utility abbandonate dagli sviluppatori, plug-in, giochi e applicazioni che potrebbero non ricevere mai un port Arm. Prism deve quindi fare in modo che quel patrimonio software continui a funzionare. La compatibilità, tuttavia, ha un costo misurabile, e non sempre piccolo.

Come Prism traduce un programma x86-64 in codice Arm64

Microsoft descrive Prism come un sistema che compila just-in-time blocchi di istruzioni x86 o x64 trasformandoli in istruzioni Arm64. Il meccanismo individua sequenze di codice, genera la corrispondente versione Arm64 e conserva i blocchi tradotti per poterli riutilizzare.

La cache ha un ruolo fondamentale: il codice prodotto finisce nel percorso C:\Windows\XtaCache; Microsoft conferma più in generale che un servizio di sistema memorizza le traduzioni per evitare di rifare continuamente lo stesso lavoro. Il primo passaggio attraverso una determinata porzione di codice può richiedere l’intervento del traduttore, mentre le esecuzioni successive possono sfruttare quanto già preparato.

Una simile architettura impone però un compromesso. Prism non può permettersi di applicare a ogni blocco tutte le sofisticate ottimizzazioni tipiche di un compilatore ahead-of-time: tradurre troppo lentamente renderebbe evidente l’emulazione all’utente, aumentando tempi di apertura e utilizzo della CPU. Deve quindi produrre codice abbastanza buono in fretta.

La traduzione può quasi raddoppiare il numero di istruzioni

Il dato più immediato riguarda il numero di istruzioni eseguite. Con la versione x86-64 di Geekbench 7 tradotta da Prism, molti test producono circa due istruzioni Arm64 per ogni istruzione x86-64, talvolta anche di più.

Non significa che ciascun programma debba impiegare il doppio del tempo per svolgere le sue attività. Le moderne CPU out-of-order possono eseguire più istruzioni in parallelo, riordinare operazioni indipendenti e sfruttare unità di esecuzione che altrimenti resterebbero inutilizzate. Un core molto largo come quelli progettati da Qualcomm può quindi assorbire una parte dell’overhead. Ma non può eliminarlo.

Perché una singola istruzione x86 può diventare tre o quattro istruzioni Arm

Una delle difficoltà principali nasce dal fatto che x86-64 e Arm64 “ragionano” in modo diverso. x86-64 dispone di istruzioni molto ricche, capaci di svolgere più operazioni insieme; Arm64 preferisce istruzioni più semplici e regolari. Di conseguenza, ciò che x86-64 completa con una sola istruzione può richiederne diverse su Arm64.

Un esempio riguarda l’istruzione x86 vbroadcastss. In pratica può leggere dalla memoria un singolo valore numerico a 32 bit e copiarlo in tutte le posizioni di un registro AVX da 256 bit. Prism deve ottenere lo stesso risultato usando i registri NEON di Arm, larghi 128 bit: prima carica il valore, poi lo replica nella prima metà del vettore e infine prepara anche la seconda metà. Una sola istruzione x86 si trasforma quindi in più istruzioni Arm.

Qualcosa di simile accade con le istruzioni FMA, usate molto nei calcoli vettoriali. Un’istruzione x86 come vfmadd231ps può leggere dati dalla memoria, calcolare l’indirizzo necessario e svolgere una moltiplicazione seguita da una somma. Su Arm64 Prism deve spesso separare questi passaggi: calcola l’indirizzo, carica i dati e poi esegue le operazioni matematiche.

Tradurre codice tra due architetture così diverse comporta inevitabilmente un aumento del numero di istruzioni. L’inefficienza vera emerge quando, oltre alle istruzioni strettamente necessarie, il traduttore ne aggiunge altre per semplificare la gestione interna o per mantenere correttamente lo stato del programma.

Prism traduce velocemente, ma non sempre nel modo più efficiente

Prism, inoltre, può generare più operazioni di quelle strettamente necessarie: Microsoft deve tradurre il codice x86 rapidamente e senza alterarne il comportamento, quindi non può dedicare troppo tempo a ottimizzare ogni singola sequenza come farebbe un compilatore nativo.

Alcuni passaggi risultano così ridondanti, per esempio salvataggi temporanei di registri, caricamenti ripetuti o operazioni mantenute per prudenza.

A ciò si aggiunge il fatto che x86-64 e Arm64 gestiscono in modo diverso diversi aspetti interni della CPU, compreso l’ordine degli accessi alla memoria. Prism deve quindi inserire istruzioni aggiuntive per conservare esattamente il comportamento previsto dal programma originale. Il risultato è semplice: il software continua a funzionare, ma la CPU deve svolgere più lavoro rispetto a una versione compilata direttamente per Arm64.

Snapdragon X2 riesce a nascondere una parte dell’overhead

I test mostrano però che non tutte le CPU Arm soffrono allo stesso modo. Snapdragon X2 Elite riesce a contenere meglio la perdita di prestazioni rispetto ai core Neoverse N1 e N2 usati nel confronto, soprattutto grazie a una microarchitettura più potente, frequenze elevate e cache più capienti.

Quando Prism trasforma una singola istruzione x86 in più istruzioni Arm64, i core Qualcomm riescono spesso a eseguirne diverse in parallelo. Per questo in alcuni test cresce perfino l’IPC, cioè il numero di istruzioni completate per ciclo. Non significa però che il programma vada più veloce: se la versione nativa deve eseguire 100 istruzioni e quella tradotta ne richiede 200, un IPC più alto può soltanto ridurre la penalità, non eliminarla.

La perdita varia inoltre molto da applicazione ad applicazione. Un editor di testo o una utility leggera possono mostrare differenze quasi impercettibili; software che usa intensamente AVX, elaborazione video, immagini, codec o calcoli numerici può invece pagare molto di più, perché Prism deve scomporre operazioni x86 complesse in sequenze Arm più lunghe.

Le applicazioni x64 funzionano su Windows on Arm, certo. I problemi del passato sono ormai alle spalle: la compatibilità può essere quindi elevata, mentre le prestazioni dipendono fortemente dal tipo di codice eseguito.

Arm64EC aiuta la migrazione, ma i driver restano un limite

Microsoft ha previsto anche una via intermedia con Arm64EC, che permette a una stessa applicazione di combinare codice Arm nativo e componenti x64 ancora affidati all’emulazione.

Uno sviluppatore può quindi convertire per prime le parti più pesanti del programma e lasciare temporaneamente sotto Prism librerie o plug-in non ancora disponibili per Arm.

C’è però un limite importante: Prism lavora sulle applicazioni in modalità utente, non sui driver del kernel. Se un software dipende da un driver disponibile soltanto per x64, serve comunque una versione Arm64 specifica.

Rispetto ai tempi di Surface RT, Microsoft può oggi conservare buona parte della compatibilità con il software Windows storico senza chiedere agli utenti di rinunciarvi in partenza. Il costo esiste e si misura in istruzioni aggiuntive, maggiore lavoro per la CPU e prestazioni inferiori in alcuni carichi; i processori Snapdragon più recenti, però, sono abbastanza potenti da nascondere una parte consistente di questo svantaggio.

Ti consigliamo anche

Link copiato negli appunti