想象你住在一个大村子里,每个家庭都有自己的方言。有的讲 x86 方言,有的讲 ARM 方言,大家都习惯了向「外国族长」租借语法和词典——每年交授权费,还随时担心人家突然翻脸不借了。于是,村东头的龙家决定自己编一套语法严谨的新方言:LoongArch;村西头的申家则为了超算比武大会,发明了一套更专精的算力方言:SW64。这两套「自主方言」的出现,不只是多了两门语言,而是把「语言主权」牢牢握在自己手里。这篇文章会用方言的故事,带你搞懂 LoongArch 与 SW64 是什么、为什么自主可控如此重要,以及要让几十年的旧软件「改口说新方言」到底有多难。

岗位关联

对 AI 从业者来说,理解国产指令集是评估模型部署硬件、做算子适配与性能调优的底层基本功——AI 跑多快,最终由指令集与工具链共同决定。

目录
  1. 可视化演示
  2. 指令集基础——CPU 的母语
  3. LoongArch 架构——龙芯的新方言
  4. SW64 架构——申威的算力方言
  5. 自主可控——把方言主权握在手里
  6. 生态迁移——让旧软件改口
  7. 软件适配——翻译官与词典工程
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示LoongArch与SW64架构特性对比、32位定长指令编码格式、二进制翻译生态迁移路径,切换模式查看不同维度。

本节配有交互动效(进入视口后自动加载,约 3KB)。

架构对比 LoongArch~2000指令 vs SW64面向HPC LA:LSX/LASX 256b向量,SW:VPU超强向量化 兼容优先vs性能优先,不同设计哲学适配不同场景

指令集基础——CPU 的母语

村里选劳力讲究「听得懂话」。同样一句「把三块砖搬到西墙」,张木匠听得懂,李铁匠却犯迷糊。CPU 也是一样执拗的「劳力」:它天生只认一种指令集语言。这套语言的词汇表里,没有「把砖搬到西墙」这样的高级话,只有最基本的动作——取数、存数、相加、跳转。把软件编译成机器代码,就是把一段复杂意图翻译成劳力能照做的简单口令。

指令集架构简写为 ISA,是 CPU 与软件之间最重要的一份契约。它定义了寄存器数量与宽度、指令格式、寻址方式。RISC 把常用动作精简成等长的短句(例如定长 32 位指令),执行快但每句话信息量小;CISC 则允许复杂长句(如 x86 的变长指令),能一句顶多句,但译码更费劲。国产 LoongArch 与 SW64 都属于 RISC 路线,目标是让「每个动作短、快、可预测」。

评价程序跑得快慢,最常用的模型把 CPU 时间拆成三项乘积:

就好像「搬砖」任务的耗时取决于句数、每句话的长度和语速,LoongArch 与 SW64 的设计本质就是在优化这三项:减少总指令量、压低平均 CPI、提高主频。谁的方言更精炼,谁就能在同样的时间里干更多的活。

Tcpu=I×CPI×tclockT_{cpu}=I\times CPI\times t_{clock}
程序总执行时间可以拆成「总指令数 × 每条指令平均周期数 × 每个时钟周期时长」三块拼图。
  1. 指令总数 I程序运行过程中真正被 CPU 执行完的机器指令条数。同一任务换不同指令集,指令条数往往不一样。
    I=执行完成的指令总条数I = \text{执行完成的指令总条数}
  2. 平均 CPI每条指令平均占用的时钟周期数,受流水线、缓存命中率等影响。
    CPI=总时钟周期数ICPI = \frac{\text{总时钟周期数}}{I}
  3. 时钟周期 t一次时钟振荡的时间,等于主频的倒数。
    tclock=1fclockt_{clock} = \frac{1}{f_{clock}}
  4. 整体组合把三项相乘得到 CPU 的纯执行时间,这是估算性能的第一性公式。
    Tcpu=I×CPI×tclockT_{cpu} = I \times CPI \times t_{clock}

LoongArch 架构——龙芯的新方言

龙家三叔受够了年年向 MIPS 家族缴纳「词典使用费」,索性自己编写一套全新的方言 LoongArch。它不是对 MIPS 的修修补补,而是从零定义语法体系。为了不让村里老伙计们突然失语,三叔还保留了「双语翻译官」,让旧 MIPS 程序在过渡期也能磕磕绊绊地继续运行。

