>백엔드 개발 >C++ >32비트 원자 변수만 사용하여 64비트 원자 카운터를 구현하는 방법은 무엇입니까?

32비트 원자 변수만 사용하여 64비트 원자 카운터를 구현하는 방법은 무엇입니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-12-11 17:38:19797검색

How to Implement a 64-bit Atomic Counter Using Only 32-bit Atomic Variables?

32비트 원자 변수를 사용하여 64비트 원자 카운터 구현

질문:

32비트 원자를 사용하여 64비트 원자 카운터 설계 및 구현 변수. 카운터에는 단일 작성자(신호 처리기)와 여러 판독기가 있습니다.

코드:

class counter {
    atomic<uint32_t> lo_{};
    atomic<uint32_t> hi_{};
    atomic<uint32_t> gen_{};

    uint64_t read() const {
        auto acquire = memory_order_acquire;
        uint32_t lo, hi, gen1, gen2;
        do {
            gen1 = gen_.load(acquire);
            lo = lo_.load(acquire);
            hi = hi_.load(acquire);
            gen2 = gen_.load(acquire);
        } while (gen1 != gen2 || (gen1 & 1));
        return (uint64_t(hi) << 32) | lo;
    }

    void increment() {
        auto release = memory_order_release;
        gen_.fetch_add(1, release);
        uint32_t newlo = 1 + lo_.fetch_add(1, release);
        if (newlo == 0) {
            hi_.fetch_add(1, release);
        }
        gen_.fetch_add(1, release);
    }
};

답변:

제공된 코드는 32비트 원자 변수를 사용하는 64비트 원자 카운터의 올바른 구현입니다. 이는 생성 카운트를 사용하여 카운터의 상위 및 하위 절반의 일관성을 유지하는 SeqLock이라는 기술을 사용합니다.

읽기 작업은 루프를 사용하여 처리하는 동안 카운터의 올바른 상태를 획득합니다. 독자와 작가 사이의 잠재적인 경쟁 조건. 쓰기 작업은 올바른 동작을 보장하기 위해 메모리 순서를 사용하여 카운터의 높은 부분과 낮은 부분을 원자적으로 증가시킵니다.

향상된 구현:

제공된 코드는 정확하지만 , 더 나은 성능과 효율성을 위해 개선될 수 있습니다.

  • 카운터에 원자 RMW 연산을 사용하는 대신 페이로드의 경우 불필요한 오버헤드를 피하기 위해 일반 로드 및 저장으로 대체할 수 있습니다.
  • 순차 카운터는 원자적으로 업데이트되지 않고 단조 증가만 하면 되므로 일반 로드 및 저장으로 유지 관리할 수도 있습니다.

대체 디자인:

원자 RMW가 필요 없는 대체 디자인 작업 전체는 휘발성 uint64_t와 std::atomic 변하기 쉬운. 휘발성 부분은 값을 읽고 쓰는 데 사용될 수 있는 반면 원자 변수는 시퀀스 카운터를 업데이트하는 데 사용될 수 있습니다. 이 접근 방식은 성능을 최적화하는 동시에 올바른 동작에 필요한 보장을 제공합니다.

위 내용은 32비트 원자 변수만 사용하여 64비트 원자 카운터를 구현하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.