64 位整数的 cmpxchg 示例

2023-12-07

我在 i686 架构中使用 cmpxchg(比较和交换)进行 32 位比较和交换,如下所示。

(编者注:原来的 32 位示例有错误,但问题不在于它。我相信这个版本是安全的,而且作为奖励,它也可以正确编译 x86-64。另请注意,为此不需要或不建议使用内联汇编;__atomic_compare_exchange_n或年龄较大的__sync_bool_compare_and_swap为。。。工作int32_t or int64_t在 i486 和 x86-64 上。但这个问题是关于使用内联汇编来做的,以防万一你仍然想要这样做。)

// note that this function doesn't return the updated oldVal
static int CAS(int *ptr, int oldVal, int newVal)
{
    unsigned char ret;
    __asm__ __volatile__ (
            "  lock\n"
            "  cmpxchgl %[newval], %[mem]\n"
            "  sete %0\n"
            : "=q" (ret), [mem] "+m" (*ptr), "+a" (oldVal)
            : [newval]"r" (newVal)
            : "memory");    // barrier for compiler reordering around this

    return ret;   // ZF result, 1 on success else 0
}

对于 64 位比较和交换,x86_64 架构的等效项是什么

static int CAS(long *ptr, long oldVal, long newVal)
{
    unsigned char ret;
    // ?
    return ret;
}

The x86_64指令集有cmpxchgq (q对于四字)用于 8 字节(64 位)比较和交换的指令。

还有一个cmpxchg8b该指令适用于 8 字节数量,但设置起来更复杂,需要您使用edx:eax and ecx:ebx而不是更自然的 64 位rax。几乎可以肯定,这种情况存在的原因与 Intel 很早之前就需要 64 位比较和交换操作有关x86_64伴随着。它仍然以 64 位模式存在,但不再是唯一的选择。

但是,正如所说,cmpxchgq对于 64 位代码来说可能是更好的选择。


如果您需要 cmpxchg 一个 16 字节对象,则使用 64 位版本cmpxchg8b is cmpxchg16b。最早的 AMD64 CPU 中缺少它,因此编译器不会为它生成它std::atomic::compare_exchange在 16B 对象上,除非您启用-mcx16(对于海湾合作委员会)。不过,汇编程序会对其进行汇编,但请注意,您的二进制文件无法在最早的 K8 CPU 上运行。 (这仅适用于cmpxchg16b,不cmpxchg8b在 64 位模式下,或cmpxchgq).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

64 位整数的 cmpxchg 示例 的相关文章

随机推荐

  • 如何按一定比例随机选择

    我想以不等的概率在两个选项之间随机选择 例如 当用户按下按钮时 25 的时间会发出声音 A 75 的时间会发出声音 B 我可以手动执行简单的比例 例如 1 4 和 2 4 但我遇到了麻烦比例如 3 5 思考这个问题的一般方法是什么 我的意思
  • 64 位整数的 cmpxchg 示例

    我在 i686 架构中使用 cmpxchg 比较和交换 进行 32 位比较和交换 如下所示 编者注 原来的 32 位示例有错误 但问题不在于它 我相信这个版本是安全的 而且作为奖励 它也可以正确编译 x86 64 另请注意 为此不需要或不建