深入解析IA32_HWP_REQUEST(MSR 0x774):从P-state到硬件调频的实战指南

发布时间:2026/9/8 15:33:48

深入解析IA32_HWP_REQUEST(MSR 0x774):从P-state到硬件调频的实战指南 给一台双路服务器做功耗压测时我碰到过一件怪事CPU使用率已经压满了核心理论频率却一直不肯顶满风扇转速跟着温度曲线走整机功耗毛刺怎么压都压不平。查到最后问题出在操作系统和硬件对“频率由谁说了算”的理解上——我一直在用传统P-state的写法操作一台已经开启了HWPHardware P-State的机器。后来把目光落到MSR 0x774上所有东西才串起来。这个0x774正式名称是IA32_HWP_REQUEST是Intel HWP机制里最核心的软件接口作用域精确到逻辑处理器。它不是让软件命令CPU“现在就跑到某个频率”而是让软件表达“我希望你跑到什么程度”最终决定权在硬件。做固件、内核、虚拟化以及服务器调优的朋友最终都要跟这个寄存器打交道。这篇想把它掰开揉碎讲一遍位字段含义、作用域、和相邻MSR怎么配合、实际读写和调优时有哪些坑。1. 为什么需要IA32_HWP_REQUEST传统P-state模式的“命令式调频”走不通了1.1 传统ACPI P-state是怎么工作的在老方案里CPU频率由OSPM操作系统电源管理说了算。OS根据负载、运行队列、温度等信息选择P0到Pn中的一个性能状态在ACPI _PCT表中找到对应描述然后写入IA32_PERF_CTL0x199。这是典型的“命令式”软件说P0硬件就得跑到P0对应的倍频。这套方案有一套非常成熟的流程CPPCCollaborative Processor Performance Control出现之前ACPI提供了P-state转换接口操作系统按固定的频率表切换。看起来顺理成章但实际用起来问题不少。最大的局限在于操作系统并不知道芯片内部的实时功耗、温度、电流余量。尤其在多核场景下一个核想冲高频但整个物理包的温度已经逼近上限OS还按自己预设的P-state表硬顶结果就是频繁降频、性能抖动。而且每次频率切换都有延迟微秒级的调度负载变化OS根本追不上。打个比方老方案像让一个没看到车道拥堵情况的前台调度员逐个打电话通知司机“你现在可以开120”但前边已经在堵车了。1.2 HWP的“请求-决策”分工HWP的引入把决策下沉到CPU内部。硬件每毫秒级别自动看负载、温度、功耗预算、能效偏好算出一个合适的频率。软件的工作从“定频率”变成“提要求”告诉我你期望的性能等级Desired Performance给我划出上下限Maximum/Minimum告诉我性能和电费哪个更重要EPPEnergy Performance Preference这些要求打包成一个32位的值放在IA32_HWP_REQUEST里。硬件看了你的期望结合它自己的实时信息做最终裁决。这也是为什么这个寄存器叫“Request”而不是“Control”。传统P-state里写IA32_PERF_CTL是刚性命令而0x774更像“递交申请材料”。硬件决定最终执行什么样软件只负责表达意图。这套机制在服务器上尤其有价值。多路服务器里同一个物理包内负载分布可能极其不均匀一个核在跑数据库查询另一个核在闲着。OS无法精确判断每个核的功耗余量但硬件能。HWP让硬件用比软件快几个数量级的响应速度去适配这些变化。1.3 标题里14.4.4.1的出处这个编号来自Intel SDMIntel 64 and IA-32 Architectures Software Developer’s Manual第14章Power and Thermal Management14.4节讲的是Hardware-Controlled P-states14.4.4.1这个小节就是专门描述IA32_HWP_REQUEST的。手头有SDM Volume 3的可以翻到那里看官方定义我建议照着我这篇内容配合SDM原文读效果最好。有一点需要从一开始就拎清楚这一小节标题里的“逻辑处理器作用域”是跟后面14.4.4.2小节描述的IA32_HWP_REQUEST_PKG0x775包作用域区分开的。很多人把这俩搞混拿着包级寄存器的示例去改单核或者反过来。我在后面的章节会专门展开作用域的差异。2. 0x774的位字段一个值如何表达“我希望你跑成什么样”2.1 位段总览以下这个表是我根据Intel SDM整理出来的具体每一位的生效情况建议以你手头最新版SDM为最终依据位段字段名宽度访问属性含义63:32Reserved32保留读通常返回0写必须保持读出原值31:24Desired Performance (DP)8RW期望性能等级0x00表示硬件自主23:16Maximum Performance (MaxP)8RW允许的最高性能等级0x00表示无限制15:8Minimum Performance (MinP)8RW允许的最低性能等级0x00表示无限制7:2Energy Performance Preference (EPP)6RW能效偏好值越小越偏性能越大越偏省电1:0Reserved2保留读通常返回0写必须保持读出原值这个结构非常紧凑。一个32位的低半部分实际主要是低32位在使用高32位保留就把软件对硬件的“性能诉求”表达完了。但正因为紧凑字段之间很容易互相干扰。2.2 Desired Performance不是“目标频率”DP字段是8位但不要理解成“频率值”。它只是一个码值对应的是性能等级不是具体的MHz。CPU会通过IA32_HWP_CAPABILITIES0x771向软件汇报一系列性能点最高性能等级、最低性能等级、最高能效等级等。DP写0表示“我不表达期望硬件自己看着办”写一个非零值则表示希望硬件把性能维持在大约这个等级附近。我见过不少人的误区是DP200就是想要2GHz。实际上8位值对应的是一个线性映射实际频率要代入所在平台HWP_CAPABILITIES的范围去换算。不同体质、不同TDP配置的CPU同样的DP码值对应的实际频率可能完全不同。所以做性能调优的时候盯着DP数值没意义要看它映射到的性能等级和实际生效频率。这个字段更接近“偏好”而非“目标”。即使你写了DP180硬件如果发现温度已经快到警戒线实际跑在150也是允许的。它不会像传统P-state那样“抗命”而是去做权衡。2.3 MaxP/MinP是边界不是目标MaxP和MinP的意义在于给硬件划范围。比如你写MinP10、MaxP255意思就是“再怎么节能不能低于最低性能点涡轮再怎么激进也不能超过最高性能点”。如果写0表示“我不限制这个方向”。这里就出现了一个非常反直觉的特性0表示“无限制”而不是“拉到最低”。很多初学者上来把MaxP写成0以为是要硬件别再往上冲结果反而把上限完全敞开硬件放开了跑。这是0x774字段语义跟普通配置寄存器完全不同、最容易踩的坑。在服务器场景最常见的用法是压低MaxP来限制最高睿频。比如某些机房对功耗有硬指标你不想让CPU短时冲到最高睿频引起供电抖动就把MaxP限制到某一档。在笔记本场景则经常抬高MinP保证50ms瞬时负载下处理器别掉到低频去减少卡顿感。2.4 EPP告诉硬件“电费和速度你更在意哪个”EPP字段占位7:2一共6位。数值小代表性能优先数值大代表能效优先。在Linux sysfs里你看到的是0-255的软件语义值比如performance对应0powersave对应255。intel_pstate驱动写入硬件时会做右移处理把8位语义值压缩到6位硬件字段里。自己手动通过wrmsr写EPP时记得先确认CPUID.06H:EAX的bit10是不是1。只有硬件报告支持EPP能力位时这个字段才有效否则写了也白写。这一点在后面专门讲坑。2.5 保留位处理别把0x774当成普通配置项整块覆盖写0x774的时候最忌讳的模式就是直接wrmsr一个写死的常量进去比如不管三七二十一写个0x80。这等于把DP、MaxP、MinP、EPP全部一次性覆盖了还把保留位的原有状态也冲掉了。Intel推荐的做法是read-modify-write先读0x774的旧值把不需要动的位段用掩码保留只改你要改的位段再写回。硬件在实际运行中可能会在保留位或未公开字段上留下状态你整块覆盖掉很容易触发不可预知的行为。我印象很深的一个case有个做BIOS的同事每次想调EPP都直接往0x774写0x80。后来发现处理器行为变得很怪频率经常“不听指挥”。查了半天才发现他每写一次DP、MaxP、MinP就全被清成0了等于把别的字段的意图全丢了。所以能只改一个字段就不要碰其他位这是处理MSR类寄存器的通用纪律。3. “逻辑处理器作用域”到底指什么3.1 三个等级逻辑处理器、核心、包IA32_HWP_REQUEST的作用域是逻辑处理器。超线程开启时一个物理核上有两个逻辑处理器各自有一份独立的0x774可以分别写不同的DP、MaxP、MinP、EPP。这听着很自由但实际使用时要特别小心。核心级别没有单独的HWP_REQUEST寄存器核心内的最终请求是通过硬件协调得到的。包级别则有IA32_HWP_REQUEST_PKG即0x775用来表达对整颗物理包的限制或偏好。三个作用域的关系是底层每个逻辑处理器有自己的请求上层核心/包再叠加仲裁。3.2 同一核两个线程同时请求会发生什么当同一个物理核的两个逻辑处理器各自提交请求时硬件内部会做协调。SDM并没有给一个特别简单的“取交集”公式但工程上最安全的理解是最终执行状态必须同时满足两个逻辑处理器的硬边界。也就是说一个线程设了MaxP上限同核另一个线程哪怕设了MaxP255也跑不上去。我实测过一颗支持超线程的处理器线程0设MaxP100线程1设MaxP255跑多线程负载时该核最高只能到线程0限制对应的等级附近。反过来线程0设MinP200线程1设MinP0结果常驻频率会偏向较高的一侧因为MinP的约束是“不能低于”任何一个线程要求不能太低最终执行频率就得抬高。所以别把0x774理解成“每个线程独立自由”更准确的理解是“每线程独立表达包内统一裁决”。你在做系统调优时如果只改一个线程的0x774另一些线程没有处理最终观察到的频率可能跟你的预期差很远。3.3 0x774和0x775的分工0x775IA32_HWP_REQUEST_PKG提供包级请求可以让软件一次给整包所有逻辑处理器设置默认的MaxP、MinP、EPP等算是一个包内基线值。其作用域是Physical Package而不是单个逻辑处理器。实际工程中功耗封顶场景我喜欢用0x775因为包级限制能真正约束整个物理包。只写0x774的话你得保证包内所有线程都写一遍漏掉一个那个线程就可能把频率带起来。而且就算你写全了不同线程的请求还要经过硬件协调结果不如包级限制那么直接。两者不是互斥关系。可以这样理解0x775是对整个包的“基础约束”0x774是每个逻辑处理器在此基础上做的“个性化覆盖”。硬件仲裁时包级限制通常优先级更高或者取更限制性的那个值。当0x775把MaxP限得很低你单独给某个线程0x774写很高的MaxP也顶不上去。3.4 虚拟化场景下作用域更容易被搞乱在虚拟化环境里CPUID暴露的HWP能力由VMM虚拟机监控器决定。如果VMM用MSR bitmap捕获了0x774guest里的写入会被VMM模拟或忽略如果直接透传guest每个vCPU访问的仍然是同一个物理逻辑处理器上的0x774。这里有个实际风险多个guest如果被调度到同一个物理核的两个超线程上它们对0x774的写入就会互相干扰。比如guest A设置EPP为性能优先guest B设置EPP为节能优先最终硬件执行时会取一个折中结果两边都觉得自己的设置没生效。我见过做多租户IaaS底层的人排查这类问题时一头雾水每个VM里看EPP都是自己设的值但整机功耗变化就是不对劲。根因就是两个guest共用了同一个物理核的超线程0x774的作用域是逻辑处理器不是虚拟处理器。所以做云平台底层时要么用VMM拦截并统一仲裁要么在CPU亲和性上避免这种共核情况否则HWP相关配置会变得不可预测。4. 从读寄存器到改行为手动读写0x774的完整套路4.1 先确认硬件支持HWP在动手写0x774之前先确认CPU支持HWP。方法是问CPUID叶子06HEAX bit71代表支持HWPbit101代表支持EPP。Linux下直接查/proc/cpuinfo的flags看到hwp、hwp_epp这些关键词就说明支持。没有的话先别折腾0x774得先查BIOS里有没有关闭HWP相关选项。不少服务器BIOS里会把HWP能力藏起来因为它依赖特定Power Technology设置。如果你在CPU flags里看不到hwp先进BIOS找找有没有类似Power Performance Tuning或者Hardware P-State Control的开关。有些平台默认开有些默认关跟品牌和固件策略都有关系。4.2 启用HWP先写0x770HWP需要在IA32_PM_ENABLE0x770里先写入1之后0x774的写入请求才会被硬件接受。0x770主要是一个置位性质的寄存器读回的值意义不大关键是确保写进去的是1。如果你在没启用HWP的情况下写0x774多数平台表现为静默忽略也就是“你写了但什么都没发生”。这是排查HWP问题时最容易误判的点寄存器写操作本身没有报错结果调优无效最后定位到是0x770没写。4.3 用msr-tools做一轮实际操作Linux下加载msr内核模块后可以直接读CPU 0逻辑处理器上的0x774modprobe msr rdmsr -p 0 0x774返回值是64位的。硬件复位后常见的中性值类似0x0000000000000080具体以平台为准。记下这个值再按之前的位表拆开看你就能知道当前设置的DP、MaxP、MinP、EPP分别是什么。修改时最稳妥的方式是read-modify-write。下面用Python脚本演示避免Shell里64位掩码造成符号位问题import subprocess def rdmsr(cpu, msr): out subprocess.check_output([rdmsr, -p, str(cpu), hex(msr)]).decode().strip() return int(out, 16) def wrmsr(cpu, msr, val): subprocess.check_call([wrmsr, -p, str(cpu), hex(msr), hex(val)]) cpu 0 msr 0x774 val rdmsr(cpu, msr) val ~(0x3F 2) # 只清EPP位段其它位保持原值 val | (0x00 2) # EPP 0即性能优先 wrmsr(cpu, msr, val)注意代码里我刻意只动了位7:2其他位段完全不碰。很多人图省事直接wrmsr -p 0 0x774 0x80等于把DP、MaxP、MinP、EPP全改了一遍。这不是调优这是埋雷。4.4 用turbostat观察效果改完0x774之后建议用turbostat做A/B验证turbostat --show PkgWatt,Core,Avg_MHz,Busy%,Bzy_MHz --num_iterations 3重点关注Bzy_MHz实际忙时频率和PkgWatt整包功耗。做对比时固定负载、固定温度环境只改一个变量比如只改EPP或者只改MaxP然后看这两个数值怎么变化。我实践下来有个经验单独调EPP对纯计算负载影响不大但对混合负载部分访存、部分计算的能效影响比较明显。而调MaxP的影响是立竿见影的限制多少峰值频率几乎立刻掉下来。所以好多人调了半天EPP觉得没用其实是负载类型不合适不是寄存器不工作。4.5 写之前必须看的CLI细节msr模块与lockdown再提醒一个工程细节很多时候你rdmsr能读但wrmsr写失败或者直接报“Operation not permitted”。这通常跟内核的security_lockdown机制有关。不少主流发行版默认开启lockdown把MSR写操作限制住了。这种情况下要么通过内核启动参数允许要么走intel_pstate驱动暴露的sysfs接口而不是直接裸写MSR。排查顺序建议先rdmsr确认能读再查dmesg | grep -i lockdown看有没有拦截提示最后确认内核模块和调度器是否允许你绑定到指定CPU。5. 实际调优中别踩的坑兼容性、默认值和不可见行为5.1 字段可用性取决于CPU能力位0x774里的字段不是每个平台全都可用。EPP只有在CPUID.06H:EAX的bit10为1时才有效Activity Window这类后来扩展的字段也要看对应微架构是否支持。在老平台或者某些低功耗Atom上直接写EPP可能被忽略也可能被当作保留位处理。你以为自己在调能效实际什么都没变最后得出“HWP不工作”的错误结论。最稳妥的做法是每到一个新平台先读一遍CPUID能力位再写0x774。不同微架构之间HWP寄存器族的实现细节有差异只背一种写法走天下是不行的。5.2 0值语义和默认值0x774多个字段的0值都表示“无限制”或“由硬件决定”这是它跟一般控制寄存器很不一样的地方。DP0表示硬件自主MaxP0表示不设上限MinP0表示不设下限。如果你用脚本工具把整个寄存器写成0实际做的事情是“把控制权全部交还给硬件”而不是“降到最低”。有次我排查一个功耗异常问题发现别人写的自动化脚本在“禁用HWP限制”时直接往0x774写0结果频率不但没降反而比设置之前还高。因为之前至少还有个MaxP限制写成0以后限制全没了。记住把字段清成0不等于“关闭”而是“放开”。5.3 未启用HWP时写入会被忽略前面提过0x770没置位前写0x774通常被硬件忽略。排查问题时先确认HWP使能再确认写值真的发生了。有一个很实用的检查方法写完0x774之后立刻用rdmsr读回来看写入的值是否落在对应位段里。如果写的是自己想要的值但行为没变化那问题多半在硬件仲裁或上层策略而不是寄存器没写进去。5.4 HWP交互项包级请求、RAPL功耗墙、热管理优先级更高0x774不是唯一的裁决者。当0x775包级请求和0x774单线程请求同时存在时硬件仲裁结果更倾向于满足两者交集中的限制。同理RAPL功耗墙和热管理电路是更高优先级的“强制约束”它们的优先级高于HWP请求。做服务器功耗优化时我通常按这个顺序排查先看RAPL那边设的功耗墙再看0x775包级限制最后才动0x774的单线程限制。层级错了一起解决才有效只调最底层往往被上层约束压住。5.5 读0x774看到的值不一定是“当前生效值”这是最容易误导人的一点。你写DP180硬件可能因为热限制实际跑在150。你再读0x774读到的还是你写的180不是150。0x774是“请求侧”寄存器不是“状态侧”寄存器。要看硬件实际做了什么得去看IA32_HWP_STATUS0x773以及性能计数器、频率采样相关的位置。我用turbostat看到实际频率用0x774看到的是意图两者不一致是正常的。我见过有人拿0x774的值去当成实际频率判断散热是否异常整个分析方向都反了。5.6 跨核迁移0x774的设置不跟线程走在OS调度层面还有个细节0x774跟的是逻辑处理器不是线程。线程从一个CPU迁移到另一个CPU原来那个CPU上的设置不会跟着走。多核场景下你单独给CPU3设了MaxP限制线程跑到CPU7上限制就没了。这也是为什么做系统级调优时我倾向于用更上层的接口比如intel_pstate驱动的sysfs属性而不是直接对每个CPU裸写MSR。裸写适合测试和验证适合正式部署的还是要有策略层的封装让设置跟随调度域而不是CPU编号。关于这个寄存器最后说一点我的体会0x774最让人头疼的地方不是位段记不住而是容易把它当成一个“命令”寄存器来用。只要记住它是一个“请求”你的表达方式就会自然变成“给硬件留余地、给限制留边界”整个调优思路也会顺很多。这个标题如果是第一次讲那后续可以继续展开0x775包级请求、0x770/0x771/0x773这几个寄存器之间的配合关系以及它们在ACPI、intel_pstate和固件不同层面各自应该关注什么。寄存器这东西光看文档永远觉得简单真正被频率问题咬过几回之后你才会对作用域和保留位这些细节产生敬畏心。
延伸阅读

