CMPXCHG16B 正确吗?

2024-03-19

尽管我不确定为什么,但这似乎并不完全正确。 建议会很好,因为 CMPXCHG16B 的文档非常少(我没有任何英特尔手册......)

template<>
inline bool cas(volatile types::uint128_t *src, types::uint128_t cmp, types::uint128_t with)
{
    /*
    Description:
     The CMPXCHG16B instruction compares the 128-bit value in the RDX:RAX and RCX:RBX registers 
     with a 128-bit memory location. If the values are equal, the zero flag (ZF) is set, 
     and the RCX:RBX value is copied to the memory location. 
     Otherwise, the ZF flag is cleared, and the memory value is copied to RDX:RAX.
     */
    uint64_t * cmpP = (uint64_t*)&cmp;
    uint64_t * withP = (uint64_t*)&with;
    unsigned char result = 0;
    __asm__ __volatile__ (
    "LOCK; CMPXCHG16B %1\n\t"
    "SETZ %b0\n\t"
    : "=q"(result)  /* output */ 
    : "m"(*src), /* input */
      //what to compare against
      "rax"( ((uint64_t) (cmpP[1])) ), //lower bits
      "rdx"( ((uint64_t) (cmpP[0])) ),//upper bits
      //what to replace it with if it was equal
      "rbx"( ((uint64_t) (withP[1])) ), //lower bits
      "rcx"( ((uint64_t) (withP[0]) ) )//upper bits
    : "memory", "cc", "rax", "rdx", "rbx","rcx" /* clobbered items */
    );
    return result;
}

当运行一个例子时,我得到 0,而它应该是 1。有什么想法吗?


注意到几个问题,

(1) 主要问题是约束,“rax”并不像看起来那样,而是第一个字符“r”让 gcc 使用任何寄存器。

(2) 不确定您的存储类型如何::uint128_t,但假设 x86 平台使用标准小端,则高位和低位双字也会交换。

(3) 获取某个地址并将其转换为其他地址可能会违反别名规则。取决于您的 types::uint128_t 的定义方式,这是否是一个问题(如果它是两个 uint64_t 的结构则很好)。假设不违反别名规则,带有 -O2 的 GCC 将进行优化。

(4) *src 实际上应该标记为输出,而不是指定内存破坏器。但这实际上更多的是性能问题而不是正确性问题。类似地,rbx 和 rcx 不需要指定为 clobbered。

这是一个有效的版本,

#include <stdint.h>

namespace types
{
    // alternative: union with  unsigned __int128
    struct uint128_t
    {
        uint64_t lo;
        uint64_t hi;
    }
    __attribute__ (( __aligned__( 16 ) ));
}

template< class T > inline bool cas( volatile T * src, T cmp, T with );

template<> inline bool cas( volatile types::uint128_t * src, types::uint128_t cmp, types::uint128_t with )
{
    // cmp can be by reference so the caller's value is updated on failure.

    // suggestion: use __sync_bool_compare_and_swap and compile with -mcx16 instead of inline asm
    bool result;
    __asm__ __volatile__
    (
        "lock cmpxchg16b %1\n\t"
        "setz %0"       // on gcc6 and later, use a flag output constraint instead
        : "=q" ( result )
        , "+m" ( *src )
        , "+d" ( cmp.hi )
        , "+a" ( cmp.lo )
        : "c" ( with.hi )
        , "b" ( with.lo )
        : "cc", "memory" // compile-time memory barrier.  Omit if you want memory_order_relaxed compile-time ordering.
    );
    return result;
}

