Condividi tramite


Programmazione a 64 bit per sviluppatori di giochi

I produttori di processori sono esclusivamente processori a 64 bit nei loro computer desktop e anche i chipset della maggior parte dei computer portatili supportano la tecnologia x64. È importante che gli sviluppatori di giochi sfruttano i miglioramenti offerti dai processori a 64 bit con le nuove applicazioni e per garantire che le applicazioni precedenti vengano eseguite correttamente nei nuovi processori e nelle edizioni a 64 bit di Windows Vista e Windows 7. Questo articolo risolve problemi di compatibilità e conversione e consente agli sviluppatori di semplificare la transizione a piattaforme a 64 bit.

Microsoft ha attualmente i sistemi operativi a 64 bit seguenti:

  • Windows 10
  • Windows 11
  • Windows Server 2019 o versione successiva

Oltre i sistemi operativi a 64 bit:

  • Windows Server 2003 Service Pack 1
  • Windows XP Professional x64 Edition (disponibile per gli sviluppatori e per gli sviluppatori tramite MSDN)
  • Windows Vista
  • Windows 7
  • Windows 8.0
  • Windows 8.1
  • Windows Server 2008 - 2016

Nota

Windows Server 2008 R2 o versione successiva è disponibile solo come edizione a 64 bit. Windows 11 è disponibile solo come edizione a 64 bit o ARM64.

 

Differenze nella memoria indirizzabile

La prima cosa che gli sviluppatori notano è che i processori a 64 bit offrono un enorme salto nella quantità di memoria fisica e virtuale che può essere risolto.

  • Le applicazioni a 32 bit su piattaforme a 32 bit possono affrontare fino a 2 GB.

  • Le applicazioni a 32 bit compilate con il flag di collegamento /LARGEADDRESSAWARE:YES in Windows XP o Windows Server 2003 con l'opzione di avvio /3gb speciale può affrontare fino a 3 GB. In questo modo il kernel viene vincolato solo a 1 GB, che potrebbe causare l'esito negativo di alcuni driver e/o servizi.

  • Applicazioni a 32 bit compilate con il flag del linker /LARGEADDRESSAWARE:YES nelle edizioni a 32 bit di Windows Vista, Windows Server 2008 e Windows 7 possono indirizzare la memoria fino al numero specificato dall'elemento Di configurazione di avvio (BCD) IncreaseUserVa. IncreaseUserVa può avere un valore compreso tra 2048, il valore predefinito e 3072 (che corrisponde alla quantità di memoria configurata dall'opzione di avvio /3gb in Windows XP). Il resto di 4 GB viene allocato al kernel e può causare errori di configurazione del driver e del servizio.

    Per altre informazioni su BCD, vedere Dati di configurazione di avvio.

  • Le applicazioni a 32 bit su piattaforme a 64 bit possono affrontare fino a 2 GB o fino a 4 GB con il flag del linker /LARGEADDRESSAWARE:YES.

  • Le applicazioni a 64 bit usano 43 bit per l'indirizzamento, che fornisce 8 TB di indirizzo virtuale per le applicazioni e 8 TB riservate per il kernel.

Oltre alla memoria, le applicazioni a 64 bit che usano l'I/O con mapping della memoria sfruttano notevolmente lo spazio degli indirizzi virtuali. L'architettura a 64 bit ha inoltre migliorato le prestazioni a virgola mobile e il passaggio più veloce dei parametri. I processori a 6 bit hanno un doppio numero di registri, sia per utilizzo generico che per i tipi di estensioni SIMD di streaming (SSE), nonché il supporto per set di istruzioni SSE e SSE2; molti processori a 64 bit supportano anche set di istruzioni SSE3.

Specifica di un indirizzo di grandi dimensioni durante la compilazione

È consigliabile specificare un indirizzo di grandi dimensioni durante la compilazione di applicazioni a 32 bit usando il flag del linker /LARGEADDRESSAWARE, anche se l'applicazione non è destinata a una piattaforma a 64 bit, a causa dei vantaggi ottenuti senza costi. Come illustrato in precedenza, l'abilitazione di questo flag per una compilazione consente a un programma a 32 bit di accedere a più memoria con opzioni di avvio speciali in un sistema operativo a 32 bit o in un sistema operativo a 64 bit. Tuttavia, gli sviluppatori devono prestare attenzione che i presupposti del puntatore non vengono effettuati, ad esempio presupponendo che il bit elevato non sia mai impostato in un puntatore a 32 bit. In generale, l'abilitazione del flag /LARGEADDRESSAWARE è una buona procedura.

