Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Memory Harvesting in Multi-GPU Systems with Hierarchical Unified Virtual Memory

From noriwiki
Memory Harvesting in Multi-GPU Systems with Hierarchical Unified Virtual Memory
AuthorSangjin Choi, Taeksoo Kim, Jinwoo Jeong, Rachata Ausavarungnirun, Myeongjae Jeon, Youngjin Kwon, Jeongseob Ahn
Conference2022 USENIX Annual Technical Conference (USENIX ATC 22)
Year2022



개요

이 논문은 shared multi-GPU server에서 어떤 GPU는 memory oversubscription으로 host memory를 느리게 쓰는 반면, 다른 GPU에는 작은 idle memory가 남는 imbalance가 왜 발생하며, neighbor GPU의 spare memory를 GPU Unified Virtual Memory 계층에 넣어 이를 어떻게 완화할 수 있는지를 다룬다.

Motivation

GPU 수요가 커지면서 연구실과 산업 환경에서는 multi-GPU server를 여러 job이 공유하는 방식이 일반적이다. DNN training은 batch size를 GPU memory에 거의 맞추어 조정하고, graph analytics는 graph size에 따라 memory demand가 크게 달라진다. 이 때문에 한 서버 안에서도 어떤 GPU는 oversubscription으로 host DRAM을 swap-like backing store로 쓰는 반면, 다른 GPU에는 수백 MB에서 수 GB의 idle memory가 남을 수 있다.

기존 GPU Unified Virtual Memory는 GPU memory보다 큰 working set을 host memory까지 활용해 실행하게 해 주지만, host memory 접근은 PCIe path를 거친다. 논문은 AWS p3.8xlarge의 NVIDIA V100 환경에서 2 MB migration을 측정했을 때 PCIe는 12.3 GB/s, 16.7 us인 반면 NVLink는 40.1 GB/s, 5.1 us로 약 3배 빠르다고 보고한다. 즉 같은 서버 안의 neighbor GPU memory는 host memory보다 작고 동적으로 변하지만, 접근 latency와 bandwidth 면에서는 훨씬 나은 중간 계층이 될 수 있다.

따라서 문제는 단순히 "GPU memory가 부족하다"가 아니라 "multi-GPU server 전체에는 잠시 놀고 있는 GPU memory가 있는데, 기존 UVM은 이를 capacity extension으로 쓰지 못한다"는 점이다. 이 논문은 이 memory fragmentation을 driver-level memory management 문제로 재구성한다.

Importance

이 논문이 중요한 이유는 GPU memory oversubscription을 single-GPU local memory와 host memory 사이의 문제로만 보지 않고, shared multi-GPU server 전체의 memory hierarchy 문제로 확장했기 때문이다. 이전 연구들은 주로 host memory prefetch/pre-eviction, framework-guided tensor swapping, hardware/runtime co-design, memory compression에 초점을 두었다. 반면 이 논문은 commodity multi-GPU server에 이미 존재하는 NVLink/NVSwitch path와 neighbor GPU idle memory를 사용한다.

또한 memHarvester는 spare memory가 충분하지 않아도 유용하다는 점을 보인다. neighbor GPU memory를 모든 evicted data의 최종 거주지로 쓰는 것이 아니라, host access latency를 critical path에서 숨기는 victim cache이자 staging buffer로 사용한다. 이 framing은 이후 ARIADNE: Adaptive UVM Management for Efficient GPU Memory Oversubscription 같은 UVM oversubscription 연구와도 보완적이다. ARIADNE가 VABlock locality와 Zero-copy placement에 집중한다면, 이 논문은 multi-GPU topology와 path diversity를 활용하는 방향을 제시한다.

Background

GPU UVM
GPU Unified Virtual Memory는 GPU와 CPU memory를 하나의 virtual address space로 보이게 하고, page fault를 통해 필요한 page를 GPU memory로 migrate한다. GPU memory가 부족하면 기존 GPU-resident page를 host memory로 evict한 뒤 faulted page를 가져와야 하므로, eviction과 fetch가 page fault critical path에 들어간다.
2 MB chunk
논문 기준 NVIDIA UVM은 GPU physical memory를 2 MB chunk 단위로 관리한다. Page fault 자체는 host architecture의 base page granularity와 연결되지만, eviction은 2 MB chunk 단위로 수행된다. memHarvester는 이 granularity를 유지하면서 neighbor GPU spare chunk를 harvested memory로 표시한다.
Hierarchical Unified Virtual Memory
HUVM은 local GPU memory, neighbor GPU spare memory, host memory로 구성된 hierarchy이다. Local GPU에 free space가 없을 때 바로 host memory로 evict하는 대신, NVLink로 연결된 neighbor GPU spare memory를 먼저 victim buffer로 사용한다.

