有人可以验证以下用于比较和设置的内联汇编代码 gcc 的正确性吗?

发布于 2024-10-11 05:00:19 字数 609 浏览 2 评论 0原文

在我看来,该功能运行良好。我正在尝试为多线程应用程序实现一个计数器。由于计数器值可能超出整数范围,因此我使用 64 位。我不太确定线程安全性,因为这里我们处理的是 64 位数字。

UINT64 get_and_increment(volatile UINT64* dest) {

   UINT64 old_value, new_value;
   bool result = false;
   while(!result)   {
        old_value = *dest;
        new_value = old_value + 1;

        __asm__ volatile    (
                            "lock cmpxchg %3, %1 \n setzb %0"
                            : "=m"(result), "+m" (*dest)
                            : "a" (old_value), "r"(new_value)
                            );
   }
   return old_value;
}

谢苏丹舒克拉

The function as it looks to me is working fine. I am trying to implement a counter for a multi threaded application. As the counter value can be beyond the integer range, I using 64 bit for it. I am not very sure about the thread safety as, here we are dealing with 64 bit numbers.

UINT64 get_and_increment(volatile UINT64* dest) {

   UINT64 old_value, new_value;
   bool result = false;
   while(!result)   {
        old_value = *dest;
        new_value = old_value + 1;

        __asm__ volatile    (
                            "lock cmpxchg %3, %1 \n setzb %0"
                            : "=m"(result), "+m" (*dest)
                            : "a" (old_value), "r"(new_value)
                            );
   }
   return old_value;
}

Thanks

Sudhanshu Shukla

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

落墨 2024-10-18 05:00:19

为什么不使用GCC 内置的原子内在函数

UINT64 get_and_increment(volatile UINT64* dest) {
    UINT64 old_value, new_value;
    do {
        old_value = *dest;
        new_value = old_value + 1;
    } while (!__sync_bool_compare_and_swap(dest, old_value, new_value));
    return old_value;
}

或者甚至

UINT64 get_and_increment(volatile UINT64* dest) {
    return __sync_fetch_and_add(dest, 1);
}

话虽如此,您的程序集无法在 32 位平台上运行(缺少 64 位 lock cmpxchg),并且可以更简单地编写为 lock xadd没有循环,但看起来它可以在 64 位上运行。

Why not use GCC's built-in atomic intrinsics?

UINT64 get_and_increment(volatile UINT64* dest) {
    UINT64 old_value, new_value;
    do {
        old_value = *dest;
        new_value = old_value + 1;
    } while (!__sync_bool_compare_and_swap(dest, old_value, new_value));
    return old_value;
}

Or even

UINT64 get_and_increment(volatile UINT64* dest) {
    return __sync_fetch_and_add(dest, 1);
}

That being said, your assembly won't work on 32-bit platforms (lack of a 64-bit lock cmpxchg), and would be simpler written as lock xadd without a loop, but otherwise looks like it would work on 64-bit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文