Compartir a través de


Programación de 64 bits para desarrolladores de juegos

Los fabricantes de procesadores envían exclusivamente procesadores de 64 bits en sus equipos de escritorio, e incluso los conjuntos de chips de la mayoría de los equipos portátiles admiten la tecnología x64. Es importante que los desarrolladores de juegos aprovechen las mejoras que ofrecen los procesadores de 64 bits con sus nuevas aplicaciones y asegurarse de que sus aplicaciones anteriores se ejecutan correctamente en los nuevos procesadores y las ediciones de 64 bits de Windows Vista y Windows 7. En este artículo se abordan los problemas de compatibilidad y portabilidad, y ayuda a los desarrolladores a facilitar su transición a plataformas de 64 bits.

Microsoft tiene actualmente los siguientes sistemas operativos de 64 bits:

  • Windows 10
  • Windows 11
  • Windows Server 2019 o posterior

Sistemas operativos de 64 bits anteriores:

  • Windows Server 2003 Service Pack 1
  • Windows XP Professional x64 Edition (disponible para los OEM y para desarrolladores a través de MSDN)
  • Windows Vista
  • Windows 7
  • Windows 8.0
  • Windows 8.1
  • Windows Server 2008 - 2016

Nota

Windows Server 2008 R2 o posterior solo está disponible como edición de 64 bits. Windows 11 solo está disponible como edición de 64 bits o ARM64.

 

Diferencias en la memoria direccionable

Lo primero que observa la mayoría de los desarrolladores es que los procesadores de 64 bits proporcionan un gran salto en la cantidad de memoria física y virtual que se puede abordar.

  • Las aplicaciones de 32 bits en plataformas de 32 bits pueden abordar hasta 2 GB.

  • Las aplicaciones de 32 bits creadas con la marca del enlazador /LARGEADDRESSAWARE:YES en Windows XP o Windows Server 2003 de 32 bits con la opción de arranque especial /3gb pueden abordar hasta 3 GB. Esto restringe el kernel a solo 1 GB, lo que puede provocar un error en algunos controladores o servicios.

  • Las aplicaciones de 32 bits compiladas con la marca del enlazador /LARGEADDRESSAWARE:YES en las ediciones de 32 bits de Windows Vista, Windows Server 2008 y Windows 7 pueden dirigir la memoria hasta el número especificado por el elemento de datos de configuración de arranque (BCD) IncreaseUserVa. IncreaseUserVa puede tener un valor comprendido entre 2048 y 3072 (que coincide con la cantidad de memoria configurada por la opción de arranque /3gb en Windows XP). El resto de 4 GB se asigna al kernel y puede dar lugar a errores en las configuraciones de controlador y servicio.

    Para obtener más información sobre BCD, consulte Datos de configuración de arranque.

  • Las aplicaciones de 32 bits en plataformas de 64 bits pueden abordar hasta 2 GB o hasta 4 GB con la marca del enlazador /LARGEADDRESSAWARE:YES.

  • Las aplicaciones de 64 bits usan 43 bits para el direccionamiento, que proporciona 8 TB de dirección virtual para aplicaciones y 8 TB reservadas para el kernel.

Además de simplemente memoria, las aplicaciones de 64 bits que usan E/S de archivos asignados a memoria se benefician en gran medida del mayor espacio de direcciones virtuales. La arquitectura de 64 bits también ha mejorado el rendimiento de punto flotante y el paso más rápido de parámetros. Los procesadores de sesenta y cuatro bits tienen el doble del número de registros, tanto de tipos de extensiones SIMD de uso general como de streaming (SSE), así como compatibilidad con conjuntos de instrucciones SSE y SSE2; muchos procesadores de 64 bits incluso admiten conjuntos de instrucciones SSE3.

Especificación de reconocimiento de direcciones grandes al compilar

Es recomendable especificar el reconocimiento de direcciones grandes al compilar aplicaciones de 32 bits mediante el uso de la marca del enlazador /LARGEADDRESSAWARE, incluso si la aplicación no está pensada para una plataforma de 64 bits, debido a las ventajas que se obtienen sin costo alguno. Como se explicó anteriormente, habilitar esta marca para una compilación permite que un programa de 32 bits tenga acceso a más memoria con opciones de arranque especiales en un sistema operativo de 32 bits o en un sistema operativo de 64 bits. Sin embargo, los desarrolladores deben tener cuidado de que no se realicen suposiciones de puntero, por ejemplo, suponiendo que el bit alto nunca se establece en un puntero de 32 bits. En general, habilitar la marca /LARGEADDRESSAWARE es un procedimiento recomendado.

