확장성 있고 휴대 가능하며 메모리 효율적인 락프리 FIFO 큐

읽는 시간: 5 분
...

📝 원문 정보

  • Title: A Scalable, Portable, and Memory-Efficient Lock-Free FIFO Queue
  • ArXiv ID: 1908.04511
  • 발행일: 2019-08-14
  • 저자: Ruslan Nikolaev

📝 초록 (Abstract)

이 논문에서는 기존의 고성능 큐들과 달리 매우 메모리 효율적인 새로운 락프리(multi-producer multi-consumer, MPMC) FIFO 큐 설계를 제시합니다. 이 설계는 확장성이 있으며 ABA 안전성(ABA safety)을 갖추고 있어 외부 메모리 할당자 또는 안전한 메모리 재할당 기법이 필요하지 않습니다. 실제로 이 큐 자체가 데이터 풀(data pool)에 사용될 수 있습니다. 가장 경쟁이 심한 핫스팟에서 FAA(fetch-and-add) 명령을 사용하여 더 확장성이 있는 CAS(compare-and-set) 명령보다 성능이 높아집니다. 그러나 전작들과 달리 이 큐는 락프리(lock-free)와 선형화(linearizable) 모두를 갖추고 있습니다. 또한, 제안된 접근법인 SCQ는 유계 큐(bounded queues)에 대한 것으로, 이를 쉽게 확장하여 임의 개수의 요소를 저장할 수 있는 무한 큐(unbounded FIFO queues)도 지원할 수 있습니다. SCQ는 거의 모든 기존 아키텍처에서 포팅 가능하고 다양한 용도에 충분히 유연합니다. x86-64와 PowerPC 아키텍처에서 알고리즘의 성능을 측정했습니다. 평가 결과, 이 큐는 다른 알고리즘들보다 뛰어난 메모리 효율성을 가지고 있으며, 성능은 종종 최신의 확장성 있는 알고리즘들과 맞먹거나 그 이상입니다.

💡 논문 핵심 해설 (Deep Analysis)

This paper introduces a new scalable and memory-efficient lock-free FIFO queue design called SCQ (Scalable Circular Queue). The primary focus is to address the issue of balancing high performance with low memory usage in queue designs. Traditional solutions often compromise on either memory efficiency or full compliance with both lock-freedom and linearizability, leading to suboptimal systems.

SCQ leverages FAA (fetch-and-add) instructions at hot spots for higher scalability compared to CAS (compare-and-set). It achieves ABA safety without requiring external memory allocators or safe memory reclamation techniques. The design is portable across various CPU architectures, making it a versatile solution suitable for many applications.

The key achievement of SCQ lies in its exceptional memory efficiency and high performance, often surpassing state-of-the-art scalable algorithms. Experimental evaluations demonstrate that SCQ uses significantly less memory compared to other designs like LCRQ while maintaining competitive throughput rates.

This research is significant as it provides a robust solution for developing efficient and scalable systems across different architectures, particularly benefiting applications with stringent memory management requirements such as data pools.

📄 논문 본문 발췌 (Translation)

# 배경

락프리 알고리즘

우리는 하나의 스레드가 유한한 단계 내에 진행할 수 있는 경우를 lock-free라고 정의합니다. 즉, 개별 스레드는 멈출 수 있지만, 프리임(preempted)된 스레드가 다른 스레드의 진행을 차단하지 않습니다. 반면, 스핀 락(암시적 또는 명시적)은 해당 스레드가 예약된 경우 다른 스레드의 추가 진행을 방지합니다.

원자 프리미티브

대부분의 락프리 알고리즘에서 CAS(compare-and-set)가 사용됩니다. 그러나 CAS의 한 가지 단점은 많은 경쟁 상황에서 실패할 수 있다는 것입니다. FAA(fetch-and-add)와 SWAP과 같은 전문화된 명령어는 직접적으로 메모리 경쟁을 줄이지 않지만, 하드웨어에서 더 효율적으로 구현되고 실패하지 않습니다. FAA 및 SWAP은 현재 x86-64, ARMv8.1+ 및 RISC-V에서 구현되어 있습니다.

안전한 메모리 재할당(Safe Memory Reclamation)

대부분의 비트리ivial한 락프리 알고리즘, 특히 큐에는 특별한 처리가 필요합니다. 동시 스레드가 변경된 락프리 데이터 구조에 대한 포인터를 참조하는 동안 해제해야 하는 메모리 블록을 접근할 수 있기 때문입니다. C/C++과 같은 언어에서는 무관리 코드(unmanaged code)가 일반적으로 사용되며, lock-free safe memory reclamation 기법은 이러한 상황에서 사용됩니다. 주요 고수준 아이디어는 각 액세스된 포인터가 해당 API 호출에 의해 보호받아야 한다는 것입니다. 작업이 완료되면 스레드의 포인터 예약을 재설정할 수 있습니다. 메모리 블록이 안전하게 OS로 반환될 수 있을 때까지 safe memory reclamation은 메모리 할당을 트리거합니다.