Le applicazioni a trenta bit che sono a conoscenza di indirizzi di grandi dimensioni possono determinare in fase di esecuzione la quantità totale di spazio indirizzi virtuale disponibile per loro con la configurazione del sistema operativo corrente chiamando GlobalMemoryStatusEx. Il risultato ullTotalVirtual varia da 2147352576 byte (2 GB) a byte 4294836224 (4 GB). I valori maggiori di 3221094400 (3 GB) possono essere ottenuti solo in edizioni a 64 bit di Windows. Ad esempio, se IncreaseUserVa ha un valore pari a 2560, il risultato è ullTotalVirtual con un valore di 2684223488 byte.

Compatibilità di applicazioni a 32 bit in piattaforme a 64 bit

I sistemi operativi Windows a 32 bit sono compatibili con l'architettura IA32 e la maggior parte delle API usate dalle applicazioni a 32 bit è disponibile tramite l'emulatore a 64 bit di Windows, WOW64. WOW64 consente di assicurarsi che queste API funzionino come previsto.

WOW64 ha un livello di esecuzione che gestisce il marshalling dei dati a 32 bit. WOW64 reindirizza le richieste di file DLL, reindirizza alcuni rami del Registro di sistema per applicazioni a 32 bit e riflette alcuni rami del Registro di sistema per applicazioni a 32 e 64 bit.

Altre informazioni su WOW64 sono disponibili nei dettagli dell'implementazione WOW64.

Potenziali problemi di compatibilità

La maggior parte delle applicazioni sviluppate per una piattaforma a 32 bit verrà eseguita senza problemi in una piattaforma a 64 bit. Alcune applicazioni potrebbero avere problemi, che potrebbero includere quanto segue:

  • Tutti i driver per edizioni a 64 bit dei sistemi operativi Windows devono essere versioni a 64 bit. La richiesta di nuovi driver a 64 bit ha implicazioni per gli schemi di protezione delle copie che si basano sui driver precedenti. Si noti che i driver in modalità kernel devono essere firmati authenticode per essere caricati da edizioni a 64 bit di Windows.
  • I processi a 64 bit non possono caricare DLL a 32 bit e i processi a 32 bit non possono caricare DLL a 64 bit. Gli sviluppatori devono assicurarsi che le versioni a 64 bit delle DLL di terze parti siano disponibili prima di procedere con lo sviluppo. Se è necessario usare una DLL a 32 bit in un processo a 64 bit, è possibile usare la comunicazione tra processi (IPC) di Windows. I componenti COM possono anche usare server out-of-process e marshalling per comunicare tra limiti, ma in tal modo può introdurre una penalità delle prestazioni.
  • Molti processori x64 sono anche processori multi-core e gli sviluppatori devono testare come ciò influisce sulle applicazioni legacy. Altre informazioni sui processori multi-core e sulle implicazioni per le applicazioni di gioco sono disponibili in Tempi di gioco e processori multicore.
  • Le applicazioni devono anche chiamare SHGetFolderPath per individuare i percorsi dei file, in quanto alcuni nomi di cartelle sono stati modificati in alcuni casi. Ad esempio, CSIDL_PROGRAM_FILES restituirà "C:\Programmi(x86)" per un'applicazione a 32 bit in esecuzione in una piattaforma a 64 bit anziché "C:\Programmi". Gli sviluppatori devono essere consapevoli del funzionamento delle funzionalità di reindirizzamento e reflection dell'emulatore WOW64.

Inoltre, gli sviluppatori devono essere belliche di programmi a 16 bit che potrebbero ancora essere usati. WOW64 non può gestire applicazioni a 16 bit; include i vecchi programmi di installazione e tutti i programmi MS-DOS.

Nota

I problemi di compatibilità più comuni sono i programmi di installazione che eseguono codice a 16 bit e non hanno driver a 64 bit per schemi di protezione della copia.

 

La sezione successiva illustra i problemi relativi alla conversione del codice a 64 bit nativo per gli sviluppatori che vogliono garantire che i programmi legacy funzionino su piattaforme a 64 bit. È anche per gli sviluppatori che non hanno familiarità con la programmazione a 64 bit.

Conversione di applicazioni a piattaforme a 64 bit

Avere gli strumenti e le librerie corretti consente di semplificare la transizione da 32 bit a sviluppo a 64 bit. DirectX 9 SDK include librerie per supportare progetti basati su x86 e x64. Microsoft Visual Studio 2005 e Visual Studio 2008 supportano la generazione di codice per x86 e x64 e sono ottimizzate per la generazione di codice x64. Tuttavia, sarà necessario anche per gli sviluppatori distribuire i runtime di Visual C con le applicazioni. Si noti che le edizioni Express di Visual Studio 2005 e Visual Studio 2008 non includono il compilatore x64, ma che le edizioni Standard, Professional e Team System fanno tutto.