Las aplicaciones de treinta y dos bits que son compatibles con direcciones grandes pueden determinar en tiempo de ejecución cuánto espacio total de direcciones virtuales está disponible para ellas con la configuración actual del sistema operativo mediante una llamada a GlobalMemoryStatusEx. El resultado de ullTotalVirtual oscilará entre 2147352576 bytes (2 GB) y 4294836224 bytes (4 GB). Los valores mayores que 3221094400 (3 GB) solo se pueden obtener en ediciones de 64 bits de Windows. Por ejemplo, si IncreaseUserVa tiene un valor de 2560, el resultado es ullTotalVirtual con un valor de 2684223488 bytes.

Compatibilidad de aplicaciones de 32 bits en plataformas de 64 bits

Los sistemas operativos Windows de sesenta y cuatro bits son binarios compatibles con la arquitectura IA32 y la mayoría de las API que usan las aplicaciones de 32 bits están disponibles a través del Emulador de Windows de 64 bits, WOW64. WOW64 ayuda a garantizar que estas API funcionarán según lo previsto.

WOW64 tiene una capa de ejecución que controla la serialización de datos de 32 bits. WOW64 redirige las solicitudes de archivo DLL, redirige algunas ramas del Registro para aplicaciones de 32 bits y refleja algunas ramas del Registro para aplicaciones de 32 y 64 bits.

Puede encontrar más información sobre WOW64 en WOW64 Implementation Details(Detalles de implementación de WOW64).

Posibles problemas de compatibilidad

La mayoría de las aplicaciones desarrolladas para una plataforma de 32 bits se ejecutarán sin problemas en una plataforma de 64 bits. Algunas aplicaciones podrían tener problemas, lo que podría incluir lo siguiente:

  • Todos los controladores de las ediciones de 64 bits de los sistemas operativos Windows deben ser versiones de 64 bits. Requerir nuevos controladores de 64 bits tiene implicaciones para los esquemas de protección de copia que dependen de controladores antiguos. Tenga en cuenta que los controladores en modo kernel deben estar firmados por Authenticode para cargarse en ediciones de 64 bits de Windows.
  • Los procesos de 64 bits no pueden cargar archivos DLL de 32 bits y los procesos de 32 bits no pueden cargar archivos DLL de 64 bits. Los desarrolladores deben asegurarse de que las versiones de 64 bits de archivos DLL de terceros estén disponibles antes de continuar con el desarrollo. Si debe usar un archivo DLL de 32 bits en un proceso de 64 bits, se puede usar la comunicación entre procesos (IPC) de Windows. Los componentes COM también pueden usar servidores fuera de proceso y serializar para comunicarse entre límites, pero hacerlo puede suponer una penalización de rendimiento.
  • Muchos procesadores x64 también son procesadores de varios núcleos, y los desarrolladores deben probar cómo afecta esto a sus aplicaciones heredadas. Puede encontrar más información sobre los procesadores de varios núcleos y las implicaciones para las aplicaciones de juegos en Game Timing y Procesadores multicore.
  • Las aplicaciones también deben llamar a SHGetFolderPath para detectar rutas de acceso de archivo, ya que algunos nombres de carpeta han cambiado en determinados casos. Por ejemplo, CSIDL_PROGRAM_FILES devolvería "C:\Archivos de programa(x86)" para una aplicación de 32 bits que se ejecuta en una plataforma de 64 bits en lugar de "C:\Archivos de programa". Los desarrolladores deben tener en cuenta cómo funcionan las funcionalidades de redirección y reflexión del emulador WOW64.

Además, los desarrolladores deben tener cuidado con los programas de 16 bits que podrían seguir usando. WOW64 no puede controlar aplicaciones de 16 bits; Esto incluye instaladores antiguos y todos los programas MS-DOS.

Nota

Los problemas de compatibilidad más comunes son los instaladores que ejecutan código de 16 bits y no tienen controladores de 64 bits para esquemas de protección de copia.

 

En la sección siguiente se describen los problemas relacionados con la portabilidad de código a 64 bits nativos para desarrolladores que quieran asegurarse de que sus programas heredados funcionan en plataformas de 64 bits. También es para desarrolladores que no están familiarizados con la programación de 64 bits.

Migración de aplicaciones a plataformas de 64 bits

Tener las herramientas y bibliotecas adecuadas ayudarán a facilitar la transición del desarrollo de 32 bits a 64 bits. El SDK de DirectX 9 tiene bibliotecas para admitir proyectos basados en x86 y x64. Microsoft Visual Studio 2005 y Visual Studio 2008 admiten la generación de código para x86 y x64, y incluyen bibliotecas optimizadas para generar código x64. Sin embargo, también será necesario que los desarrolladores distribuyan los entornos de ejecución de Visual C con sus aplicaciones. Tenga en cuenta que las ediciones Express de Visual Studio 2005 y Visual Studio 2008 no incluyen el compilador x64, pero que todas las ediciones Standard, Professional y Team System lo hacen.

