在真实物理服务器里,CPU core 与 hardware thread 是两层概念:一颗物理 core 可以开启 SMT(比如 Intel 的 Hyper-Threading),让同一颗 core 同时挂两条硬件线程。虚拟化诞生以后,云厂商把这条硬件执行“车道”抽象成可分配给虚拟机的调度单位,并给它起了一个实用的名字:vCPU。更直白一点,vCPU 是虚拟化调度器看到的“可运行槽位”,在大多数公有云上,它等价于一条硬件线程;在少数平台或特定机型上,它也可能直接等于一颗物理 core。这不是口号,而是各家公开文档里的明确定义。以 AWS EC2 为例,官方写得很清楚:启用 SMT 的实例每条线程对应一个 vCPU,比如 m5.xlarge 的默认两核二线程会呈现为 4 vCPU。(AWS Documentation)
在 GCP Compute Engine 的术语中,vCPU 也被直接定义为“单个硬件线程”;SMT 让一颗 core 拆出多条线程,于是机器类型里写的 vCPU 数,就是这些线程的计数。(Google Cloud)
vCPU 究竟映射到什么:不同平台的小差异
并不是所有 vCPU 都一模一样。几处常被忽略的差异,恰恰决定了算力、调度行为与费用感知。
-
x86机型上的vCPU大多等于一条超线程
在AWS的Intel/AMD代系里,vCPU对应hyperthread;你看到8 vCPU,常可理解为“4 核 × 2 线程”,物理core大概是vCPU/2。(AWS Documentation) -
ARM机型可能让vCPU= 物理core
AWS Graviton家族的官方指引就明确指出:x86世界里vCPU多是超线程,而在Graviton上,vCPU等同物理core。这意味着相同vCPU数下,Graviton每个vCPU的“专用性”更强。(AWS Documentation) -
Azure的个别代系会把每个vCPU绑定到一整颗物理core
例如基于Azure Cobalt 100的Dpdsv6系列,文档写的是“一颗物理core对应一个vCPU”。此外,Azure还提供constrained vCPU规格,用更少的vCPU去配更大的内存/带宽,以配合按core计费的数据库授权场景。(Microsoft Learn) -
容器世界里的映射规则
在Kubernetes文档里,1 CPU单位被定义为:在云上等于1 vCPU/1 vCore,在带HT的裸金属Intel机器上等于“一条超线程”。同样支持小数与millicore标记(例如100m)。(Kubernetes)
这一层差异解释了为什么你在不同云上选到 8 vCPU 的虚机,跑同一个负载,体验并不完全一致:底层到底是 8 条超线程,还是 8 颗物理 core,答案不同,吞吐与延迟的峰谷自然不同。
vCPU 的本质:调度单位、不是硅片
当你在控制台里创建 8 vCPU 的虚机,真正发生的是:把 8 个可运行的“线程槽位”借给你,由虚拟化调度器把你的 vCPU 们排到宿主机的 pCPU(物理 core 或硬件线程)上。只要宿主机资源允许,很多虚拟化平台会进行合理超配(overcommit):让 vCPU 总数超过底层 pCPU 的总数,以提升整体利用率。VMware vSphere 的官方性能白皮书就写到,在多数环境里,ESXi 允许较显著的 CPU overcommit,只要不让宿主机长期处于饱和,性能并不会显著恶化。(VMware)
近年的实践还强调一个观念:与其死盯 vCPU:pCPU 的固定比例,不如“按争用来开车”,在业务可观测的前提下把主机推向更高密度。(VMware Blogs)
这也衍生出几个工程含义:
-
看到的
vCPU并不保证 100% 专属。当同宿主的其他虚机很忙时,你的vCPU可能会排队,表现为延迟增长或steal time上升。 -
NUMA与拓扑很重要。当一个虚机的vCPU数跨越多个NUMA node时,跨节点内存访问会带来额外开销,很多调优指南都会建议优先选能被单NUMA容纳的规格。(VMware)
vCPU 与计费、许可、配额:为什么你的钱包在乎定义
公有云普遍以 vCPU 作为计费、配额和上限的“自然单位”。两个常见而又容易被忽略的细节:
-
可突发实例的
vCPU与“基线”
AWS T3/T4g这类“可突发通用型”机型不是无限制地让你把所有vCPU打满,它会给定一个按vCPU计的基线利用率,低于基线时攒积分,高于基线时消耗积分,额度用光就会被“拉回”到基线。文档里的例子很直观:t3.large有2 vCPU,每小时积累36个积分,对应30%的基线;t3.nano的两颗vCPU每小时合计6积分,对应5%基线。(AWS Documentation, Amazon Web Services, Inc.)
监控页上还能看到CPUCreditBalance等指标,告诉你积分的赚取与消耗过程,以及Unlimited与Standard两种模式在欠费逻辑上的区别。(AWS Documentation) -
按核授权的软件与“受限
vCPU”规格
比如在Azure,有些constrained vCPU规格把可用vCPU数降到一半或四分之一,以降低像SQL Server这类按核授权软件的许可成本,同时保留原实例的内存与 I/O 吞吐能力。(Microsoft Learn)
如何用工程视角去判断一个 vCPU 的“含金量”
把营销名词撇到一边,落到项目上,判断“每个 vCPU 值多少分”可以从三层做功课:
-
确认平台映射
是“每vCPU= 一条超线程”,还是“每vCPU= 一颗物理core”?AWS的Graviton与部分Azure系列会给你后者;大多数x86云机型是前者。这直接影响vCPU的单核持续吞吐。(AWS Documentation, Microsoft Learn) -
确认调度与超配策略
你的vCPU会不会和很多别的虚机争同一套pCPU?vSphere的文档强调在不饱和的前提下适度超配是常态,但一旦饱和,延迟就会明显上升。对延迟敏感的组件(交易撮合、同步复制、JIT 编译),要尽量选能被单NUMA容纳的规格,必要时考虑主机隔离或CPU pinning。(VMware) -
确认配额/计费模型
是否存在vCPU基线、积分与“突发费用”?是否涉及按核授权?这些都改变了vCPU的“边际价格”。AWS T3的积分基线与Unlimited/Standard行为,是常见的“坑点”。(AWS Documentation)
容器与 vCPU:Kubernetes 的单位换算
当你把工作负载上容器编排平台,Kubernetes 的 1 CPU 就是跨平台的胶水单位:在云上通常等于 1 vCPU/1 vCore;在支持 HT 的裸金属上,等于“一条超线程”。这套定义允许你用 0.5、250m 这类细粒度配额来约束容器的可用算力。(Kubernetes)
一个可运行的小程序:用你的机器感知 vCPU 并测一轮 CPU-bound 标定
下面这段 Python 脚本不依赖第三方库,在 Linux/Windows/macOS 都能跑。它会:
- 读取逻辑处理器数(在虚机里通常等于看到的
vCPU数)。 - 运行一段
CPU-bound的Pi近似计算,用不同并发度(1, N/2, N, 2N)的进程来对比耗时。 - 你会观察到:并发度接近逻辑处理器数时加速最明显;如果超配到
2N,因为进程会“争抢vCPU槽位”,反而可能变慢。
注意:我在代码里统一使用单引号,避免任何英文双引号。
# cpu_bench_vcpu.py
import os, math, time, multiprocessing as mp
def burn(n_terms: int) -> float:
# 计算莱布尼茨公式的圆周率近似,纯 CPU 计算
s = 0.0
for k in range(n_terms):
s += 4.0 * ((-1.0) ** k) / (2 * k + 1)
return s
def run_once(workers: int, terms_per_worker: int) -> float:
t0 = time.time()
with mp.Pool(processes=workers) as pool:
_ = pool.map(burn, [terms_per_worker] * workers)
return time.time() - t0
if __name__ == '__main__':
n_logical = os.cpu_count() or 1 # 在虚机里通常等于看到的 vCPU 数
print(f'检测到的逻辑处理器数: {n_logical}')
tests = [1, max(1, n_logical // 2), n_logical, n_logical * 2]
# 根据机器速度自适应每个 worker 的工作量,目标是单 worker 约 0.2~0.6 秒
probe = 400_000
t = run_once(1, probe)
terms = int(probe * max(0.2, min(0.6, 0.4 / max(t, 1e-3)) / t))
print(f'每个 worker 迭代项估计: {terms}, 单 worker 预估时长: ~{t:.3f}s')
for w in tests:
dt = run_once(w, terms)
print(f'并发进程 {w} 个,用时 {dt:.3f}s')
把它放在任何一台云虚机上跑,都能直观体会 vCPU 的并行上限。如果你在 AWS Graviton 上把 N 设为与 vCPU 相等,常会得到更接近“专属 core”的直线加速;在 x86 两线程的世界里,N = vCPU 的最后 50% 并不总是翻倍收益,因为同一颗物理 core 里的两条超线程会争共享的执行端口与缓存带宽。平台文档关于“vCPU 等于超线程或等于 core”的差异,最终都会在这里体现出来。(AWS Documentation, Google Cloud)
常见误区与工程对策
-
把
vCPU当成“绝对算力”
vCPU是调度单位而不是微架构承诺。遇到吞吐不达标,除了看vCPU数,还要核对SMT、主频、内存带宽与NUMA黏连。vSphere文档的NUMA经验法则值得遵循。(VMware) -
忽视“积分/基线”
在T3/T4g上,短时CPU冲高没问题,长时间打满会被基线“拉回”。部署前先算一遍你的QPS与CPU per request是否需要Unlimited,并监控CPUCreditBalance。(AWS Documentation) -
忽视“许可按核计费”
数据库、商用中间件时常按核授权,Azure的constrained vCPU是给这类场景设计的,配合“高内存/低核数”把账算清。(Microsoft Learn) -
容器资源配额不落地
在Kubernetes里没有设置requests/limits,等于把vCPU抢占权交给谁先跑满谁占多。用1 CPU = 1 vCPU/1 vCore/1 hyperthread的定义做配额,才谈得上稳定的SLO。(Kubernetes)
一段更形式化的“定义”
综合各家权威描述,可以把 vCPU 用一句工程化表述归纳出来:**vCPU 是由虚拟化层对外暴露的“可运行上下文”计量单位,在启用 SMT 的平台上,通常映射为一条硬件线程;在禁用 SMT 或少数专用系列上,可能直接映射为一颗物理 core;在容器编排中,1 CPU 这一单位与上面的 vCPU/核心/超线程 对齐,用以描述可分配的算力份额。**这句话里每个分句都能在官方文档找到影子与佐证。(AWS Documentation, Google Cloud, Microsoft Learn, Kubernetes)
一个可操作的选型与核算清单
想让 vCPU 的钱花得值,不妨照着下面的顺序走:
-
确认映射关系:当前实例系列的
vCPU是否等于超线程?是否有“vCPU= 物理core”的特殊系列可选(如Graviton、Azure Cobalt)?(AWS Documentation, Microsoft Learn) -
确认突发与基线:如果考虑
T3/T4g,基线是多少,Unlimited的溢价与风险能否接受,监控哪些指标?(AWS Documentation) -
确认拓扑契合度:目标
vCPU数是否能落进单NUMA,是否需要绑定或主机隔离来控制抖动?(VMware) -
确认容器侧单位:在
Kubernetes里,按1 CPU = 1 vCPU的语义设置requests/limits,并对延迟敏感服务禁用CPU throttling的副作用。(Kubernetes) -
确认许可与预算:若有按核授权,评估
constrained vCPU是否更经济。(Microsoft Learn)
结语
vCPU 是虚拟化生态里最接地气的抽象之一。它既贴近硬件——在多数学术与厂商口径里,等价于“一条硬件线程”;也足够工程化——被用作云上计费、配额与容量管理的共同语言。理解它到底映射到什么、调度如何发生、计费怎样计算,就能把一串冷冰冰的 8 vCPU/16 vCPU 规格,翻译成你的系统吞吐与尾延迟的现实承诺。
——希望这篇长文与那段小程序,能帮助你把 vCPU 从“参数”变成“认知”。
参考要点与出处:vCPU = 线程 的平台定义(AWS/GCP)(AWS Documentation, Google Cloud);Graviton 与 Azure Cobalt 的“vCPU = 物理 core”特例(AWS Documentation, Microsoft Learn);Kubernetes 的 1 CPU 单位对齐规则(Kubernetes);vSphere 对 overcommit/NUMA 的实践建议(VMware);T3/T4g 的积分与基线模型(AWS Documentation)。









网友评论