Gli sviluppatori destinati alle piattaforme a 32 bit possono prepararsi per lo sviluppo a 64 bit per semplificare la transizione in un secondo momento. Quando si compilano progetti a 32 bit, gli sviluppatori devono usare il flag /Wp64, che causerà la generazione di avvisi relativi ai problemi che influiscono sulla portabilità. Il passaggio a strumenti e librerie a 64 bit genererà probabilmente un sacco di nuovi errori di compilazione inizialmente; è quindi consigliabile passare a strumenti e librerie bit neutrali e correggere eventuali avvisi prima di passare a una compilazione a 64 bit.

La modifica di strumenti, la modifica delle librerie e l'uso di determinati flag del compilatore non saranno sufficienti, anche se. I presupposti negli standard di codifica devono essere rivalutati per garantire che gli standard di codifica correnti non consentano problemi di portabilità. I problemi di portabilità possono includere troncamenti puntatori, dimensioni e allineamento dei tipi di dati, dipendenza da DLL a 32 bit, uso di API legacy, codice assembly e file binari precedenti.

Nota

Visual C++ 2010 o versioni successive include le intestazioni stdint.h e cstdint C99 che definiscono i tipi di portabilità standard int32_t, uint32_t, int64_t, uint64_t, intptr_t e uintptr_t. L'uso di questi tipi di dati insieme ai tipi di dati standard ptrdiff_t e size_t può essere preferibile ai tipi di portabilty windows usati di seguito per migliorare la portabilità del codice.

 

I principali problemi di conversione includono quanto segue:

Troncamento puntatore

I puntatori sono a 64 bit in un sistema operativo a 64 bit, quindi i puntatori a altri tipi di dati possono causare il troncamento e l'aritmetica puntatore può causare un danneggiamento. L'uso del flag /Wp64 in genere fornisce un avviso su questo tipo di problema, ma l'uso di tipi polimorfici (INT_PTR, DWORD_PTR, SIZE_T, UINT_PTR e così via) quando i tipi di puntatori di cast sono una buona pratica per evitare completamente questo problema. Poiché i puntatori sono a 64 bit nelle nuove piattaforme, gli sviluppatori devono controllare l'ordinamento dei puntatori e i tipi di dati nelle classi e nelle strutture, per ridurre o eliminare il riempimento.

Tipi di dati e file binari

Mentre i puntatori aumentano da 32 bit a 64 in una piattaforma a 64 bit, altri tipi di dati non sono. I tipi di dati a precisione fissa (DWORD32, DWORD64, INT32, INT64, LONG32, LONG64, UINT32, UINT64) possono essere usati in luoghi in cui è necessario conoscere le dimensioni del tipo di dati; ad esempio, in una struttura di file binari. Le modifiche apportate alle dimensioni del puntatore e all'allineamento dei dati richiedono una gestione speciale per garantire la compatibilità a 32 bit a 64 bit. Altre informazioni sono disponibili in Nuovi tipi di dati.

API Win32 precedenti e allineamento dei dati

Alcune API Win32 sono state deprecate e sostituite con chiamate API più neutrali, ad esempio SetWindowLongPtr al posto di SetWindowLongLong.

La penalità delle prestazioni per gli accessi non allineati è maggiore sulla piattaforma x64 rispetto a una piattaforma x86. Le macro TYPE_ALIGNMENT(t) e le macro FIELD_OFFSET(t, membro) possono essere usate per determinare le informazioni di allineamento che possono essere usate direttamente dal codice. L'uso corretto di queste macro sopra indicate deve eliminare potenziali sanzioni di accesso non allineate.

Altre informazioni sulla macro TYPE_ALIGNMENT, la macro FIELD_OFFSET e le informazioni generali sulla programmazione a 64 bit sono disponibili in Programmazione Windows a 64 bit: Suggerimenti per la migrazione: Considerazioni aggiuntive e regole per l'uso dei puntatori.

Codice assembly

Il codice assembly inline non è supportato in piattaforme a 64 bit e deve essere sostituito. Le modifiche apportate all'architettura potrebbero avere modificato colli di bottiglia dell'applicazione e C/C++ o intrinseci possono ottenere risultati simili con il codice più semplice da leggere. La pratica più consigliabile consiste nel passare tutto il codice assembly a C o C++. Gli intrinseci possono essere usati al posto del codice assembly, ma devono essere usati solo dopo l'esecuzione completa della profilatura e dell'analisi.

X87, MMX e 3DNow! i set di istruzioni sono deprecati in modalità a 64 bit. I set di istruzioni sono ancora presenti per la compatibilità con le versioni precedenti per la modalità a 32 bit; tuttavia, per evitare problemi di compatibilità in futuro, il loro uso nei progetti correnti e futuri è scoraggiato.

API deprecate

Alcune API DirectX precedenti sono state eliminate per applicazioni native a 64 bit: DirectPlay 4 e versioni precedenti, DirectDraw 6 e versioni precedenti, Direct3D 8 e versioni precedenti e DirectInput 7 e versioni precedenti. Inoltre, l'API principale di DirectMusic è disponibile per le applicazioni native a 64 bit, ma il livello di prestazioni e DirectMusic Producer sono deprecati.

