AIFM: High-Performance, Application-Integrated Far Memory


Zhenyuan Ruan, Malte Schwarzkopf, Marcos K. Aguilera, Adam Belay
2020 USENIX Symposium on Operating Systems Design and Implementation

개요

AIFM은 커널에서 관리하는 Transparent한 Linux의 Far memory (Remote memory)관리가 성능 면에서 문제가 있다고 보고, User level runtime을 통해서 Semantic gap을 극복하고 Far memory를 효율적으로 사용하기 위한 C++ Library와 Remote API를 개발하였다. 이를 통해서 대부분의 상황에서 거의 Local memory와 같은 Latency를 가지는 Far memory관리 기법을 개발하였다.

Motivation

Memory는 2020년 컴퓨팅 환경에서 점차 사용하는 용량이 증가하고 있지만, 새로 확장하거나 Runtime에 바꾸기 매우 어려운 매체이다. 이러한 상황에서 Far memory즉 Disaggregated memory system을 효율적으로 관리하는 것의 중요성이 점차 확대되고 있다.

Importance

현재 리눅스는 Far memory 관리를 위해서 Swap시스템을 사용하고 있지만, Swap[1]은 두가지 측면에서 문제가 있다. 첫번째로 Application은 메모리를 Byte단위로 접근하는 것에 반하여 Swap은 Page단위로 일어나기 때문에 불필요한 Memory copy (논문에서는 memory amplification이라고 표현함)이 일어나게 된다. 또한 Swap은 Page fault와 같은 Kernel stack을 타기 때문에, Overhead가 막심하다. 따라서 Swap으로만 메모리를 관리하면 Transparent하기는 하지만 성능면에서 매우 떨어지는 단점이 있었다.

Main Idea

AIFM은 C++ Library로 Flexible하게 관리될 수 있는 User level runtime을 통해서 Application-level object단위로 Far memory관리를 하도록 하였다. 이를 통해서 커널에서 관리하는 Swap과 같은 Page단위의 방식 대비 더 큰 성능을 발휘하였다. 또한 Green-thread와 같은 여러 Optimization을 통해서 Far memory migration에 드는 Overhead를 낮추었다.

Key design of AIFM
Challenge Solution
Semantic gap User-level datastructure library
Kernel overheads from page faults or I/O busy waits Userspace runtime
Pause from memory reclamation Pauseless userspace evacuator
Network BW < DRAM BW Remote agent and prefetch

Design

Remoteable Memory Abstractions
AIFM은 유저 레벨 라이브러리를 제공함으로, 유저가 Far memory관리를 Flexible하게 관리할 수 있도록 하였다. 또한 유저 레벨 라이브러리를 통해서 유저의 Semantic을 이해하는 메모리 관리가 가능하도록 하였다. 이러한 유저 레벨 라이브러리를 통해서 유저는 Remote node에서 Query가 일어나면 어떤 작업을 할 것인지, Migration이 일어나면 어떤 작업을 할 것인지, Hot page는 뭔지와 같은 여러 Semantic hint들을 AIFM 런타임에 제공할 수 있도록 하였다. 이러한 정보를 활용하여 AIFM은 Prefetching, Migration policy와 같은데 사용하여 효율적인 메모리 관리가 가능하게 하였다.
AIFM Runtime
AIFM 런타임은, Green thread와 커널 bypass TCP/IP 네트워크 스택, 그리고 pauseless memory evacuator로 구성된다. 이러한 유저 레벨 런타임은 Context switch overhead가 매우 작고 (User-level thread라서), Optimized된 구현으로 커널을 직접 타는 것 대비 매우 빠른 Latency를 제공하였다. Green thread는 Application thread가 Remote memory에서 page를 가져올때, 다른 Application thread의 작업을 User-level thread를 활용하여서 Context swtich overhead가 거의 없는 상태에서 작동하게 하여, I/O busy wait에 따른 CPU 리소스의 낭비를 없앴다. 또한 Runtime에서 Prefetcher thread가 계속 예측된 접근 패턴을 바탕으로 Prefetching이 일어나도록 하여서 Remote memory에서 migration하는 Latency를 줄였다.
Pauseless Memory Evacuator
Pauseless Garbage Colloector의 아디이어를 빌려와서 AIFM은 Memory pressure가 높아지는 환경에서 Pauseless memory evacuator가 작동하도록 하여서 현재 레퍼런스가 없는 메모리들을 Clock 알고리즘을 통한 우선순위 대로 Far memory node로 전송하였다. 이떄 Evacuator thread와 Native thread가 같은 Scheduling에 대한 Priority가 있으면 곤란함으로, 스케쥴링 알고리즘을 최적화하여 Memory evacuator와 Green thread간의 밸런스를 유지하였다.
Remote Agent
Network bandwidht가 Ram의 bandwidth보다 더 작음으로, 데이터처리의 일부 로직을 리모트 서버에서 작동하도록 Offloading하여서 리모트 서버에서 데이터 스트력처에대한 작업이 일부 끝난뒤 결과를 받을 수 있도록 Data structure 로직을 작성할 수 있도록 하였다. 이러한 작업은 RemDevice라는 C++ Abstraction을 통해서 개발자에게 주어졌다.

Result

AIFM은 벤치마크를 위해서 6개의 데이터 구조를 설계하였으며; Array, Vector, List, Stack, Queue, and Hashtable, 이를 통해서 Far memory disaggregation에 대한 실험을 수행하였다. 실험을 통해서 baseline인 local 메모리 환경대비 얼마나 성능 저하가 오는지, 2020년 State of art가 되는 기법들과는 성능에 대한 이점이 있는지를 분석하였다.

  1. Fastswap과 비교하여 Outperform하는 성능 향상을 보일 수 있었다.
  2. Macro benchmark에서 거의 리눅스 Native와 비슷한 성능 향상을 보일 수 있었다.

Contribution

  1. Far memory management에 대한 로직을 유저 스페이스에 둠으로서 매우 큰 성능 향상을 보일 수 있음을 보임
  2. Green thread와 Pauseless memory evacuator을 통해서 Far memory관리에 드는 Latency를 줄임

Criticize

  1. CXL이 나오고 있는 2023년 기점으로 전통적인 Memory disaggregation을 어떻게 연구해야 할까?
  2. Distributed shared memory가 Cache coherence protocol때문에 Latency가 생긴다고 하는데, CXL과 같은 경우에는 그 Latency가 하드웨어 적으로 구현되어서 Performance에 큰 영향을 주지 않을 것 같다. [2]
  3. Transparent하지 않기 때문에 Application을 Patching해야 한다. 특히 만약 구현체에서 버그가 있을 경우에는, 디버깅이 힘들 것 같다.
  4. User-level thread는 context change overhead가 작은 장점이 있지만, 동시에 커널 시맨틱이 없어서, 스케쥴링이나 시그널 핸들링에 문제가 있기 때문에 현대 리눅스는 대부분 NPTL을 사용한다. 관연 유저 레벨 스레드를 Application을 위해서 사용하는 것이 Valid한 접근법인지를 확신하지 못하겠다.
  5. Prefetcher thread, Memory evacuator가 작동하는 동안의 CPU Resource사용량이 리포트되어 있지 않다. Application의 Memory overhead가 심각해지는 상황의 경우 CPU resource를 많이 먹는 상황이 벌어질 수도 있을 것 같고, 만약 이를 위해서 Prefetcher thread의 Utilization을 줄일 경우, 오히려 메모리 압력이 높아지는 경우 전반적인 시스템의 메모리 성능 저하가 심해질 수도 있을 것이다.

Reference