LoongArch 是龙芯中科于 2021 年正式发布的自主指令集,分为 32 位 LA32 与 64 位 LA64 两档。它设计了 32 个通用寄存器,绝大多数指令为定长 32 位,并提供原子操作、虚拟化支持、向量扩展等现代特性。关键的是,它不基于 MIPS 或 RISC-V,而是一套完全自主定义的架构规则——用「自造语法」替代「租借语法」。

LoongArch 的向量扩展 LSX(128 位)与 LASX(256 位)让一条指令能同时处理多个数据,这对矩阵运算、图像处理、AI 推理而言意义重大。向量化的收益可以这样估算:

新方言的「语法」设计得规矩利落,定长指令让译码器像查字典一样快;向量扩展是给方言加的「成语」,一个词顶一串话。三叔这套 LoongArch 方言,既守住了自主的底线,又为旧软件留了一条平移的退路。

Ssimd=1(1−α)+α/VS_{simd}=\frac{1}{(1-\alpha)+\alpha / V}
向量化加速比 = 1 除以「串行时间占比 + 向量部分时间占比/向量宽度」。
  1. 向量化比例 α程序中可被向量化的执行时间占总执行时间的比例,α 越接近 1,说明大部分工作都能批量处理。
    α=向量化代码执行时间总执行时间\alpha = \frac{\text{向量化代码执行时间}}{\text{总执行时间}}
  2. 向量宽度 V单条向量指令能同时操作的数据个数,例如 128 位寄存器可装 4 个 32 位浮点数。
    V=向量寄存器位宽单元素位宽V = \frac{\text{向量寄存器位宽}}{\text{单元素位宽}}
  3. 合并算加速分母越小,加速越大;串行部分 \((1-\alpha)\) 是天花板,α 很低时向量扩展的收益有限。
    Ssimd=1(1−α)+α/VS_{simd}= \frac{1}{(1-\alpha)+\alpha / V}

SW64 架构——申威的算力方言

申氏家族不走兼容老路,他们发明 SW64 方言的初衷非常明确:为了超算比武大会拿名次。会场上的题目都是气象建模、流体力学、蛋白质折叠这类「算力巨兽」,句句都要求庞大的浮点计算和极快的访存。SW64 就是为了这些题目量身定制的专业方言。

SW64 是申威设计的一套 64 位自主指令集,搭载于神威系列超算。它面向高性能计算(HPC),在指令设计上强调高吞吐、高主频、多核互联和访存带宽。与通用 CPU 追求「什么活都能干」不同,SW64 更在意的是「把科学计算干到极致」。它的这种专精,让科研软件在重编译后能发挥出接近硬件的极限性能。

评估一台超算的算力上限,峰值浮点运算速度是最直观的指标:

SW64 像「比武专用暗语」,不追求日常通用,而是在 FLOPS 的赛场上做到最快。当别人还在用通用语言慢慢念题时,申家已经用专属方言把答案算完了。

F=C×f×RF=C\times f\times R
浮点峰值算力 = 核心数 × 主频 × 每周期每核浮点运算次数。
  1. 核心数 C处理器内部能并行计算的物理核心数量,超算系统往往拥有数百万核心。
    C=参与计算的物理核心总数C = \text{参与计算的物理核心总数}
  2. 主频 f每秒时钟周期数,通常以 GHz 为单位,决定每颗核心的「语速」。
    f=处理器主频f = \text{处理器主频}
  3. 每周期浮点运算数 R每个核心一个时钟周期内能完成的浮点加减或乘加(FMA)次数。
    R=每周期每核浮点操作次数R = \text{每周期每核浮点操作次数}
  4. 连乘结果三者相乘得到理论浮点峰值,是超算榜单排名的核心依据。
    F=C×f×RF = C \times f \times R

自主可控——把方言主权握在手里

为什么不能一直借用别人的方言?因为方言的词典和语法书握在别人手里。一家芯片企业使用国外指令集授权,一旦对方停止授权或禁运新架构,产品线就会瞬间断粮。更深远地说,谁掌握了指令集,谁就掌握了这个硬件平台上的所有软件生态规则。

