TECH 으로 돌아가기
TECH HACKER NEWS 오늘 7분 읽기 28 READS

가장 느린 단 하나의 명령어를 찾아서: 어셈블리 '수치의 전당'

가장 느린 단 하나의 명령어를 찾아서: 어셈블리 '수치의 전당'
SOURCE IMAGE · HACKER NEWS

CPU 성능을 다루는 글은 대개 한 방향을 향한다. 어떻게 하면 명령어를 더 빨리 실행할 것인가. 보안 연구자 크리스토퍼 도마스(@xoreaxeaxeax)가 공개한 '어셈블리 수치의 전당(Assembly Hall of Shame)'은 정확히 그 반대편을 판다. 단 하나의 명령어가 낼 수 있는 성능의 '바닥'이 어디인지, 즉 어떻게 하면 명령어 하나를 가능한 한 오래 걸리게 만들 수 있는지를 겨루는 리더보드다. 프로젝트 소개 문구부터가 "CPU 성능의 바닥을 향한 경주"다.

출발선은 아무 일도 하지 않는 nop이다. nop은 문자 그대로 아무것도 하지 않기 때문에 리더보드의 기준점 역할을 한다. 여기서 곧바로 역설적인 질문이 나온다. 아무것도 안 하는 일을 어떻게 더 오래 걸리게 만들 것인가. 답은 마이크로코드와 하드웨어의 예외 경로를 일부러 밟는 것이다. 참가 기종으로는 인텔 Core i7-8559U(2.70GHz)와 AMD Ryzen 7 5800H(Trigkey S5)가 등장한다.

마이크로코드의 느린 골목을 파고들기

초기 전략들은 CPU 내부에서 '지름길'이 아니라 '우회로'가 발동되는 조건을 노린다. 128비트 피제수(rdx:rax=2:0)와 작은 제수를 써서 나눗셈 마이크로코드의 가장 긴 경로를 강제하거나, 비정규수(denormal/subnormal)를 피연산자로 넣어 부동소수점 마이크로코드 어시스트를 유발하는 식이다. 지수 필드를 0x7ff로 채워 '특수값' 처리 경로(QNaN)에 진입시키거나, 중첩 깊이를 최대치인 31까지 올려 디스플레이 포인터를 반복적으로 걷게 만드는 시도도 있다. AMD Zen에서는 lock 접두사가 붙은 피연산자를 캐시 라인 경계에 걸치도록 정렬해, 빠른 MESI 캐시 일관성 경로 대신 외부 버스 락을 강제로 걸게 하는 기법이 소개된다.

메모리 서브시스템을 통째로 흔드는 방법도 있다. movnti 저장으로 write-combining 라인필 버퍼를 모두 채운 뒤 mfence로 전체를 uncore까지 배출하게 하거나, L1/L2/L3를 더티 라인으로 가득 채워 계층 전체를 DRAM으로 되쓰게 만든다. rdrand 계열을 촘촘한 루프로 돌려 하드웨어 엔트로피 풀을 소모 속도보다 빠르게 고갈시켜 후속 호출이 재충전을 기다리며 멈추게 하는 접근도 흥미롭다.

MMIO와 PCIe 패브릭이라는 '심해'

리더보드의 진짜 바닥은 CPU 코어 바깥, 즉 PCIe 패브릭에 있다. 저자는 mmiotic, rakefield, project:nightshyft 같은 자체 도구로 응답이 극단적으로 느린 지점을 찾는다. 예컨대 nightshyft로 찾아낸 Zen의 MCG_CTL MSR은 여러 하드웨어 유닛의 MCA 오류 뱅크를 동기화하며 다이 바깥과의 패브릭 통신을 요구하는 것으로 추정된다. VIA에서는 문서화되지 않은 0x133 레지스터가 터무니없이 긴 응답 시간을 보이는데, 무슨 기능인지는 알 수 없다고 적혀 있다. NIC 레지스터 경계에 걸친 I/O 포트를 건드려 매 쓰기마다 TX DMA 엔진을 멈추게 하거나, ACPI PM 블록에 매핑된 포트의 비정렬 4바이트 읽기를 여러 개의 논포스티드 로드로 분해시키는 방법도 목록에 있다.

가장 극단적인 항목들은 규격 위반에 가깝다. PCIe 패브릭에서 가장 느린 GPU 레지스터를 찾은 뒤 8·16·32바이트 MMIO 읽기로 한 번에 여러 dword 접근을 강제하는데, 저자는 이것이 "기술적으로 허용되지 않지만 어쨌든 동작한다"고 반복해 적는다. 비정렬 32바이트 읽기로 9개 dword를 긁어내는 변형은 정렬판보다 "더더욱 허용되지 않지만" 역시 동작한다. 백미는 fxrstor64로 512바이트 FPU/MMX/XMM 상태를 느린 MMIO 영역에서 로드하고, 그 로드가 진행 중일 때 다수의 '해머 코어'가 다른 고지연 MMIO 레지스터를 4바이트 읽기로 두드려 패브릭을 포화시키는 것이다. CPU 0의 512바이트 로드는 이 경쟁 트래픽 뒤에 줄을 서게 된다.

장난을 넘어선 시사점

이 프로젝트가 단순한 기행으로만 보이지 않는 이유는, 여기서 쓰인 기법이 실제 보안 연구와 맞닿아 있기 때문이다. 규격을 어긴 비정렬 ymm0 로드로 멈춰 있는 GPU 레지스터에서 논포스티드 dword 전송을 강제하는 기법은 시스템 관리 모드(SMM)의 근본 설계를 무너뜨리는 데 사용됐다고 명시된다. 실무자 입장에서 이는 '허용되지 않지만 동작하는' 하드웨어의 회색지대가 곧 신뢰 경계의 약점이 될 수 있음을 보여준다. 인텔 사파이어 래피즈에서는 확장 AVX 상태의 xsave 영역이 512바이트가 아니라 8KB로 16배에 달해, 같은 MMIO 기법을 적용하면 1조(1,000,000,000,000) 사이클급 지연이 가능하다는 계산까지 제시된다.

다만 한계도 분명하다. 각 전략은 특정 칩과 특정 플랫폼 구성에서 관찰된 결과이며, 0x133 레지스터처럼 동작 원리조차 확인되지 않은 항목이 다수다. 재현성은 메인보드, 펌웨어, 연결된 장치 배치에 따라 크게 달라질 수밖에 없다. 그럼에도 이 '느림의 경주'는 명령어 지연 분석을 성능 최적화의 반대편에서 바라볼 때 CPU와 I/O 패브릭의 마이크로아키텍처가 얼마나 깊고 예측 불가능한지를 드러낸다. 벤치마크의 평균값 뒤에 숨은 극단값이야말로, 성능 엔지니어와 보안 연구자 모두가 눈여겨봐야 할 지점이라는 사실을 이 리더보드는 유쾌하게 상기시킨다.

SOURCE · HACKER NEWS
원문 전체 보기 → https://github.com/xoreaxeaxeax/asm-hall-of-shame
SHARE
처리 중...