Los desarrolladores que tienen como destino plataformas de 32 bits pueden prepararse para el desarrollo de 64 bits para facilitar su transición más adelante. Al compilar proyectos de 32 bits, los desarrolladores deben usar la marca /Wp64, lo que provocará la generación de advertencias sobre problemas que afectan a la portabilidad. Cambiar a las herramientas y bibliotecas de 64 bits probablemente generará muchos errores de compilación nuevos inicialmente; por lo tanto, es aconsejable cambiar las herramientas y bibliotecas neutras de bits y corregir las advertencias antes de cambiar a una compilación de 64 bits.

Sin embargo, el cambio de herramientas, el cambio de bibliotecas y el uso de determinadas marcas del compilador no serán suficientes. Las suposiciones en los estándares de codificación se deben volver a evaluar para asegurarse de que los estándares de codificación actuales no permiten problemas de portabilidad. Los problemas de portabilidad pueden incluir truncamiento de punteros, tamaño y alineación de tipos de datos, dependencia de archivos DLL de 32 bits, uso de API heredadas, código de ensamblado y archivos binarios antiguos.

Nota

Visual C++ 2010 o posterior incluye los encabezados stdint.h y cstdint C99 que definen los tipos de portabilidad estándar int32_t, uint32_t, int64_t, uint64_t, intptr_t y uintptr_t. El uso de estos junto con los tipos de datos estándar ptrdiff_t y size_t puede ser preferible a los tipos de portabilidad de Windows que se usan a continuación para mejorar la portabilidad del código.

 

Entre los principales problemas de portabilidad se incluyen los siguientes:

Truncamiento del puntero

Los punteros son de 64 bits en un sistema operativo de 64 bits, por lo que la conversión de punteros a otros tipos de datos puede provocar truncamiento y la aritmética de puntero puede provocar daños. El uso de la marca /Wp64 normalmente proporcionará una advertencia sobre este tipo de problema, pero el uso de tipos polimórficos (INT_PTR, DWORD_PTR, SIZE_T, UINT_PTR, etc.) cuando los tipos de puntero de conversión son una buena práctica para ayudar a evitar este problema por completo. Dado que los punteros son de 64 bits en nuevas plataformas, los desarrolladores deben comprobar el orden de los punteros y los tipos de datos en clases y estructuras, para reducir o eliminar el relleno.

Tipos de datos y archivos binarios

Aunque los punteros aumentan de 32 bits a 64 en una plataforma de 64 bits, otros tipos de datos no. Los tipos de datos de precisión fija (DWORD32, DWORD64, INT32, INT64, LONG32, LONG64, UINT32, UINT64) se pueden usar en lugares donde se debe conocer el tamaño del tipo de datos; por ejemplo, en una estructura de archivos binarios. Los cambios en el tamaño del puntero y la alineación de los datos requieren un control especial para garantizar la compatibilidad de 32 bits a 64 bits. Puede encontrar más información en Nuevos tipos de datos.

Alineación de datos y API de Win32 anteriores

Algunas API de Win32 han quedado en desuso y se han reemplazado por llamadas API más neutrales, como SetWindowLongPtr en lugar de SetWindowLong.

La penalización de rendimiento de los accesos no alineados es mayor en la plataforma x64 que en una plataforma x86. Las macros TYPE_ALIGNMENT(t) y FIELD_OFFSET(t, miembro) se pueden usar para determinar la información de alineación que el código puede usar directamente. El uso correcto de estas macros mencionadas anteriormente debe eliminar posibles penalizaciones de acceso no alineadas.

Puede encontrar más información sobre la macro TYPE_ALIGNMENT, la macro de FIELD_OFFSET y la información general de programación de 64 bits en Programación de Windows de 64 bits: Sugerencias de migración: Consideraciones adicionales y reglas para usar punteros.

Código de ensamblado

El código de ensamblado insertado no se admite en plataformas de 64 bits y debe reemplazarse. Los cambios en la arquitectura pueden haber cambiado los cuellos de botella de la aplicación y C/C++ o intrínsecos pueden lograr resultados similares con el código que es más fácil de leer. La práctica más recomendable es cambiar todo el código de ensamblado a C o C++. Los intrínsecos se pueden usar en lugar del código de ensamblado, pero solo se deben usar después de realizar la generación de perfiles y el análisis completos.

¡Los x87, MMX y 3DNow! Los conjuntos de instrucciones están en desuso en modos de 64 bits. Los conjuntos de instrucciones siguen estando presentes para la compatibilidad con versiones anteriores para el modo de 32 bits; sin embargo, para evitar problemas de compatibilidad en el futuro, no se recomienda su uso en proyectos actuales y futuros.

API en desuso