무한 배열 큐

Figures [alg:infring1]은 LCRQ 설계에 처음으로 설명된 무한 배열 큐를 보여줍니다. 이 큐는 라이브락(livelock)에 취약하지만, 우리의 무한 배열 큐 및 SCQ 설계는 이를 통해 영감을 받았습니다. 초기에는 모든 항목이 특수 값 $`\bot`$로 설정된 상태에서 큐가 비어 있습니다. enqueue는 FAA를 사용하여 새로운 항목을 배치할 수 있는 슬롯을 검색합니다. 이전 값이 $`\bot`$가 아닌 경우, 어떤 dequeuer가 이미 해당 슬롯을 수정했기 때문에 이 enqueuer는 다음 슬롯으로 이동합니다. dequeue는 FAA를 사용하여 프로듀서가 생성한 항목이 포함된 슬롯을 검색합니다. dequeuer는 $`\top`$라는 특수 값을 삽입하여 해당 슬롯이 더 이상 사용할 수 없다는 것을 나타냅니다. 이전 값이 $`\bot`$가 아닌 경우, 대응 enqueuer는 이미 항목을 생성했기 때문에 이를 가져옵니다. 그렇지 않으면 dequeuer는 다음 슬롯으로 이동합니다.

평가

본 섹션에서는 SCQ 설계를 잘 알려진 또는 최신 알고리즘들과 비교하여 평가합니다. [alg:infring1]에서 구현한 여러 알고리즘을 사용하고 확장했습니다.

평가에서, 우리는 SCQ가 다른 고성능 알고리즘의 제약 조건(즉, 라이브락 해결책, 메모리 재할당 및 포팅) 없이 매우 높은 성능을 달성하며, 특히 LCRQ와 같은 최신 접근법들이 매우 높은 메모리 사용량을 가질 수 있다는 문제를 SCQ는 해결하지 않는다는 것을 보여줍니다.

SCQP는 임의의 포인터(Scalable Circular Queue with Pointers)를 저장하는 버전입니다. SCQ 요소가 반드시 포인터가 아닌 모든 유형일 수 있기 때문에 순수한 SCQ가 관련성이 있습니다. 우리는 SCQ 및 SCQP를 M&S FIFO 락프리 큐(MSQUEUE), 조합 큐(CCQUEUE) - 이는 락프리 큐가 아니지만 좋은 성능이 알려져 있으며, CRQ(링 버퍼의 락프리 리스트를 유지하는 큐)와 비교합니다. 이러한 알고리즘은 잘 알려진 또는 확장성 측면에서 최신 접근법을 대표하므로 합당한 기준입니다. 또한 NCQ를 추가 기준으로 제공합니다. NCQ는 SCQ와 동일한 데이터 구조를 사용하지만, 락프리 및 선형화를 모두 만족하는 큐 설계가 필요합니다.

실험

x86-64 및 ARM64 아키텍처에서의 SCQP

x86-64와 ARM64는 두 개의 연속된 단어를 원자적으로 업데이트하는 더블 브로드 CAS(double-width CAS)를 구현합니다. 이를 사용하여 indirection 없이 임의 포인터를 저장할 수 있는 SCQ를 구축할 수 있습니다.

이 버전의 SCQP는 동일한 API와 호환되므로, 더블 브로드 CAS가 없는 아키텍처에서도 동일한 큐를 구현할 수 있습니다. enqueueenqueue_ptr, 그리고 dequeuedequeue_ptr으로 변경됩니다.

만약 enqueue_ptr이 완전한 큐를 식별해야 한다면 추가적인 변경 사항이 필요합니다. Figure [alg:dcas]에서 제시된 방법은 Tail 값을 비교하는 것입니다. 이 비교는 완화되어 $`k`$($`k ≤ n`$)개의 동시 enqueuer가 Tail을 무작위로 증가시키기 때문에, Tail이 이제 Head보다 최대 $`3n`$ 슬롯 앞에 있을 수 있습니다. 우리는 이전에 이를 $`2n`$으로 가정했기 때문에 임계값을 $`4n-1`$으로 늘립니다. 이 방법은 정확하지 않으며, 적어도 $`n`$개의 요소가 큐에 있다는 것을 보장할 수 있지만 실제 개수는 변동합니다. 특히 무한 큐를 생성하는 경우(Section [sec:unbounded]), 완전한 큐를 finalizing하는 데 이 방법이 편리합니다.

Reference

이 글은 ArXiv의 공개 자료를 바탕으로 AI가 자동 번역 및 요약한 내용입니다. 저작권은 원저자에게 있으며, 인류 지식 발전에 기여한 연구자분들께 감사드립니다.

검색 시작

검색어를 입력하세요

↑↓
ESC
⌘K 단축키