更多相关文章

2026/9/8 15:28:48

程序的内存布局和函数的调用过程

这是学习国资社畜的视频之后的整理这是程序的源代码,接下来编译,保护全关。编译之后第一步,运行程序看一眼当运行程序的时候,程序需要先把程序放进内存,程序在内存中的布局是什么样的呢,在gdb中输入vmmap查…

2026/9/8 15:28:48

ponytail:用“技能包”重塑终端工作流

最近在折腾命令行效率工具的时候,我注意到了 ponytail 这个项目。说它是个项目,更准确一点讲,它是一套以“技能包”为粒度的终端工作流管理方案。你只需要在本地执行一行 npx skill add dietrichgebert/ponytail ,就能把分散在…

2026/9/8 15:28:48

opencode上手全指南:安装配置、模型接入、IDE插件与实战技巧

这两年终端里的AI编程助手越来越卷,从Claude Code到Codex再到各种名字都记不全的开源项目,基本是每季度换一波主力。我大概在半年前开始重度使用opencode,最开始只是抱着“再试一个新工具”的心态,结果它到现在还留在我日常工作流…

2026/9/8 16:44:10

彻底解放双手✅PaperXie科研绘图!搞定本科论文所有学术图表

很多同学用PaperXie只知道写作、降重、改格式,却忽略了理工科、社科毕设最刚需的科研绘图功能! 本科论文扣分从来不止文字逻辑!图表混乱、画风花哨、逻辑错位、图片模糊、不会配图,是大批同学被导师反复打回的核心原因。网上找的…

