La vez que el equipo del emulador x86 encontró un código tan malo que lo corrigieron durante la emulación

Soluciones alternativas de la plataforma y los controladores para código malo

  • Muchos comentarios trazan paralelismos entre el emulador “arreglando” código malo y capas modernas como Proton/Wine, los controladores de GPU y los navegadores, que incluyen amplios trucos y excepciones por aplicación.
  • Los controladores de GPU suelen detectar juegos por el nombre del ejecutable o por APIs explícitas, y luego aplican optimizaciones específicas para cada juego o soluciones para corregir fallos, a veces incluso reduciendo la calidad para los benchmarks.
  • Esto se ve como algo frágil: las optimizaciones para un título (por ejemplo, “hl2.exe”) pueden mejorar el rendimiento, romper otros juegos o depender de comportamiento indefinido.
  • Los motores de navegador tienen tablas similares de “excepciones” por sitio; los sistemas operativos y los entornos de ejecución han incluido adaptadores específicos por aplicación (por ejemplo, para SimCity).

Benchmarks, trampas y optimizaciones competitivas

  • Varios ejemplos mencionan controladores que “hacen trampas” para benchmarks populares (Quake 3, demos de DirectX) al bajar la calidad o saltarse trabajo cuando detectan una ruta de benchmark.
  • En general, los proveedores intentan informar a los desarrolladores de juegos sobre errores de corrección, pero a menudo primero publican soluciones en el controlador; los grandes estudios reciben más atención.
  • A veces, los ajustes solo de rendimiento se mantienen en los controladores como una ventaja competitiva en lugar de enviarse aguas arriba.

Patologías de E/S y de bibliotecas

  • Varias historias destacan usos patológicos de E/S: lecturas diminutas (fread/ReadFile en trozos de 1 byte o 4 bytes), componentes del sistema operativo que emiten muchas llamadas al sistema pequeñas y aplicaciones que, en la práctica, anulan las capas de almacenamiento en búfer.
  • Un comentarista señala que el uso de fread(data, 1, 65536, f) por parte de un juego puso en evidencia una mala implementación de la stdlib o un modo sin búfer, provocando lecturas byte a byte de 65 kB; fue necesario un nivel de caché en el hook para corregir el rendimiento.
  • Existe debate sobre si ese uso de fread es semánticamente incorrecto (la mayoría dice que no; la culpa es de la implementación).

Comprobación de pila, páginas de guarda y memoria no inicializada

  • La discusión cubre la comprobación de pila en Windows: los grandes marcos de pila deben tocar cada página secuencialmente para activar las páginas de guarda y detectar desbordamientos.
  • Algunos señalan que muchas asignaciones reales de pila simplemente “confían en lo mejor”, pero los compiladores de Windows añaden comprobaciones para marcos grandes.
  • Varios comentarios describen características personalizadas o del sistema que rellenan la memoria de la pila con patrones centinela o con ceros (por ejemplo, opciones del compilador, inicialización automática de la pila) para detectar errores de variables no inicializadas.

Desenrollado de bucles y bloat de código

  • Se defiende el desenrollado de bucles como una optimización válida, pero muchos señalan rendimientos decrecientes y costes en tamaño de código, especialmente cuando bloques gigantes desenrollados introducen penalizaciones de caché.
  • El ejemplo de “256 KB de código para inicializar 64 KB” se ve ampliamente como un caso extremo de sobreoptimización y mal comportamiento del compilador.