x86 에뮬레이터 팀, 형편없는 코드 발견 후 에뮬레이션 중 수정
원제: The time the x86 emulator team found code so bad they fixed it during emulation
왜 중요한가
레거시 시스템 에뮬레이션에서 컴파일러 최적화 버그나 극단적 비효율성을 실시간으로 감지·수정하는 기법은 하위 호환성 유지와 성능 최적화의 절충 사례로서 참고 가치가 있다.
마이크로소프트 x86-32 에뮬레이터 팀이 컴파일러의 극도로 비효율적인 최적화로 인해 64KB 메모리 초기화에 256KB 코드를 사용하는 프로그램을 발견했다. 팀은 에뮬레이터의 바이너리 번역기에 특수 코드를 추가해 이 함수를 감지하고 효율적인 루프로 대체하기로 결정했다.
마이크로소프트의 x86 에뮬레이터 팀이 경험한 일화에 따르면, 특정 프로그램이 스택에 약 64KB 메모리를 할당하고 초기화하려고 했을 때 심각한 코드 비효율성을 발견했다. 표준적인 방식은 스택 프로브를 수행한 후 스택 포인터에서 65,536을 빼고 루프를 통해 메모리를 초기화하는 것이다.
그러나 해당 프로그램을 컴파일한 컴파일러는 루프를 이용한 초기화 대신 극도로 비효율적인 "최적화"를 수행했다. 각 바이트를 메모리에 기록하는 개별 "메모리 쓰기" 명령어 65,536개를 전개(unroll)하여 생성한 것이다. 각 명령어가 4바이트씩이므로 총 256KB의 코드가 필요했다. 즉, 64KB 데이터를 초기화하기 위해 256KB의 코드를 사용한 것이다.
이 상황에 분노한 에뮬레이터 팀은 특수한 대응책을 강구했다. 바이너리 번역 방식의 에뮬레이터에 특수 코드를 추가하여 이러한 형편없는 함수를 감지하고, 동등한 기능을 하는 효율적인 루프로 자동 대체하도록 구현했다. 이는 JIT 컴파일러처럼 작동하는 에뮬레이터가 원본 코드의 극단적인 비효율을 실시간으로 감지하고 수정한 사례다.