Challenge

  1. Effective harvesting: neighbor GPU의 idle memory는 작고, spotty하며, workload phase에 따라 변한다. 따라서 spare memory가 전체 overcommitted data를 담지 못해도 성능 이득을 내야 한다.
  2. Minimal interference: harvested memory를 제공하는 yielding GPU도 application을 실행 중이다. Borrowed memory capacity뿐 아니라 NVLink, PCIe, memory bandwidth 사용이 yielding workload를 방해할 수 있다.
  3. Low overhead: UVM은 page fault handling과 page table update 비용을 이미 갖고 있다. HUVM이 추가 metadata와 background work를 넣으면 NVLink/PCIe bandwidth를 충분히 활용하기 전에 software overhead가 병목이 될 수 있다.
  4. Framework-agnostic: shared server의 jobs는 PyTorch DNN training, cuGraph graph analytics처럼 서로 다른 framework를 쓴다. 따라서 solution은 application/framework modification 없이 driver layer에서 동작해야 한다.

Main Idea

Characterization

논문의 관찰은 shared multi-GPU server에서 memory pressure가 GPU별로 균등하지 않다는 것이다. Figure 1의 consolidation scenarios에서는 PageRank, BFS, WCC, Louvain 같은 graph workload가 host memory를 쓰는 동안 VGG16, MobileNet, ResNet101 또는 partitioned PageRank가 실행되는 다른 GPU에는 idle memory가 남는다. 기존 UVM은 이 idle memory를 보지 못하므로 host memory를 느린 backing store로 사용한다.

Optimization

핵심 아이디어는 neighbor GPU의 spare memory를 local GPU와 host memory 사이의 fast victim cache로 추가하는 것이다. Spare memory가 모든 evicted page를 보관할 만큼 크지 않아도, 최근 evicted chunk를 NVLink-attached memory에 잠시 두고 background writeback과 prefetch를 병렬화하면 host memory access latency를 critical path 밖으로 밀어낼 수 있다.

memHarvester는 이 아이디어를 centralized driver-level coordinator로 구현한다. It dynamically harvests spare 2 MB chunks, evicts local GPU chunks to harvested memory, writes them back to host in the background, and reclaims removable chunks quickly when the yielding GPU needs memory again. 즉 harvested memory는 빌린 capacity이면서도 즉시 돌려줄 수 있어야 하는 transient resource이다.