技术封锁的教训并不遥远。近些年多家国内企业在 EDA 工具、芯片 IP、先进工艺上遭遇出口管制,让「自主可控」从口号变成了硬需求。LoongArch 与 SW64 的意义在于:指令集本身完全自主原创,不依赖外部授权,CPU 的「语言版权」握在自己手中。用可控性思维看,自主化率可以这样量化:

自主可控,就是把自己方言的「词典版权」握在自己手里,不让任何人用「停止授权」四个字掐住喉咙。有了原生指令集,CPU 的演进节奏、安全策略、生态规则才真正由自己说了算。

Rself=CselfCself+CimportR_{self} = \frac{C_{self}}{C_{self}+C_{import}}
自主化率 = 自研环节数量 /(自研环节 + 外部依赖环节)数量,衡量系统受制于人的程度。
  1. 自研环节 C_self指令集设计、CPU 微架构、编译工具链、操作系统适配等由自己掌控的环节数。
    Cself=自主可控的技术环节数量C_{self} = \text{自主可控的技术环节数量}
  2. 外部依赖 C_import需要从国外购买授权、进口 IP 核或关键组件的环节数量。
    Cimport=外部授权或进口环节数量C_{import} = \text{外部授权或进口环节数量}
  3. 求比值结果越接近 1,代表整个技术栈受制于人的环节越少。
    Rself=CselfCself+CimportR_{self}=\frac{C_{self}}{C_{self}+C_{import}}

生态迁移——让旧软件改口

新方言再好,若整个村子的账本、话本、招牌都是用旧方言写的,推广起来就是一场大工程。软件生态迁移是国产指令集能否普及最关键的坎——不是造出芯片就完事,而是让芯片「有话可听」。

x86 生态积累了数十年,Windows、Linux、数据库、行业软件……没有哪个能靠换 CPU 自动跑起来。LoongArch 为了承接旧 MIPS 生态,提供了二进制翻译通道;SW64 面对超算负载,则大量依赖源码重编译。迁移的本质是成本的权衡,而衡量「并行优化最多能带来多大收益」的经典工具,就是阿姆达尔定律:

翻译官能力再强,如果一段文献里「必须逐字核对」的串行部分太多,整体翻完的速度就被这段硬骨头卡住。生态迁移也一样:先把程序里最耗时的并行部分优化好,再考虑翻译开销与测试成本,才是务实的迁移路线。

Sall=1(1−p)+p/NS_{all}=\frac{1}{(1-p)+p/N}
整体加速比 = 1 除以「串行时间比例 + 并行时间比例 / 加速倍数」。无论并行部分多快,串行部分都会卡住上限。
  1. 并行比例 p程序中可以并行执行部分的执行时间占比,p 越接近 1,说明程序越「好说话」。
    p=可并行执行时间总执行时间p = \frac{\text{可并行执行时间}}{\text{总执行时间}}
  2. 加速倍数 N并行处理带来的加速倍数,例如从单核扩展到 4 核理想可加速 4 倍。
    N=并行加速倍数N = \text{并行加速倍数}
  3. 组合求值当 N 趋于无穷,加速比仍接近 \(1/(1-p)\),串行部分决定了性能天花板。
    Sall=1(1−p)+p/NS_{all}=\frac{1}{(1-p)+p/N}

软件适配——翻译官与词典工程

把旧方言的软件翻译成新方言,光懂语法不够,还必须有词典、语料库和校对流程——对应到计算世界里,就是编译器工具链、系统库、驱动和二进制翻译器。没有这些「翻译基础设施」,再好的指令集也只能孤芳自赏。

软件适配包含四个关键层面:交叉编译器(GCC/LLVM 后端)、系统库(glibc/musl)、操作系统内核与驱动、性能分析工具。二进制翻译又分静态翻译(先整体翻译再运行)与动态翻译(边运行边翻译,如 QEMU 类模拟器)。翻译后的程序性能,很大程度上取决于访存行为是否高效,因为原程序的内存访问模式映射到新架构后可能变得「话不对路」。

访存性能常用平均访存时间来衡量,命中率模型是理解它的钥匙:

适配工作像给方言编写「双向词典」,谁流畅谁卡顿,最后都要看词典的查询速度和命中率。国产指令集要成功,不仅靠 CPU 设计得好,更靠整套「翻译基础设施」打磨得够顺。

