GPU — レイテンシを削る代わりにスループットを広げた設計
한국어 원문으로 표시합니다.
한 줄 요약
CPU 는 한 스레드를 최대한 빨리 끝내도록 만들어졌고, GPU 는 수만 스레드를 동시에 굴려 메모리 대기 시간을 서로 가려 주도록 만들어졌다.
왜 이게 필요했나
CPU 는 한 흐름의 지연을 줄이는 데 트랜지스터를 쓴다. 분기 예측기, 비순차 실행 엔진, 커다란 캐시가 전부 "지금 이 스레드가 멈추지 않게" 하는 장치다. 문제는 이 방식의 수익이 체감한다는 것이다. 예측기를 두 배로 키워도 성능은 몇 퍼센트 오른다.
같은 트랜지스터를 다르게 쓰는 방법이 있다. 제어 회로를 극단적으로 단순화하고 산술 유닛을 잔뜩 채운 뒤, 스레드를 아주 많이 올려 둔다. 한 스레드가 메모리를 기다리는 동안 다른 스레드를 실행하면 대기 시간이 가려진다. 이것이 GPU 의 설계 철학이며, 그래서 GPU 는 지연을 줄이는 장치가 아니라 지연을 감추는 장치다.
어떻게 동작하나
GPU 는 여러 개의 스트리밍 멀티프로세서(SM) 로 이루어진다. 각 SM 안에서 스레드는 32개씩 묶여 워프(warp) 단위로 스케줄링되며, 한 워프 안의 스레드들은 같은 명령어를 각자의 데이터에 대해 실행한다(SIMT).
여기서 두 가지 성능 함정이 나온다.
분기 발산(divergence). 워프 안에서 절반은 if 로, 절반은 else 로 가면 하드웨어는 양쪽 경로를 순차로 실행하면서 해당하지 않는 스레드를 잠시 꺼 둔다. 결과는 맞지만 시간은 두 경로의 합이 된다. 조건이 데이터에 따라 제각각인 커널이 느린 이유다.
병합 접근(coalescing). 한 워프의 32개 스레드가 연속된 주소를 읽으면 메모리 트랜잭션 몇 개로 끝난다. 흩어진 주소를 읽으면 최악의 경우 32개의 트랜잭션이 필요하다. 같은 계산인데 인덱싱만 바꿔도 배수로 갈리는 이유가 여기 있다.
메모리 계층도 CPU 와 다르다. SM 안에는 프로그래머가 명시적으로 관리하는 공유 메모리가 있다. 캐시가 알아서 해 주기를 기다리는 대신, 재사용할 데이터를 직접 올려 두고 여러 스레드가 나눠 쓴다. 행렬 곱셈 커널의 성능 대부분이 이 공유 메모리 타일링에서 나온다.
점유율(occupancy) 은 SM 이 동시에 유지할 수 있는 워프 수 대비 실제로 올라간 워프 수다. 점유율이 낮으면 가릴 스레드가 부족해 메모리 대기가 그대로 드러난다. 다만 점유율이 높다고 늘 빠른 것은 아니다. 레지스터를 많이 쓰는 커널은 점유율을 낮추더라도 스레드당 작업량을 늘리는 편이 나을 때가 있다.
현장에서 만나는 모습
AI 추론에서 GPU 사용률이 30퍼센트를 못 넘는다는 이야기가 흔하다. 원인은 대개 연산 부족이 아니라 메모리 대역폭이다. LLM 디코딩은 거대한 가중치를 읽어와 작은 입력과 곱하고 버리므로 산술 강도가 낮고, 그래서 roofline 의 왼쪽 비탈에 놓인다. 이 구간에서는 연산 성능이 더 높은 칩을 사도 성능이 오르지 않는다. 답은 읽을 바이트를 줄이거나(양자화) 배치를 키워 같은 가중치 읽기를 여러 요청이 나눠 쓰게 만드는 것이다.
TPU 같은 가속기가 다른 답을 낸 지점도 여기다. 시스톨릭 어레이는 데이터를 격자 사이로 흘리며 재사용해서 메모리 접근당 연산 수를 극대화한다. 범용성을 포기하고 산술 강도를 사 온 설계다.
무엇이 GPU 에 맞고 무엇이 안 맞나
같은 문제라도 GPU 에 올려서 이득을 보는 것과 오히려 손해를 보는 것이 나뉜다. 판단 기준은 세 가지다.
한 번에 할 일이 충분히 많은가. GPU 는 수만 스레드를 굴려야 제 값을 하므로, 원소가 수천 개뿐인 계산은 커널을 띄우는 비용조차 회수하지 못한다. 커널 실행 자체에 수 마이크로초가 들고, 그 시간이면 CPU 가 이미 끝냈을 일이 흔하다.
옮기는 값이 계산량에 비해 작은가. CPU 메모리와 GPU 메모리는 별개라 데이터를 복사해야 하고, 그 통로는 GPU 안의 대역폭보다 훨씬 좁다. 복사에 드는 시간이 계산 시간보다 길면 GPU 는 순수한 손해다. 그래서 실무의 정석은 한 번 올린 데이터를 여러 단계에 걸쳐 GPU 위에서 계속 쓰는 것이고, 단계마다 CPU 로 내렸다 올리는 구조는 거의 언제나 잘못된 설계다.
스레드마다 하는 일이 같은가. 원소마다 조건이 달라 갈라지는 계산은 앞에서 본 분기 발산 때문에 이득이 크게 줄어든다. 그래서 GPU 에 맞는 문제는 대체로 조밀한 배열 위의 규칙적인 연산이다.
이 셋을 뒤집으면 GPU 가 안 맞는 일이 그대로 나온다. 갈래가 많은 논리, 포인터를 따라가는 자료 구조, 앞의 결과가 있어야 다음을 시작할 수 있는 순차 처리, 그리고 매번 조금씩만 계산하는 짧은 작업이다. AI 학습과 추론이 GPU 에 잘 맞는 이유는 신비한 성질 때문이 아니라 이 세 조건을 정확히 만족하기 때문입니다.
한 가지 실무 감각을 덧붙인다. GPU 가 붙은 서버에서 성능이 안 나올 때 사람들은 GPU 를 먼저 의심하지만, 원인이 데이터를 공급하는 쪽인 경우가 아주 많다. 디스크에서 읽고 전처리해서 올려 주는 파이프라인이 GPU 를 다 채우지 못하면, 값비싼 카드가 대부분의 시간을 기다리며 논다. 사용률을 시간에 따라 그려 봤을 때 톱니처럼 오르내린다면 그것이 이 상황의 전형적인 모습이다.
이어지는 퀴즈에서 확인할 것
"GPU 가 CPU 보다 빠르다"는 말이 왜 절반만 맞는지, 그리고 GPU 를 사고도 성능이 안 나오는 전형적인 이유를 설명할 수 있는지 확인한다.