InlineAssemblyNote

本文解析了QT源码中智能指针引用计数的原子操作实现,利用ARM的LDREX与STREX指令确保操作的原子性,避免多线程环境下数据竞争。文章详细解释了内联汇编代码的语法与功能,包括输出操作数、输入操作数及操作寄存器列表的作用。

内联汇编笔记

0x01. 内联汇编代码.

template<> template<typename T> inline
bool QBasicAtomicOps<4>::ref(T &q_value) Q_DECL_NOTHROW
{
    T newValue;
    int result;
    asm volatile("0:\n"
                 "ldrex %[newValue], [%[q_value]]\n"
                 "add %[newValue], %[newValue], #1\n"
                 "strex %[result], %[newValue], [%[q_value]]\n"
                 "teq %[result], #0\n"
                 "bne 0b\n"
                 : [newValue] "=&r" (newValue),
                   [result] "=&r" (result),
                   "+m" (q_value)
                 : [q_value] "r" (&q_value)
                 : "cc", "memory");
    return newValue != 0;
}

内联汇编代码如上所示。

上面是QT 源码中智能指针,累加引用计数值的具体实现源码。原理是通过LDREX与STREX 指令产生barrier,进而实现操作的原子操作(更加具体的实现需要深入ARM 体系结构进一步扩展阅读)。

上述代码功能简述:

a. 将q_value中的值加载到变量newValue(这里在实际的汇编模块里将替换为一个通用寄存器);

b. 将newValue中的值+1后存放在newValue中;

c. 将+1后的结果(存放在newValue中)传递给result(该变量将被另外一个通用寄存器所替换);

d. 检测result中的值是否等于0,如果不相等则跳转到ldrex 这句重新执行。

0x02. 内联汇编的语法.

asm ( assembler template            
     : output operands                  /* optional */           
     : input operands                   /* optional */           
     : list of clobbered registers      /* optional */           
    ); 
  • assembler template 汇编语句的模板,模板可以由一条或多条汇编指令构成,每条指令由双引号包裹,并显式地将换行符(’\n’)添加到指令的末尾;

  • : output operands 输出操作数;

    输出操作数列表中,各个操作数之间由‘,’分隔:

    : [newValue] "=&r" (newValue), [result] "=&r" (result), “+m” (_q_value)

    在上例中,一共有三个输出操作数:

    [newValue] "=&r" (newValue)[result] "=&r" (result) 以及 "+m" (_q_value)

    其中 [ ]内指示汇编代码中出现的符号,( ) 中对应C 中对应的变量或表达式。

    =&r: 标识,当前参数仅通过通用寄存器方式输出。

    +m: 标识,该操作数可读可写,是一个任意有效的变量(不影响任何寄存器值)。

  • : input operands 输入操作数;

    ​ 输入操作数列表中,各个操作数之间由‘,’分隔:

    : [_q_value] "r" (&_q_value)

    ​ 在上例中,一共有一个输入操作数:

    ​ 其中 [ ]内指示汇编代码中出现的符号,( ) 中对应C 中对应的变量或表达式。

    "r": 标识,当前输入操作数将使用通用寄存器传递变量值。

  • :list of clobbered registers 操作寄存器的列表,以及特殊指示标识列表。用于指示语句内指定绑定的寄存器列表或者指示一些特殊的提示信息状态,提供给编译。

    : "cc", "memory"

    “cc”:标识当前的汇编代码段的执行结果将对CPU状态寄存器产生影响(该段汇编中使用加法指令add,该指令将产生进位位等,进而影响到CPU状态寄存器。)。需要显式标识,告知编译器,当该段代码执行返回后,编译器需要负责清理并恢复该寄存器。(寄存器的具体名称根据不同CPU体系而变化。)

    “memory”:用于指示编译器,当前句块内的操作将影响内存内容。比如输出表达式,[newValue] "=&r" (newValue) 表示汇编语言中的名为newValue的变量中的值将通过一个通用寄存器返回给C模块中的变量newValue。而上述操作将修改对应堆栈上的变量内容,同时该操作也修改了所指定的通用寄存器的值。

代码下载地址: https://pan.quark.cn/s/61e7403383a7 中文 | English One Hub 本项目是基于one-api二次开发而来的 请不要和原版混用,因为新增功能,数据库与原版不兼容 为了更加简洁,本项目之后,除了新增供应商时会更新程序自带的模型列表,平常不再更新程序自带的模型列表。 如果发现缺少新模型,请在中更新新增的模型 演示网站 文档 [!WARNING] 本项目为个人学习使用,不保证稳定性,且不提供任何技术支持,使用者必须在遵循 OpenAI 的使用条款以及法律法规的情况下使用,不得用于非法用途。 根据《生成式人工智能服务管理暂行办法》的要求,请勿对中国地区公众提供一切未经备案的生成式人工智能服务。 功能变化 全新的 UI 界面 新增用户仪表盘 新增管理员分析数据统计界面 重构了中转模块 支持使用模拟功能 渠道可配置单独的 http/socks5 代理 支持动态返回用户模型列表 支持自定义测速模型 日志增加请求耗时 支持和优化非 OpenAI 模型的函数调用(支持的模型可以在 lobe-chat 直接使用) 支持完成倍率自定义 支持完整的分页和排序 支持 支持模型按次收费 支持模型通配符 支持使用配置文件启动程序 支持模型价格更新 支持自动获取供应商模型 支持仅聊天,开启后如果有传入参数会跳过该渠道 支持支付 支持配置用户组 RPM 支持监控 支持状态监控(通过环境变量或者配置文件开启) 支持用户分组自动升级 支持用户月度账单生成(通过环境变量或者配置文件开启) 支持多策略(,,)模型价格自动更新(通过环境变量或者配置文件开启) 支持、格式API请求(详见文档) 支持登录(前往页面注册Webauthn登陆凭证即可) ...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值