You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在32位系统上无临界区实现64位变量的原子自增

解决32位系统上64位变量原子自增的无临界区方案

这确实是32位系统处理64位原子操作的典型痛点——硬件原生只支持4字节的无锁原子操作,所以编译器会自动 fallback 到基于软件锁的实现,也就出现了你看到的性能警告。如果不想用显式临界区(比如mutex这类),可以试试下面几种更高效的方案:

1. 手动拆分64位变量为两个32位原子变量

把64位计数器拆分为高位和低位两个32位原子变量,手动处理进位逻辑,完全依赖原生32位原子操作实现无锁自增:

#include <stdatomic.h>
#include <stdint.h>

atomic_uint32_t tick_counter_low = ATOMIC_VAR_INIT(0);
atomic_uint32_t tick_counter_high = ATOMIC_VAR_INIT(0);

void atomic_inc_system_tick() {
    uint32_t old_low = atomic_fetch_add_explicit(&tick_counter_low, 1, memory_order_relaxed);
    // 低位从最大值溢出到0时,给高位加1
    if (old_low == UINT32_MAX) {
        atomic_fetch_add_explicit(&tick_counter_high, 1, memory_order_release);
    }
}

// 读取完整64位值时,要确保高低位状态一致
uint64_t get_system_tick() {
    uint32_t high, low;
    do {
        high = atomic_load_explicit(&tick_counter_high, memory_order_acquire);
        low = atomic_load_explicit(&tick_counter_low, memory_order_relaxed);
        // 循环检查高位是否变化,避免读到中间状态
    } while (atomic_load_explicit(&tick_counter_high, memory_order_acquire) != high);
    return ((uint64_t)high << 32) | low;
}

这种方案完全基于标准C原子操作,移植性强,性能和原生32位原子操作接近,唯一的额外开销是进位检查和读取时的循环验证。

2. 利用平台/编译器内置的64位原子函数

如果你的目标平台是x86 32位系统,GCC/Clang提供了内置函数__sync_fetch_and_add_8,它会生成硬件支持的lock cmpxchg8b指令——这是x86硬件原生支持的64位原子操作,比软件锁的性能好很多:

#include <stdint.h>

uint64_t system_tick_counter_us = 0;

void atomic_inc_system_tick() {
    __sync_fetch_and_add(&system_tick_counter_us, 1);
}

注意:这是编译器特定的扩展,移植性不如标准原子操作,但胜在实现简单、性能比CAS循环好。

3. 用标准CAS操作模拟原子自增

利用C标准库的atomic_compare_exchange_weak做循环CAS,这是跨平台的无锁实现方式:

#include <stdatomic.h>
#include <stdint.h>

atomic_uint64_t system_tick_counter_us = ATOMIC_VAR_INIT(0);

void atomic_inc_system_tick() {
    uint64_t old_val = atomic_load_explicit(&system_tick_counter_us, memory_order_relaxed);
    // 循环尝试CAS,直到成功
    while (!atomic_compare_exchange_weak_explicit(
        &system_tick_counter_us,
        &old_val,
        old_val + 1,
        memory_order_release,
        memory_order_relaxed
    )) {
        // 失败后更新old_val,继续重试
    }
}

这种方案的优势是完全符合C标准,移植性极佳;缺点是在高并发场景下可能会有较多的CAS重试,性能略低于硬件原生的原子操作,但依然比软件临界区高效。

以上三种方案都不需要显式的临界区锁,而是通过硬件原子特性或无锁算法实现了64位变量的原子自增,你可以根据自己的移植性需求和并发场景选择合适的方案。

内容的提问来源于stack exchange,提问作者Priyank Pandya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:25:26