A vez em que a equipe do emulador x86 encontrou código tão ruim que o corrigiu durante a emulação

Contornos / Workarounds de drivers e plataformas para código ruim

  • Muitos comentários traçam paralelos entre o emulador “corrigindo” código ruim e camadas modernas como Proton/Wine, drivers de GPU e navegadores, que incluem extensas peculiaridades e gambiarras por aplicativo.
  • Drivers de GPU comumente detectam jogos pelo nome do executável ou por APIs explícitas e então aplicam otimizações específicas para cada jogo ou workarounds de correção, às vezes até reduzindo a qualidade para benchmarks.
  • Isso é visto como frágil: otimizações para um título (por exemplo, “hl2.exe”) podem melhorar o desempenho, quebrar outros jogos ou depender de comportamento indefinido.
  • Motores de navegador têm tabelas semelhantes de “quirks” por site; sistemas operacionais e runtimes já embarcaram shims específicos para aplicativos (por exemplo, para SimCity).

Benchmarks, trapaça e otimizações competitivas

  • Vários exemplos mencionam drivers “trapaceando” em benchmarks populares (Quake 3, demos do DirectX) ao reduzir a qualidade ou pular trabalho quando detectam um caminho de benchmark.
  • Em geral, os fornecedores tentam informar os desenvolvedores de jogos sobre bugs de correção, mas muitas vezes lançam primeiro os workarounds no driver; estúdios grandes recebem mais atenção.
  • Ajustes apenas de desempenho às vezes ficam nos drivers como vantagem competitiva, em vez de serem enviados para upstream.

E/S e patologias de bibliotecas

  • Várias histórias destacam uso patológico de E/S: leituras minúsculas (fread/ReadFile em blocos de 1 byte ou 4 bytes), componentes do sistema operacional emitindo muitas chamadas de sistema pequenas e aplicativos efetivamente derrotando camadas de bufferização.
  • Um comentarista observa que o uso de fread(data, 1, 65536, f) por um jogo expôs uma implementação ruim da stdlib ou modo sem buffer, causando leituras de 65k em nível de byte; uma camada de cache no hook foi necessária para corrigir o desempenho.
  • Há debate sobre se esse uso de fread é semanticamente incorreto (a maioria diz que não; a culpa é da implementação).

Stack probing, guard pages e memória não inicializada

  • A discussão cobre stack probing no Windows: frames grandes de stack precisam tocar cada página sequencialmente para acionar guard pages e detectar estouros.
  • Alguns observam que muitas alocações reais de stack simplesmente “esperam pelo melhor”, mas os compiladores do Windows adicionam probes para frames grandes.
  • Vários comentários descrevem recursos customizados ou do sistema que preenchem a memória da stack com padrões canário ou zeros (por exemplo, switches do compilador, inicialização automática da stack) para detectar bugs de variáveis não inicializadas.

Loop unrolling e inchaço de código

  • O loop unrolling é defendido como uma otimização válida, mas muitos apontam retornos decrescentes e custos de tamanho de código, especialmente quando blocos enormes desdobrados trazem penalidades de cache.
  • O exemplo de “256 KB de código para inicializar 64 KB” é amplamente visto como um caso extremo de sobre-otimização e comportamento ruim do compilador.