What Irregularity Costs: CUDA C++, Rust, and Triton on a Hash-Blocked GPU Workload
이 논문은 정규 GPU 워크로드에서는 CUDA C++, Rust, Triton이 유사한 성능을 보이는 반면, 불규칙한 해시 블록 작업(hash-blocked tasks)에서는 원자적 연산(atomic operations)과 루프 경계(loop bounds)를 표현하는 데 있어 각 언어 특유의 제한 사항으로 인해 효율성이 급격히 갈라진다는 점을 입증하며, 특히 Rust는 캐시 일관성(cache coherence) 문제로 고통받고 Triton은 마스킹 불가능한 원자적 연산(unmaskable atomics)과 컴파일 타임 루프 제약으로 인해 어려움을 겪는다는 것을 보여준다.
원본 논문은 CC BY 4.0 (http://creativecommons.org/licenses/by/4.0/) 라이선스로 제공됩니다. 이것은 아래 논문에 대한 AI 생성 설명입니다. 저자가 작성하거나 승인한 것이 아닙니다. 기술적 정확성을 위해서는 원본 논문을 참조하세요. 전체 면책 조항 읽기
무대와 연기자들
당신이 수천 장의 사진을 찍는 카메라를 이용해 방의 3D 모델을 만들려고 한다고 상상해 보십시오. 이를 실현하기 위해 컴퓨터는 그 방의 모든 아주 작은 공간에 대한 방대한 양의 데이터를 정리해야 합니다. 이것이 바로 GPU 프로그래밍의 세계입니다. 여기서 "GPU"란 컴퓨터 내부에서 매우 빠르게 작동하며, 한 번에 수백만 개의 수학 계산을 수행하는 데 탁월한 그래픽 칩을 말합니다.
보통 사람들이 이 칩들을 위한 서로 다른 프로그래밍 언어를 비교할 때는, 거대한 숫자 격자를 곱하는 것과 같이 매우 깔끔하고 예측 가능한 작업으로 테스트를 진행합니다. 이는 마치 경주용 자동차를 완벽하게 곧고 비어 있는 고속도로에서 테스트하는 것과 같습니다. 모든 차선은 동일하며, 모든 운전자는 경주가 얼마나 걸릴지 정확히 알고 있습니다. 하지만 현실 세계는 무질서합니다. 가상 현실이나 로봇 내비게이션과 같은 애플리케이션에서는 컴퓨터가 혼란스럽고 예측 불가능한 데이터를 다뤄야 합니다. 이는 방금 전의 경주용 자동차를 교통 체증이 무작위로 발생하고 운전자들이 끊임없이 멈추고 출발해야 하는, 붐비고 구불구불한 도시 거리로 보내는 것과 같습니다. 이 논문은 단순하지만 매우 중요한 질문을 던집니다: 길이 무질서해질 때, 모든 프로그래밍 언어가 똑같이 성능을 내는가, 아니면 어떤 언어는 교통 체증에 갇히고 어떤 언어는 질주하는가?
위대한 GPU 언어 대결
이 연구에서 연구진들은 이 슈퍼 칩들과 대화하는 세 가지 인기 있는 방식인 CUDA C++(전통적인 수작업 표준), Rust(안전성으로 알려진 현대적 언어), 그리고 Triton(코딩을 더 쉽게 만들기 위해 설계된 새로운 도구)을 가져와 "해시 테이블(hash table)"을 사용하여 방의 3D 지도를 만드는 매우 구체적이고 혼란스러운 작업에 투입했습니다.
해시 테이블을 거대하고 혼란스러운 사물함 방이라고 생각해 보십시오. 수천 명의 사람들(데이터 포인트)이 물건을 보관할 사물함(메모리 공간)을 찾으려고 노력하고 있습니다. 때로는 원하는 사물함이 비어 있어서 바로 차지하기도 합니다. 하지만 종종 사물함이 이미 차 있어서, 빈 공간을 찾을 때까지 다음 칸을 확인하고 또 확인해야 합니다. 완벽한 세상이라면 모두가 즉시 사물함을 찾을 것입니다. 하지만 이 "불규칙한(irregular)" 작업 환경에서는 어떤 사람들은 즉시 사물함을 찾지만, 어떤 사람들은 한참을 찾아야 하며, 모두가 동시에 몇 안 되는 사물함을 차지하려고 싸웁니다.
연구진은 세 가지 언어 모두에 동일한 작업을 실행하고 완료 시간을 측정했습니다. 결과는 충격적이었습니다: 언어에 따라 작업의 유형에 따라 완전히 다르게 행동했습니다.
"규칙적인" 부분: 막상막하의 승부
먼저, 그들은 복도를 걸어가며 보이는 모든 벽을 색칠하는 것과 같은 작업의 "규칙적인(regular)" 부분을 테스트했습니다. 이 부분은 예측 가능합니다. 이 작업에서 세 언어는 거의 동일했습니다. 전통적인 CUDA를 사용하든, 현대적인 Rust를 사용하든, 혹은 사용하기 쉬운 Triton을 사용하든, 세 언어 모두 거의 비슷한 시간 안에 작업을 마쳤습니다. 만약 당신이 이러한 깔끔하고 예측 가능한 테스트(대부분의 다른 연구들이 하는 방식)만 본다면, 어떤 언어를 선택하든 상관없다고 생각할 것입니다.
"불규칙한" 부분: 거대한 격차
그다음, 그들은 혼란스러운 사물함 찾기인 "불규칙한(irregular)" 부분을 테스트했습니다. 여기서 이야기는 극적으로 변합니다.
- Rust vs. CUDA C++: Rust 언어는 직접 작성된 CUDA C++와 거의 비슷하게 우수한 성능을 보였습니다. 경우에 따라 약 1%에서 3% 정도 약간 느렸을 뿐이며, 이는 사실상 동점이라 할 수 있습니다. Rust는 무질서하고 예측 불가능한 교통 상황을 베테랑만큼 잘 처리할 수 있음을 증명했습니다.
- Triton의 고전: 그러나 Triton은 거대한 벽에 부딪혔습니다. 혼란스러운 검색 작업에서 Triton은 다른 두 언어보다 10배 이상 느렸습니다. 실제 방 스캔을 이용한 실제 환경 테스트에서는 거의 30배나 느렸습니다.
왜 Triton은 갇혔는가?
연구진은 단순히 "Triton이 느리다"라고 말하는 데 그치지 않고, 왜 Triton이 갇혔는지 정확한 이유를 밝혀냈습니다. 그것은 코드가 형편없이 작성되었기 때문이 아니라, 언어의 구조적 설계 때문이었습니다.
Triton을 수업 중인 학생들에게 일이 끝나더라도 정해진 시간 동안 자리에 앉아 있어야 한다고 강요하는 엄격한 선생님이라고 상상해 보십시오. 혼란스러운 사물함 방에서 어떤 스레드(학생)들은 1초 만에 사물함을 찾지만, 어떤 스로들은 10초가 걸립니다.
- 문제점: Triton은 빠른 스레드들이 할 일이 더 이상 없음에도 불구하고, 가장 느린 스레드가 끝날 때까지 루프 속에서 기다리도록 강제합니다. 이는 마치 경주에서 우승자가 트랙을 떠나기 전 마지막 사람이 결승선을 통과할 때까지 가만히 서서 기다려야 하는 것과 같습니다.
- "마스크(Mask)" 문제: 더욱이, Triton에는 빠른 스레드들이 작업을 완전히 멈출 수 있게 해주는 특정 도구(이를 "마스크"라고 부릅니다)가 부족합니다. 대신, 그들은 아무 일도 하지 않으면서 계속 헛된 작업을 수행하며 에너지와 시스템 자원을 낭비합니다. 연구진은 이러한 설계 선택이 컴퓨터로 하여금 엄청난 양의 무익한 작업을 하게 만들어, 전체 속도를 10배에서 30배까지 늦췄다는 것을 발견했습니다.
- 숨겨진 위험: 안전 문제도 있었습니다. Triton은 검색에 고정된 시간 제한을 두기 때문에, 사물함 방이 너무 붐비면 검색을 포기하고 멈춰버릴 수 있습니다. 이는 컴퓨터가 3D 공간의 일부를 소리 없이 버리게 되어, 최종 모델에 보이지 않는 구멍을 만드는 것을 의미합니다. 연구진은 특정 혼잡도에서 Triton이 표면의 전체 덩어리를 놓치는 반면, 다른 언어들은 이를 완벽하게 찾아낸다는 것을 발견했습니다.
왜 Rust는 약간 더 느렸는가 (보이지 않는 함정)
Rust는 우승에 매우 근접했지만, 직접 작성된 CUDA 코드만큼 빠르지는 않았습니다. 연구진은 명령어 수와 메모리 사용량을 확인하며 왜 그런지 밝히기 위해 오랜 시간을 들였습니다. 그들은 Rust가 실제로 CUDA보다 적은 일을 하고 있음에도 불구하고 여로 느리다는 것을 발견했습니다.
원인은 Rust가 안전성을 처리하는 방식에 숨겨진 함정이었습니다. Rust에는 공유 데이터를 읽을 때 모두가 동일한 버전을 보도록 보장하여 "안전"하게 만드는 기능이 있습니다. 하지만 이 특정 칩들에서 데이터를 읽는 "안전한" 방식은 컴퓨터가 가장 빠른 메모리 캐시를 건너뛰고 더 느린 캐시로 가게 만듭니다. 이는 마치 보안 요원이 이미 안전하다고 확인된 패키지임에도 불구하고 입구에서 모든 패키지를 일일이 검사하겠다고 고집하는 것과 같습니다. 이 추가적인 단계가 Rust를 약 20~30% 정도 느리게 만들었지만, Triton의 엄청난 저하에 비하면 아주 작은 대가였습니다.
시사점
이 논문의 핵심 교훈은 깔끔하고 예측 가능한 작업만으로 프로그래밍 언어를 판단해서는 안 된다는 것입니다.
만약 당신이 오직 "규칙적인" 고속도로에서만 테스트한다면, Rust, CUDA, Triton 모두 챔피언처럼 보일 것입니다. 하지만 실제 3D 매핑의 "불규칙한" 도시 교통 속으로 던져지면, 결과는 극명하게 갈립니다.
- Rust는 강력한 경쟁자로, 가장 뛰어난 수작업 코드만큼 거의 빠르게 유지됩니다.
- Triton은 깔끔한 작업에는 훌륭할지 모르지만, 혼란스럽고 예측 불가능한 작업에서는 고전하며 수십 배 느려지고, 인지하지 못한 채 데이터를 잃을 수도 있습니다.
연구진은 무질서한 실제 데이터를 다루는 작업의 경우, 잘못된 언어를 선택하는 것이 단순히 작은 불편함이 아니라, 프로그램을 사용 불가능할 정도로 느리게 만들거나 조용히 실패하게 만들 수 있다고 결론지었습니다. 또한, 많은 이전 연구들이 "규칙적인" 부분만을 테스트했기 때문에, 이 위험하고 무질서한 부분들을 탐구하지 못했다는 점도 밝혀냈습니다.
연구 분야의 논문에 파묻히고 계신가요?
연구 키워드에 맞는 최신 논문의 일일 다이제스트를 받아보세요 — 기술 요약 포함, 당신의 언어로.