원문 캡처 · collabora.com
원문 캡처 · collabora.com

Mesa 27.0부터 Valhall(v9) 이상 아키텍처를 사용하는 모든 Mali GPU가 Panfrost 드라이버 스택의 새 컴파일러 Kraid를 사용한다. 개발을 시작한 지 약 6개월 만에 Kraid가 Mesa 메인 브랜치의 기본 컴파일러가 됐으며, Mesa 26.3은 기존 컴파일러를 탑재하는 마지막 릴리스다.

새 컴파일러를 만든 이유는 기존 컴파일러에 심각한 설계 결함이 있어 Mali GPU에 맞춰 제대로 최적화하기 어려웠기 때문이다. 자세한 내용은 이전 블로그 글이나 X.org Developer's Conference 발표에서 확인할 수 있다.

Kraid의 가장 큰 변화는 Mali GPU의 레지스터 접근 방식을 더 정확히 모델링한다는 점이다. 기존 컴파일러는 스위즐(swizzle)을 정확히 모델링하지 못해 데이터를 옮기는 불필요한 명령을 많이 생성했다. Kraid는 64비트 데이터 처리도 개선했으며, 64비트 정수 연산을 완전히 지원한다. 64비트 포인터 연산이 흔한 OpenCL에서 특히 중요하다. 캡처한 OpenGL 셰이더 집합에서는 명령 수가 거의 20% 줄었다.

total instrs in shared programs: 714433 -> 582468 (-18.47%)
instrs in affected programs: 710788 -> 578823 (-18.57%)
helped: 7038

Kraid는 부동소수점 변환 명령도 훨씬 적게 생성한다. Mali GPU는 대부분의 32비트 부동소수점 연산 명령에서 16비트 부동소수점 입력값을 읽고, 이를 추가 비용 없이 32비트로 변환할 수 있다. 필요한 경우 같은 명령에서 16비트로 다시 변환하는 일도 대체로 가능하다. Kraid의 스위즐 모델링은 이 기능을 활용해 여러 부동소수점 변환을 산술 명령의 입력이나 출력에 통합한다. OpenGL ES를 사용하는 일부 작업에서는 부동소수점 변환이 특히 많이 누적된다. 이를 보여주는 사례로 RK3588에서 clpeak v10을 실행한 벤치마크 결과가 제시됐다.

| benchmark | Kraid/Old |
|-----------------------------------------------------|-----------|
| Single-precision compute (float) | 99.77% |
| Single-precision compute (float2) | 95.95% |
| Single-precision compute (float4) | 89.96% |
| Single-precision compute (float8) | 90.19% |
| Single-precision compute (float16) | 90.26% |
| Half-precision compute (half) | 99.83% |
| Half-precision compute (half2) | 99.97% |
| Half-precision compute (half4) | 94.58% |
| Half-precision compute (half8) | 87.26% |
| Half-precision compute (half16) | 87.62% |
| Mixed-precision compute fp16xfp16+fp32 (mp) | 149.37% |
| Mixed-precision compute fp16xfp16+fp32 (mp2) | 164.54% |
| Mixed-precision compute fp16xfp16+fp32 (mp4) | 147.07% |
| Mixed-precision compute fp16xfp16+fp32 (mp8) | 152.75% |
| Mixed-precision compute fp16xfp16+fp32 (mp16) | 152.45% |

Kraid는 레지스터 할당과 스필(spill) 처리 방식도 바꿨다. 컴파일 과정에서 레지스터 할당 단계까지 정적 단일 할당(static single assignment, SSA) 형식을 유지한다. SSA 기반 레지스터 할당의 장점 중 하나는 레지스터 할당 전에 필요한 레지스터 수를 정확히 추정할 수 있다는 것이다. 이에 따라 SSA 형식을 유지한 채 레지스터 할당 전에 스필을 처리할 수 있다. 이 방식은 값이 어떻게 쓰이는지 더 많은 정보를 활용해 스필 대상을 더 잘 선택하게 해준다. Vulkan 셰이더 데이터베이스 전체에서 스필이 약 80% 줄었다. 스필이 발생할 때마다 메모리에 접근해야 하며, 모바일 GPU에서는 메모리 접근 비용이 매우 크기 때문에 중요하다.