2026/9/8 16:44:10

从抄板到盲埋孔:新手PCB设计进阶之路

1. 学习嵌入式硬件,我为什么建议从抄板下手 大一暑假刚开始碰嵌入式硬件那会儿,我连电阻电容都认不全,拿到一块开发板,第一反应是到处搜教程。后来真正让我开窍的,反而是别人不太看得上的笨办法——抄板。你别一听这两…

2026/9/8 16:39:10

AI Agent技能插件:将自然语言秒变高可读Mermaid流程图

2. 项目的核心机制拆解:到底解决的是什么问题在动手写代码之前,我先后试过三条路线:第一条是在Coze/扣子这类商业化平台里用现成的Agent编排,受限于平台自身的托管环境,换一个Agent框架就全部作废;第二条是…

2026/9/8 7:15:10

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/8 7:15:15

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/8 7:15:10

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/8 0:01:49

踩多轮坑才跑通|OpenClaw 3.1.0 双平台本地 AI 自动化搭建实操实录

🔹 工具简述 OpenClaw 是一款备受开发者与办公人群青睐的开源本地智能工具,凭借离线本地运行、可视化图形面板、全流程自主任务处理三大核心特点,积累了众多忠实用户。与普通对话类 AI 产品不同,它能够直接调用电脑的软硬件操作权…

2026/9/8 0:01:50

拒绝复杂命令行,Hermes Agent 一键包快速解锁智能办公能力

🔍前言 不少想要体验 Hermes Agent 办公能力的使用者,往往会被复杂的环境配置拦住使用脚步。手动下载匹配依赖、反复调整系统目录、处理命令行持续报错、修复权限异常、补全丢失核心文件等一系列操作,对普通使用者而言门槛较高,很…

2026/9/7 16:23:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/7 22:46:00

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/7 22:45:59

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码