Tavg=H×Thit+(1−H)×TmissT_{avg}=H\times T_{hit}+(1-H)\times T_{miss}
平均访存时间 = 命中率 × 命中延迟 + 未命中率 × 未命中延迟。命中率越高,访存越接近快速缓存的速度。
  1. 命中率 H访存请求在缓存中直接找到数据的比例,H 越高说明翻译后程序的局部性越好。
    H=缓存命中次数总访存次数H = \frac{\text{缓存命中次数}}{\text{总访存次数}}
  2. 命中延迟 T_hit数据在缓存中时一次访存的延迟,通常只要几个时钟周期。
    Thit=缓存命中时的访问延迟T_{hit} = \text{缓存命中时的访问延迟}
  3. 未命中延迟 T_miss数据不在缓存时向内存甚至外存取数的延迟,可能比命中高几十倍。
    Tmiss=缓存未命中时的访问延迟T_{miss} = \text{缓存未命中时的访问延迟}
  4. 加权平均H 越接近 1,平均访存时间越接近 T_hit,软件跑得越流畅。
    Tavg=H×Thit+(1−H)×TmissT_{avg}=H\times T_{hit}+(1-H)\times T_{miss}

AI 应用场景

智能编译器后端调优

阶段:模型驱动的编译优化与自动调参

解决的问题:传统 GCC/LLVM 后端适配 LoongArch 或 SW64 时,指令调度、寄存器分配都依赖工程师手工调优。不同指令集的延迟模型差异大,人工调优周期长且难覆盖全部指令组合。AI 可以从程序特征出发,预测最优调度策略,自动搜索编译器优化参数。

具体案例:某团队在 LLVM 的 LoongArch 后端上引入强化学习调度器:将程序中间表示(IR)的指令序列编码成图,用图神经网络预测「哪种调度方案使流水线停顿最少」,再结合测量反馈持续迭代。实验显示,该方案在矩阵乘法核上比默认调度提升约 12% 性能。

二进制翻译热段智能识别

阶段:程序特征提取、序列建模、热段标注

解决的问题:把 x86 或 MIPS 程序翻译到 LoongArch 时,动态翻译开销巨大,全部指令均匀优化不划算。传统做法靠程序员人工找热点。AI 能根据指令流频次、循环特征与调用关系,预测哪些片段是「热段」,优先做高质量翻译优化,冷段则用低成本翻译即可。

具体案例:某个二进制翻译项目用 LSTM 对历史指令流序列建模,预测下一条指令被高频重复执行的概率。当模型置信度超过阈值时,触发即时编译(JIT)优化;否则走解释执行。该方案将翻译启动时间缩短 40%,同时保持整体运行性能不下降。

Python 演示

python41 行
def parse_mix(text):    """解析指令类型及占比,例如 'ALU:60,LD:25,BR:10,OTHER:5'。"""    mix = {}    for item in text.split(","):        key, value = item.split(":")        mix[key.strip()] = int(value.strip())    return mix def average_cpi(mix, cpi_table):    """根据指令混合比例计算平均 CPI。"""    total = sum(mix.values())    return sum(mix[k] * cpi_table[k] for k in mix) / total def translated_penalty(src_mix, src_cpi, dst_cpi):    """通过 CPI 比例评估从原架构翻译到目标架构的性能惩罚。"""    src_avg = average_cpi(src_mix, src_cpi)    dst_avg = average_cpi(src_mix, dst_cpi)    return dst_avg / src_avg def migration_speedup(parallel_ratio, vector_speedup, code_penalty):    """迁移后整体加速比,基于阿姆达尔定律。"""    t_serial = (1 - parallel_ratio) * code_penalty    t_parallel = parallel_ratio / vector_speedup    return 1.0 / (t_serial + t_parallel) def main():    mix = parse_mix("ALU:60,LD:25,BR:10,OTHER:5")    cpi_la = {"ALU": 0.8, "LD": 1.1, "BR": 2.0, "OTHER": 1.4}    cpi_sw = {"ALU": 0.9, "LD": 1.0, "BR": 1.8, "OTHER": 1.2}     print("LoongArch 平均 CPI: %.2f" % average_cpi(mix, cpi_la))    print("SW64 平均 CPI: %.2f" % average_cpi(mix, cpi_sw))    penalty = translated_penalty(mix, cpi_la, cpi_sw)    print("从 LoongArch 迁移到 SW64 的 CPI 惩罚系数: %.2f" % penalty)     for ratio in (0.6, 0.8, 0.95):        speedup = migration_speedup(ratio, 4.0, penalty)        print("并行比例 %.0f%%: 总体加速比 %.2f" % (ratio * 100, speedup)) if __name__ == "__main__":    main()
目的:用 CPI 模型估算 LoongArch 与 SW64 的性能差异,再用阿姆达尔定律评估迁移到新指令集后的收益,辅助国产芯片选型决策。
  1. def parse_mix(text)把形如 "ALU:60,LD:25" 的字符串解析成指令类型到占比的字典。
  2. average_cpi(mix, cpi_table)按指令混合比例计算加权平均 CPI,回答了「这套程序平均每条指令花几个周期」。
  3. translated_penalty(src_mix, src_cpi, dst_cpi)用两套 CPI 表计算翻译后性能惩罚系数,大于 1 说明新架构上平均 CPI 更高。
  4. migration_speedup(ratio, 4.0, penalty)调用阿姆达尔公式计算迁移后的整体加速比,把代码惩罚一并纳入。
  5. if __name__ == "__main__":提供可执行入口,直接运行即可看到迁移评估结果。