Totals from 7098 (95.45% of 7436) affected shaders:
Instrs: 1424643 -> 1144579 (-19.66%); split: -19.91%, +0.25%
Spill count: 66682 -> 10454 (-84.32%); split: -84.47%, +0.15%
Fill count: 111898 -> 23988 (-78.56%); split: -78.57%, +0.01%
Estimated spill cost: 5585480 -> 887580 (-84.11%); split: -84.11%, +0.00%

SSA 기반 스필 처리와 레지스터 할당은 대체로 선형 시간 알고리즘이며, 기존 그래프 색칠 알고리즘의 이차 또는 삼차 실행 시간보다 빠르다. 그 결과 Kraid를 사용하면 Vulkan 파이프라인 데이터베이스 컴파일이 약 7배 빨라지고 메모리 사용량은 35% 줄었다.

387.32 user 5.86 system 0:23.68 elapsed 1659%CPU (1794216 max resident)
2729.18 user 6.35 system 8:14.90 elapsed 552%CPU (2783724 max resident)

Kraid를 개발하면서 오랫동안 할 일 목록에 있던 프래그먼트 셰이더 최적화도 구현했다. 그중 하나는 배리언트 보간에 숨겨진 레지스터를 활용하는 방식이다. 프래그먼트 셰이더 시작 부분에서 여러 배리언트를 보간할 때 하드웨어가 중복 계산을 피할 수 있어 전력을 아끼고 보간 속도를 높인다. 대체로 절감 폭은 작지만, 일부 Candy Crush 실행 기록에서는 성능이 40% 개선됐다.

가능한 경우 텍스처 명령 융합도 적용한다. Mali 하드웨어는 특정 조건에서 배리언트 보간과 텍스처 명령을 융합해 메시지 유닛을 거치는 왕복을 피하고, 다른 하드웨어 최적화를 가능하게 할 수 있다. 서로 다른 텍스처를 대상으로 한다는 점만 빼고 동일한 두 텍스처 명령을 융합하는 최적화도 있다. 색상용 텍스처와 노멀 맵용 텍스처를 각각 사용하는 구형 앱에서 이런 경우가 흔하다.

종합하면 실제 앱 성능은 대체로 비슷하거나 몇 퍼센트 정도 나아졌다. 모바일 GPU에서 앱 실행이 셰이더 처리에 병목되는 경우는 드물기 때문에 예상 밖의 결과는 아니다. 메모리 대역폭 같은 요소가 셰이더 연산을 조금 줄이는 것보다 성능에 훨씬 큰 영향을 주는 경우가 많다. 다만 GPU 드라이버 최적화에서는 몇 퍼센트의 개선도 큰 성과라고 설명한다. 아래 수치는 Kraid와 기존 컴파일러의 FPS를 비교한 결과다.

# Vulkan:
| benchmark | Kraid/Old FPS |
|-----------------------|---------------|
| Basemark BATS | 100.42% |
| 3DMark Wildlife | 106.51% |
| Super Fantasy Kingdom | 104.77% |
| Sky Children of Light | 96.57% |
| GFXBench Aztec Ruins | 104.38% |
| Roblox | 99.73% |
| Unity Viking Village | 99.84% |
| Android Contacts | 101.22% |
| Android Gallery | 103.85% |
| Android Maps | 102.16% |
# GLES:
| benchmark | Kraid/Old FPS |
|-----------------------|---------------|
| HalfLife | 100.49% |
| CandyCrush Soda-Saga | 139.36% |
| Firefox | 99.13% |
| Genshin Scene 1 | 104.43% |
| eBay Product Browsing | 106.38% |
| GFXBench Manhattan | 104.32% |
| Honkai: Star Rail | 102.88% |
| CallOfDutyMobile | 117.98% |
| GFXBench Aztec | 110.58% |
| PUBG | 102.56% |
| Genshin Scene 2 | 106.18% |
| DeusEx | 99.55% |
| GFXBench TRex | 103.94% |
| Netflix UI | 106.96% |
| ApexLegends | 105.34% |

개발팀은 Kraid가 앞으로 컴파일러를 개발할 더 안정적인 기반이 되기를 기대한다. 추가 작업은 남아 있으며 컴파일러 개발은 계속되지만, 기존 컴파일러 스택의 기반 문제는 대부분 해결됐다고 본다. Kraid에 버그가 전혀 없는 것은 아니지만, 숨은 문제는 훨씬 적다고 설명한다.