cudatraining · 학습 기록

LESSON 02 · 2026.04.18 · T4

복사 비용의 정체 — pageable vs pinned

같은 커널, 같은 GPU. host 쪽 메모리 선택만 바꿨는데 end-to-end 시간이 5.6 배 뛰었다. D2H 한쪽은 12.7 배. 이 격차의 출처를 숫자와 페이지 테이블로 분해한다.

GPU · T4 · sm_75 sweep · 16 runs PCIe Gen3 x16 실효 · ~13 GB/s

실험

src/vector_add.cu--pinned / --pageable 플래그를 달고, host 버퍼 할당을 cudaMallocHostnew float[] 로 분기했다. 같은 GPU 경로 — 커널은 똑같고, 호스트 메모리만 다르다.

Transfer bandwidth 고원

pinnedpageableratio
H2D~12.3 GB/s~4.6 GB/s2.7×
D2H~13.1 GB/s~1.03 GB/s12.7×

End-to-end 총 시간

npinnedpageableratio
2²⁰1.12 ms6.84 ms6.1×
2²²4.28 ms24.09 ms5.6×
2²⁴16.87 ms95.03 ms5.6×
2²⁶67.38 ms375.69 ms5.6×
2²⁸270.56 ms1519.26 ms5.6×

커널 시간은 두 모드에서 동일하다. 차이는 100% host-side 복사 에서 나온다.

왜 D2H 만 12.7 배인가 — 페이지 fault

H2D 는 유저가 init 루프에서 이미 touch 한 페이지를 읽기만 한다. Fault 없음. 그래서 2.7 배.

D2H 는 반대다. new float[n] 은 가상 주소만 할당하고 물리 페이지를 커밋하지 않는다. 드라이버가 staging → pageable 로 CPU memcpy 할 때 매 페이지에 demand-zero fault 가 발생. 1 GB 버퍼면 약 262k 페이지 fault.

pageable 이 어쩔 수 없이 강제될 때도, output buffer 는 미리 touch 해 두라. memset 한 번이면 D2H 가 수 배 빨라진다.

T4 는 pinned 일 때 PCIe Gen3 실효 상한에 닿는다

H2D 12.3, D2H 13.1 GB/s. Gen3 x16 이론 16 GB/s, 실효 ~13 GB/s. 즉 더 짜낼 여지가 없다. 다음 레버는 세 가지다.

vLLM 이 KV cache 를 GPU 에 붙박이로 두는 이유, operator fusion 이 이득이 큰 이유의 배경이 여기 있다.

작은 n 은 다른 세계다

n ≤ 2¹⁸ 구간에서는 커널이 launch overhead floor (~4–7 µs) 에 눌린다. "bandwidth %" 개념 자체가 의미 없다. n = 2¹⁸ 에선 apparent bandwidth 가 이론치의 140% — L2 cache hit 때문의 허위 대역폭. 실제 HBM-bound 로 넘어가는 crossover 는 약 n ≈ 2²⁰ (4 MB).

구조적 한 줄

Memory-bound 워크로드에서 가장 큰 레버는 kernel 이 아니라 data path 다. 커널이 이론 대역폭의 70% 를 찍고 있어도 host 쪽을 pageable 로 두면 end-to-end 는 5 배 느려진다.