常见误区

误区一直听说龙芯以前用 MIPS,现在又出了 LoongArch,这应该就是把 MIPS 改个名拿来卖吧?

正解LoongArch 是龙芯完全自主定义的新指令集,从指令格式、寄存器设计到扩展机制都重新设计,并非 MIPS 的修订版。MIPS 兼容只是生态过渡期的「翻译通道」,就像一个人从小讲粤语,后来自己发明了新方言,但还愿意当翻译官帮老伙伴沟通。

为何常见:龙芯早期产品基于 MIPS,教材和旧资料用了很多年 MIPS 术语,大众惯性思维自然把两者划等号。

误区学指令集没用,我又不写汇编,背那几十条指令有什么价值?

正解指令集的价值不在于手写汇编,而在于它是硬件与软件的全部契约。理解 ISA 能帮你读懂编译器生成的代码,判断性能瓶颈在哪,评估 AI 算子能否在该芯片上高效运行。它更像「语言学知识」,而不是「背单词」。

为何常见:大学计算机组成课常以汇编写作为入门实验,让初学者误以为 ISA 的全部就是汇编语法。

误区LoongArch 和 SW64 都是国产的,应该可以拿着同一个程序随便跑吧?

正解不同指令集的二进制完全不通用,就像闽南话和粤语无法直接对话。LoongArch 与 SW64 之间没有设计互相翻译的通道,各自需要独立编译和适配。「国产」是归属标签,不是兼容标准。

为何常见:公众把「国产芯片」视为同一阵营,误以为「同一个国家制造」就等于「用同一套语言」。

误区我有 gcc,把架构参数改一改不就能编译 LoongArch 或 SW64 了吗?

正解GCC/LLVM 虽然都是多后端编译器,但每种指令集需要专门的后端代码生成器、寄存器描述、系统库与链接脚本。gcc 默认不内置 LoongArch/SW64 后端,需要工具链厂商提供完整移植,否则根本无法生成可运行的二进制。

为何常见:开发者日常只用 gcc -O2,看不到编译器内部的巨大工程,以为「编译」是放之四海皆准的通用步骤。

误区只要用了国产自主指令集,芯片就肯定没有后门,绝对安全。

正解自主指令集解决的是「授权断供」与「架构受制于人」的问题,降低供应链风险,但不能自动消除 CPU 微架构层面的漏洞,例如熔断、幽灵这类侧信道问题。自主可控是安全的地基之一,而不是全部。

为何常见:宣传中「自主可控」与「安全可信」常常成对出现,消费者容易把二者理解成因果关系。

面试题

Q1. LoongArch 与 MIPS 的关系是怎样的?

单选题 · easy

  • A.完全相同的指令集
  • B.可实现二进制兼容翻译← 正确答案
  • C.只能使用 MIPS 指令
  • D.完全不兼容任何旧软件

答案:B。LoongArch 是自主设计的新架构,与 MIPS 没有从属关系,但为承接旧生态,通过二进制翻译层兼容部分 MIPS 程序。A 错在把二者等同,C 和 D 走向两个极端,都不符合事实。