Design

  1. HUVM data path
    Local problem: stock UVM은 local GPU memory가 부족하면 host memory로 evict하고, 이후 재접근 시 PCIe를 통해 fetch한다.
    Mechanism: HUVM은 local GPU, harvested neighbor GPU memory, host memory를 hierarchy로 구성한다. Evicted 2 MB chunks can reside in harvested memory first, and later be copied back to host.
    Why it helps: NVLink path가 PCIe host path보다 빠르므로 eviction latency와 refetch latency를 줄일 수 있다.
    Tradeoff: harvested memory는 yielding GPU의 resource이므로 capacity와 bandwidth가 동적으로 변하고, 다른 harvester와 공유될 수 있다.
  1. Spare memory management and reclamation
    Local problem: yielding GPU가 다시 memory를 필요로 하면 borrowed chunks를 빠르게 반환해야 한다.
    Mechanism: memHarvester는 GPU별 free 2 MB chunk list를 보고 spare memory를 식별한다. Harvested chunk metadata를 표시하고, evicted list와 removable list를 관리한다. Evicted chunk가 host에 background writeback되면 removable로 표시되어 yielding GPU가 fault를 낼 때 먼저 회수된다.
    Why it helps: harvested memory를 "언젠가 돌려줄 cache"가 아니라 "host copy가 준비되면 즉시 회수 가능한 cache"로 만들어 interference를 줄인다.
    Tradeoff: writeback이 완료되기 전에는 해당 chunk를 즉시 회수할 수 없으므로, writeback throughput과 large-page support가 중요하다.
  1. Eviction path optimization
    Local problem: demand fault가 발생한 뒤 eviction을 시작하면 eviction time이 page fault critical path에 들어간다.
    Mechanism: free chunk가 threshold 아래로 내려가면 memHarvester가 pre-eviction thread를 실행한다. Victim은 stock UVM과 같은 LRU 계열 policy로 고르고, target yielding GPU는 round-robin으로 선택한다. Host writeback에는 2 MB large page를 사용해 512개의 4 KB page population을 하나의 2 MB operation으로 줄인다.
    Why it helps: pre-eviction은 future demand fault 전에 free chunk를 확보하고, large page eviction은 host-side writeback과 removable chunk 생성 속도를 높인다.
    Tradeoff: pre-eviction은 잘못된 victim을 미리 내보낼 수 있고, round-robin target selection은 topology-aware optimal policy라기보다 hotspot avoidance에 가까운 heuristic이다.
  1. Parallel fault handling
    Local problem: UVM은 fault batch를 처리하지만, host memory에서 faulted pages를 순차적으로 가져오면 PCIe latency가 남는다.
    Mechanism: memHarvester는 fault batch의 head는 local GPU로, tail은 harvested memory로 처리하는 별도 kernel thread를 둔다. 서로 다른 GPU의 PCIe lane을 병렬로 활용하고, harvested memory에 들어간 page는 이후 NVLink로 local GPU에 들어온다.
    Why it helps: batch 안의 page fetch를 local path와 yielding GPU path로 나누어 host fetch latency 일부를 숨긴다.
    Tradeoff: fault batch coordination에 mutex와 metadata update가 필요하며, harvested memory에 미리 올린 page가 실제로 곧 쓰이지 않으면 이득이 줄어든다.
  1. Multi-path parallel prefetcher
    Local problem: spare memory가 일부 evicted chunks만 담고 있을 때, host memory access를 완전히 피할 수는 없다.
    Mechanism: memHarvester는 page fault history에서 next-line/stride pattern을 추출하고 기본 32 MB를 prefetch한다. Harvested memory에 있는 chunk는 NVLink로 local GPU에 prefetch하고, host memory에 있는 chunk는 active harvester 수와 PCIe congestion에 따라 harvested memory 또는 local GPU로 prefetch한다.
    Why it helps: NVLink와 PCIe path를 동시에 사용하고, host data를 neighbor GPU spare memory에 미리 올려 다음 fault의 source를 host에서 harvested memory로 바꾼다.
    Tradeoff: 여러 harvester가 하나의 yielding GPU를 공유하면 yielding GPU의 PCIe lane이 bottleneck이 될 수 있다. 이 경우 memHarvester는 host-to-local prefetch를 선택해 contention을 피하지만, harvested-memory prefetch 이득은 줄어든다.
  1. Driver-transparent implementation
    Local problem: shared GPU server의 workload는 framework와 application이 다양하므로 user-level rewrite가 어렵다.
    Mechanism: prototype은 NVIDIA UVM driver 460.67 위에 1,838 SLOC의 C code로 구현되었다. PyTorch와 cuGraph workload를 application modification 없이 실행한다.
    Why it helps: UVM driver가 GPU별 page table, residency metadata, fault stream을 볼 수 있으므로 multi-GPU memory movement를 centralized하게 조정할 수 있다.
    Tradeoff: NVIDIA UVM driver 내부 수정이 필요하므로 production deployment는 driver version, kernel memory allocation, GPU topology 지원에 의존한다.

Result

평가는 AWS p3.8xlarge에서 수행되었다. 이 서버는 16 GB NVIDIA V100 GPU 4개, NVSwitch/NVLink 2.0 interconnect, PCIe 3.0으로 연결된 240 GB host memory를 갖는다. Baseline은 stock UVM인 Base와 host memory에 대한 pre-eviction/prefetch prior approach를 모사한 Pre-ef-host이다. Workload는 PyTorch 1.10.1 DNN training과 cuGraph 21.12 graph analytics를 사용한다.

Inter-job harvesting에서는 graph workload가 다른 GPU의 DNN 또는 graph workload가 남긴 spare memory를 사용한다. Case-1에서 PageRank는 VGG16과 WCC가 남긴 총 4.64 GB spare memory를 harvest한다. 이 spare memory는 PageRank의 overcommitted memory 13.92 GB보다 작지만, memHarvester는 Base 대비 3.53배, Pre-ef-host 대비 1.31배 speedup을 보인다. 이는 harvested memory가 전체 overflow를 담지 못해도 host access latency를 숨길 수 있음을 보여준다.