int main()
{
    using namespace types;
    uint128_t test = { 0xdecafbad, 0xfeedbeef };
    uint128_t cmp = test;
    uint128_t with = { 0x55555555, 0xaaaaaaaa };
    return ! cas( & test, cmp, with );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CMPXCHG16B 正确吗? 的相关文章

随机推荐

  • 给出分割错误的 2D 矢量

    我正在尝试使用向量创建一个二维数组 我编写了以下代码 int main vector lt vector
  • 无法在 Sitecore 项目上设置工作流程和工作流程状态属性

    我目前正在开发一个项目 需要我设置一个非常简单的 Sitecore 工作流程 在修改现有项目以使用新工作流程时 我遇到了一些困难 这就是我所做的 当内容管理员开始编辑项目时 工作流程会创建一个新版本 并在单击提交按钮时发布该项目 我将这些工
  • 如何(策略)以 BDD 风格对属性(获取/设置)进行单元测试?

    我有一个 很多 类具有属性 有些有逻辑 有些则没有 假设我想测试这些属性 我该怎么做呢 最近 我对用于创建单元测试的 BDD 风格很感兴趣 see here http iridescence no post Extending xUnit
  • ASP.NET 身份 cookie 和子域

    我正在尝试跨子域共享我的 ASP NET Identity cookie 目前只是本地 sub1 domain local 子2 域 本地 我有相同的机器密钥在两个站点上 但在 sub1 上创建的 cookie 不会在 sub2 上验证 反
  • 如何让StatusBar透明?

    有谁知道如何使用 React Native 使 Android 状态栏透明 不是半透明的 是透明的 我也在使用反应导航 就像这样使用它 测试使用 react native 0 60 4 和 0 61 5
  • ASP.NET MVC 列表框处理所选项目事件

    我在视图中使用 HTML ListBox 如下所示 这是用 IEnumerable 填充的
  • Objective-C - 测试对象实例被释放/释放

    有某种方法可以测试 Objective C 实例是否被释放 释放 保留计数 0 例如 对象 A 有一个指向对象 B 的引用 指针 但对象 B 可以在内存低级别中释放 我如何测试引用 B 以确保它已被释放 interface A NSObje
  • Base64 长度(以字节为单位)是多少?

    我有一个以 Base64 编码的文件 具有一定的文件长度 如何获取以字节为单位的大小 Example var size canvas toDataURL console log resizeCanvasURL length gt 13278
  • Android 6.0 原生 tgkill 崩溃

    从今天开始我就遇到了本地崩溃 据报道仅适用于Android 6 0 与堆栈跟踪 native pc 0000000000049c34 system lib libc so tgkill 12 native pc 00000000000474
  • 将 ODBC 应用程序与 JDBC 驱动程序结合使用

    我公司使用Vertica http www vertica com 我们有使用 pyodbc 连接到它的 Python 应用程序 我的大部分开发工作都是在 Mac Snow Leopard 上进行 不幸的是 Vertica 尚未发布适用于
  • 模拟 Retrofit 响应调用,但 Call 不起作用

    我正在嘲笑 APIService 的响应 不幸的是 它不起作用 我必须回电 但我不明白如何做 问题是如何发回 Call 对象 RunWith AndroidJUnit4 class class ApiServiceTest Test fun
  • 如何使用 API Gateway 上传 xls/xlsx 文件并将文件数据发送到 lambda 函数?

    我是 lambda 和 API 网关的新手 我使用此服务做了一些简单的事情 但现在我有一个要求 用户可以上传 Excel 文件 上传过程只是触发与 lambda 函数集成的 API 网关端点 我不想保存文件 我只想将文件数据以 CSV JS
  • 如何检查实体框架类型的属性是否可为 Null

    我有一个从数据库生成的 EntityDataModel 其中一个实体模型有两个属性 它们都是字符串类型 一个是 Nullable True 另一个是 Nullable False 如何在运行时检查 Nullable 属性的值 如果您的属性装
  • 如何从 Swagger API 声明生成 JSON-Schema

    我有 Swagger API 声明 用于使用招摇 v 1 2 https github com wordnik swagger spec blob master versions 1 2 md 我对 Swagger 的最初感觉是它非常接近
  • SQL Server - 同义词提示和技巧? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何在xamarin表单中移动右侧搜索栏的搜索图标

    如何在 Xamarin 表单中移动右侧搜索栏的搜索图标 我正在寻找安卓和IOS 对于 Android 我使用了 SearchBarRenderer 下面的代码不起作用 有人知道该怎么做吗 请帮忙 protected override voi
  • 如何在AngularJS中创建全局变量

    我遇到这个问题 当您注册时 您会进入 用户 页面 它应该说 欢迎 用户名没有出现在网页上 原因我不确定 请帮助这里是plunkr http plnkr co edit qB3Gkeq5ji1YQyy0kpGH p preview http
  • 如何在Python中找到素数

    我是Python新手 我正在尝试计算给定范围内的素数 开发者分享的一些答案如下 import math def count primes num out for i in range 3 num 2 if all i j 0 for j i
  • 如何使用车把模板显示json对象键和值?

    我已经开始学习handlebar js 我正在努力显示 json 数据 我的 json 看起来像这样 var data record1 first name john city newyork name brit
  • CMPXCHG16B 正确吗?

    尽管我不确定为什么 但这似乎并不完全正确 建议会很好 因为 CMPXCHG16B 的文档非常少 我没有任何英特尔手册 template lt gt inline bool cas volatile types uint128 t src t