Visual Studio genera avvisi di deprecazione e queste modifiche non sono un problema per gli sviluppatori che usano le API più recenti.

Profilatura e ottimizzazione delle applicazioni convertite

Tutti gli sviluppatori devono ri-profilare tutte le applicazioni che vengono convertite in nuove architetture. Molte applicazioni che vengono convertite in piattaforme a 64 bit avranno profili di prestazioni diversi dalle versioni a 32 bit. Gli sviluppatori devono eseguire test delle prestazioni a 64 bit prima di valutare cosa deve essere ottimizzato. La buona notizia di questo è che molte ottimizzazioni tradizionali funzionano su piattaforme a 64 bit. Inoltre, i compilatori a 64 bit possono anche eseguire molte ottimizzazioni con l'uso corretto dei flag del compilatore e degli hint di codifica.

Alcune strutture possono avere i tipi di dati interni riordinati per risparmiare spazio di memoria e migliorare la memorizzazione nella cache. Gli indici di matrice possono essere usati anziché un puntatore a 64 bit completo in alcuni casi. Il flag /fp:fast può migliorare l'ottimizzazione e la vettorializzazione a virgola mobile. L'uso di __restrict, declspec(restrict) e declspec(noalias) può aiutare il compilatore a risolvere l'aliasing e migliorare l'uso del file di registrazione.

Altre informazioni su /fp:fast sono disponibili in /fp (Specificare il comportamento di Floating-Point).

Altre informazioni sulle __restrict sono disponibili in Modificatori specifici di Microsoft.

Altre informazioni su declspec(restrict) sono disponibili in Procedure consigliate per l'ottimizzazione.

Altre informazioni su declspec( noalias) sono disponibili in __declspec(noalias).

Codice gestito in un sistema operativo a 64 bit

Il codice gestito viene usato da molti sviluppatori di giochi nella catena di strumenti, quindi è possibile comprendere il comportamento in un sistema operativo a 64 bit. Il codice gestito è neutrale, quindi quando si esegue un'applicazione gestita in un sistema operativo a 64 bit, Common Language Runtime (CLR) può eseguirlo come processo a 32 bit o a 64 bit. Per impostazione predefinita, CLR esegue applicazioni gestite a 64 bit e devono funzionare correttamente senza problemi. Tuttavia, se l'applicazione dipende da una DLL nativa a 32 bit, l'applicazione avrà esito negativo quando tenta di chiamare questa DLL. Un processo a 64 bit richiede codice completamente a 64 bit e non è possibile chiamare una DLL a 32 bit da un processo a 64 bit. La soluzione a lungo termine migliore consiste nel compilare il codice nativo anche come 64 bit, ma una soluzione a breve termine perfetta consiste nel contrassegnare semplicemente l'applicazione gestita come per x86 solo usando il flag di compilazione /platform:x86.

Implicazioni delle prestazioni dell'esecuzione di un sistema operativo a 64 bit

Poiché i processori con architettura AMD64 e Intel 64 possono eseguire istruzioni a 32 bit in modo nativo, possono eseguire applicazioni a 32 bit a velocità completa, anche in un sistema operativo a 64 bit. È previsto un costo modesto per la conversione dei parametri tra 32 bit e 64 bit quando si chiamano funzioni del sistema operativo, ma questo costo è generalmente trascurabile. Ciò significa che non dovrebbe essere visualizzato alcun rallentamento durante l'esecuzione di applicazioni a 32 bit in un sistema operativo a 64 bit.

Quando si compilano applicazioni a 64 bit, i calcoli sono più complessi. Un programma a 64 bit usa puntatori a 64 bit e le relative istruzioni sono leggermente maggiori, quindi il requisito di memoria è leggermente aumentato. Ciò può causare un lieve calo delle prestazioni. D'altra parte, avere due volte più registri e avere la possibilità di eseguire calcoli integer a 64 bit in un'unica istruzione spesso più di compensazione. Il risultato netto è che un'applicazione a 64 bit potrebbe essere eseguita leggermente più lenta rispetto alla stessa applicazione compilata a 32 bit, ma spesso verrà eseguita leggermente più velocemente.

Riepilogo

Le architetture a sessanta bit consentono agli sviluppatori di spingere le limitazioni sul modo in cui i giochi sembrano, suonano e giocano. La transizione dalla programmazione a 32 bit alla programmazione a 64 bit non è tuttavia semplice. Comprendendo le differenze tra i due e usando gli strumenti più recenti, la transizione a piattaforme a 64 bit può essere più semplice e veloce.

Altre informazioni sulla programmazione a 64 bit sono disponibili in Visual C++ Developer Center: programmazione a 64 bit.