Case-2에서 BFS는 MobileNet과 ResNet101이 실행되는 GPU의 spare memory를 사용해 Base 대비 3.52배, Pre-ef-host 대비 2.1배 빨라진다. 이때 yielding workload의 performance impact는 약 7-9%이다. Case-3에서는 WCC와 BFS가 PageRank가 실행되는 두 GPU의 spare memory를 공유하며, WCC는 Base 대비 3.83배와 Pre-ef-host 대비 2.71배, BFS는 Base 대비 3.21배와 Pre-ef-host 대비 2.67배 speedup을 보인다. 논문이 주장하는 "prior approach 대비 up to 2.71x"는 이 case에서 나온다. Case-4에서는 WCC와 Louvain이 ResNet101이 남긴 4.16 GB spare memory 하나를 공유하며, Base 대비 약 2.1-2.36배, Pre-ef-host 대비 30-40% 개선을 보인다.

Ablation은 각 mechanism이 다른 병목을 줄인다는 점을 뒷받침한다. Harvesting(H)은 NVLink victim cache로 eviction/fetch latency를 줄이고, pre-eviction(PE)은 eviction을 demand fault critical path에서 빼며, large page(LP)는 host writeback을 빠르게 만들어 removable chunk 생성을 촉진한다. Parallel fetch(PLF)는 fault batch 처리 latency를 줄이고, multi-path parallel prefetcher(MPF)는 local-only prefetch보다 큰 이득을 보인다. 다만 Case-4처럼 하나의 yielding GPU에 여러 harvester가 몰리면 MPF는 yielding GPU PCIe contention을 피하기 위해 host-to-local prefetch를 선택하므로 local prefetcher 대비 추가 이득이 작다.

Sensitivity study에서는 2 MB stride와 32 MB prefetch size를 기본값으로 선택한다. Available spare memory를 5%에서 60%까지 바꾸는 실험에서는 5%, 즉 800 MB의 spare memory만 있어도 네 개 graph workload 모두에서 2배 이상 성능 향상이 나온다. 어느 정도 spare memory가 active working set을 수용하면 추가 spare memory를 늘려도 성능은 더 좋아지지 않는다.

Interference 측정에서는 ResNet101이 yielding GPU에서 실행되고 VectorAdd microbenchmark가 harvested memory traffic을 만든다. Harvester가 하나일 때 ResNet101 degradation은 최대 3%로 작지만, 세 harvester가 동시에 접근하면 degradation이 13%까지 커진다. 논문은 이는 memory bandwidth와 NVLink traffic contention 때문이며, throttling은 future work로 남긴다.

Intra-job harvesting에서는 pipeline parallel DNN training처럼 하나의 multi-GPU job 내부에서 GPU별 memory demand가 불균형한 경우를 다룬다. GNMT16과 ResNet50에서는 memHarvester throughput이 Pre-ef-host보다 1.5-1.6배 높다. GNMT8과 VGG16처럼 yielding GPU들의 aggregate spare memory가 충분하지 않은 경우에도 Pre-ef-host 대비 각각 2.16배, 1.24배 throughput improvement를 보인다.

Contribution

  1. Shared multi-GPU server에서 GPU별 memory pressure와 idle memory가 동시에 발생하는 memory imbalance를 DNN training과 graph analytics consolidation scenario로 정량화하였다.
  2. Local GPU memory와 host memory 사이에 neighbor GPU spare memory를 넣는 Hierarchical Unified Virtual Memory(HUVM) abstraction을 제안하였다.
  3. Dynamic spare memory harvesting, background writeback, fast reclamation을 결합해 yielding GPU의 memory를 transient victim cache로 사용하는 memHarvester를 설계하였다.
  4. Pre-eviction, 2 MB large page eviction, parallel fault-batch fetch, multi-path parallel prefetcher를 통해 eviction latency와 fetch latency를 각각 줄였다.
  5. NVIDIA UVM driver 수정만으로 PyTorch와 cuGraph workload에 transparent하게 적용 가능한 prototype을 구현하였다.
  6. Inter-job과 intra-job harvesting 실험을 통해 Base 및 host-only pre-eviction/prefetch baseline 대비 성능 향상과 yielding workload interference를 함께 제시하였다.

Conclusion

이 연구는 GPU memory oversubscription을 단일 GPU의 capacity 부족 문제가 아니라 shared multi-GPU server의 memory fragmentation과 hierarchy design 문제로 바라보게 만든다. HUVM과 memHarvester는 neighbor GPU의 작고 동적인 spare memory를 fast victim cache로 활용하고, eviction/fetch/prefetch path를 병렬화하여 host memory latency를 critical path에서 숨길 수 있음을 보였다. 따라서 이 논문은 GPU UVM, multi-GPU memory management, shared GPU cluster efficiency를 다룰 때 기억할 만한 design point를 제공한다.