Q2. SW64 指令集主要用于哪个领域?

单选题 · easy

  • A.嵌入式低功耗控制
  • B.高性能计算 HPC← 正确答案
  • C.移动端图形渲染
  • D.打印外设通信

答案:B。SW64 是申威面向超算设计的 64 位指令集,目标场景是气象建模、科学计算等高强度运算。嵌入式、移动端和打印机外设都不是它能发挥优势的主场。

Q3. CPU 执行时间的正确表达式是?

单选题 · mid

  • A.I + CPI + f
  • B.I × CPI × t_clock← 正确答案
  • C.I × f / CPI
  • D.CPI / (I × t_clock)

答案:B。CPU 时间 = 指令条数 × 平均 CPI × 时钟周期时长。你可以把它拆成「总话数 × 每句话拍数 × 每拍时长」,三者连乘才对;A、C、D 的乘除关系都违背量纲。

Q4. 国产指令集自主可控的直接收益包括哪些?

多选题 · mid

  • A.降低技术断供风险← 正确答案
  • B.完全免去信息安全测试
  • C.提升供应链可预期性← 正确答案
  • D.代码生态自动大一统

答案:AC。自主指令集让架构授权不依赖国外,降低断供风险并让供应链更可控。但安全测试仍不可少,生态统一也需要长期建设,B 和 D 属于夸大。

Q5. x86 和 LoongArch 的程序能互用同一份二进制吗?

单选题 · easy

  • A.可以,因为体系结构相同
  • B.不可以,指令集不同← 正确答案
  • C.能直接通过网卡翻译
  • D.只要改名就能运行

答案:B。二进制文件由指令编码组成,不同指令集的编码规则完全不同,就像同一个录音不能同时让讲粤语和闽南话的人听懂。必须经过重新编译或翻译器处理。

Q6. 生态迁移中常见的软件适配手段有哪些?

多选题 · mid

  • A.源码重新编译← 正确答案
  • B.二进制翻译执行← 正确答案
  • C.通过超频处理器提速
  • D.运行时系统层模拟← 正确答案

答案:ABD。源码重编译是效率最高的方式,二进制翻译和运行时可执行文件模拟是过渡手段。超频只提高主频、不改变指令集差异,解决不了「语言不通」问题。

Q7. LoongArch 中向量扩展 LSX/LASX 的主要作用是?

单选题 · mid

  • A.让 CPU 更能识别语音
  • B.提升数据并行计算性能← 正确答案
  • C.减少内存容量
  • D.替代所有 IO 协议

答案:B。向量扩展让一条指令同时处理多个数据元素,例如 128 位寄存器一次装 4 个 float,大幅提升数据并行任务的吞吐。它不是为了语音识别、省内存或替代 IO。

Q8. 阿姆达尔定律揭示了什么规律?

单选题 · hard

  • A.加速比与并行比例无关
  • B.加速比受串行部分制约← 正确答案
  • C.并行越多功耗必然下降
  • D.串行比例会随核心数变零

答案:B。加速比上限是 1 除以不可并行比例。即使并行部分无限加速,串行部分仍然占据固定时间,就像文献里必须逐字核对的部分永远无法通过加人手缩短。

Q9. 工具链适配新指令集涉及哪些环节?

多选题 · hard

  • A.编译器后端生成目标代码← 正确答案
  • B.链接器与运行时支持← 正确答案
  • C.操作系统内核与驱动← 正确答案
  • D.芯片对外只卖开发板

答案:ABC。编译器后端把语言翻译成目标指令,链接器和运行时负责拼装与启动程序,内核与驱动则让操作系统认识新芯片。只卖开发板而不构建这些环节,芯片就是块「听不懂话的哑砖」。

Q10. 某程序迁移后平均 CPI 提高 20%,可并行部分占 80% 且向量加速 4 倍,整体加速比约为?

单选题 · extreme

  • A.≈ 0.86
  • B.≈ 1.44
  • C.≈ 2.08← 正确答案
  • D.≈ 4.00

答案:C。设原时间 1,迁移后串行部分 \(0.2\times 1.2=0.24\),并行部分 \(0.8\times 1.2/4=0.24\),总时间 0.48,加速比约 2.08。D 忽视了翻译开销,A、B 计算量纲不对。