Algunas API anteriores de DirectX se han quitado para aplicaciones nativas de 64 bits: DirectPlay 4 y versiones anteriores, DirectDraw 6 y versiones anteriores, Direct3D 8 y versiones anteriores, y DirectInput 7 y versiones anteriores. Además, la API principal de DirectMusic está disponible para aplicaciones nativas de 64 bits, pero la capa de rendimiento y directMusic Producer están en desuso.

Visual Studio emite advertencias de desuso y estos cambios no son un problema para los desarrolladores que usan las API más recientes.

Generación de perfiles y optimización de aplicaciones porteadas

Todos los desarrolladores deben volver a generar perfiles de las aplicaciones que se van a migrar a nuevas arquitecturas. Muchas aplicaciones que se van a migrar a plataformas de 64 bits tendrán perfiles de rendimiento diferentes de sus versiones de 32 bits. Los desarrolladores deben ejecutar pruebas de rendimiento de 64 bits antes de evaluar lo que debe optimizarse. La buena noticia de esto es que muchas optimizaciones tradicionales funcionan en plataformas de 64 bits. Además, los compiladores de 64 bits también pueden realizar muchas optimizaciones con el uso correcto de marcas del compilador y sugerencias de codificación.

Algunas estructuras pueden tener sus tipos de datos internos reordenados para ahorrar espacio de memoria y mejorar el almacenamiento en caché. Los índices de matriz se pueden usar en lugar de un puntero de 64 bits completo en algunos casos. La marca /fp:fast puede mejorar la optimización de punto flotante y la vectorización. El uso de __restrict, declspec(restrict) y declspec(noalias) puede ayudar al compilador a resolver el alias y mejorar el uso del archivo de registro.

Puede encontrar más información sobre /fp:fast en /fp (Especificar Floating-Point Comportamiento).

Puede encontrar más información sobre __restrict en Modificadores específicos de Microsoft.

Puede encontrar más información sobre declspec(restrict) en Procedimientos recomendados de optimización.

Puede encontrar más información sobre declspec(noalias) en __declspec(noalias).

Código administrado en un sistema operativo de 64 bits

Muchos desarrolladores de juegos usan código administrado en su cadena de herramientas, por lo que una comprensión de cómo se comporta en un sistema operativo de 64 bits puede ser útil. El código administrado es neutro para el conjunto de instrucciones, por lo que cuando se ejecuta una aplicación administrada en un sistema operativo de 64 bits, Common Language Runtime (CLR) puede ejecutarlo como un proceso de 32 o 64 bits. De forma predeterminada, CLR ejecuta aplicaciones administradas como de 64 bits y deben funcionar correctamente sin problemas. Sin embargo, si la aplicación depende de un archivo DLL nativo de 32 bits, se producirá un error en la aplicación cuando intente llamar a este archivo DLL. Un proceso de 64 bits necesita código de 64 bits completo y no se puede llamar a un archivo DLL de 32 bits desde un proceso de 64 bits. La mejor solución a largo plazo es compilar el código nativo como de 64 bits, pero una solución a corto plazo perfectamente razonable es simplemente marcar la aplicación administrada como para x86 únicamente mediante la marca de compilación /platform:x86.

Implicaciones de rendimiento de ejecutar un sistema operativo de 64 bits

Dado que los procesadores con arquitectura AMD64 e Intel 64 pueden ejecutar instrucciones de 32 bits de forma nativa, pueden ejecutar aplicaciones de 32 bits a velocidad completa, incluso en un sistema operativo de 64 bits. Hay un costo modesto para convertir parámetros entre 32 y 64 bits al llamar a funciones del sistema operativo, pero este costo suele ser insignificante. Esto significa que no debería ver ninguna ralentización al ejecutar aplicaciones de 32 bits en un sistema operativo de 64 bits.

Al compilar aplicaciones como de 64 bits, los cálculos se complican más. Un programa de 64 bits usa punteros de 64 bits y sus instrucciones son ligeramente mayores, por lo que el requisito de memoria aumenta ligeramente. Esto puede provocar una ligera caída en el rendimiento. Por otro lado, tener el doble de registros y tener la capacidad de realizar cálculos enteros de 64 bits en una sola instrucción a menudo más que compensar. El resultado neto es que una aplicación de 64 bits puede ejecutarse ligeramente más lenta que la misma aplicación compilada que 32 bits, pero a menudo se ejecutará un poco más rápido.

Resumen

Las arquitecturas de sesenta y cuatro bits permiten a los desarrolladores insertar las limitaciones de aspecto, sonido y reproducción de los juegos. Sin embargo, la transición de la programación de 32 bits a la programación de 64 bits no es trivial. Al comprender las diferencias entre los dos y mediante las herramientas más recientes, la transición a plataformas de 64 bits puede ser más fácil y rápida.

Puede encontrar más información sobre la programación de 64 bits en el Centro para desarrolladores de Visual C++: Programación de 64 bits.