观察:
我有一台配备 AMD 双核 CPU (Turion II Neo N40L) 的 HP 服务器,可以将频率从 800 MHz 扩展到 1500 MHz。频率缩放适用于 FreeBSD 9 和具有 Linux 内核 3.5 的 Ubuntu 12.04。然而,当我将 FreeBSD 9 置于 Ubuntu 之上的 KVM 环境中时,频率缩放不起作用。来宾系统(即 FreeBSD)不会检测最小和最大频率,因此当 CPU 占用率变高时不会进行任何调整。在主机(即 Ubuntu)上,KVM 进程使用 80% 到 140% 的 CPU 资源,但没有发生频率缩放,频率保持在 800 MHz,尽管当我在同一个 Ubuntu 机器上运行任何其他进程时,按需调速器很快将频率扩展到 1500 MHz!
关心和问题:
我不明白 CPU 是如何虚拟化的,以及是否由来宾执行适当的扩展。是否需要向来宾公开某些 CPU 功能才能使其正常工作?
附录:
这以下红帽发行说明倾向于建议频率扩展甚至在虚拟化环境中也能工作(参见第 6.2.2 和 6.2.3 章),认为该说明未能解决该技术适用于哪种虚拟化技术(kvm、xen 等?)
有关信息,cpufreq-info
Ubuntu 上的输出为:
$ cpufreq-info
cpufrequtils 007: cpufreq-info (C) Dominik Brodowski 2004-2009
Report errors and bugs to [email protected], please.
analyzing CPU 0:
driver: powernow-k8
CPUs which run at the same hardware frequency: 0
CPUs which need to have their frequency coordinated by software: 0
maximum transition latency: 8.0 us.
hardware limits: 800 MHz - 1.50 GHz
available frequency steps: 1.50 GHz, 1.30 GHz, 1000 MHz, 800 MHz
available cpufreq governors: conservative, ondemand, userspace, powersave, performance
current policy: frequency should be within 800 MHz and 1.50 GHz.
The governor "ondemand" may decide which speed to use
within this range.
current CPU frequency is 800 MHz.
cpufreq stats: 1.50 GHz:14.79%, 1.30 GHz:1.07%, 1000 MHz:0.71%, 800 MHz:83.43% (277433)
analyzing CPU 1:
driver: powernow-k8
CPUs which run at the same hardware frequency: 1
CPUs which need to have their frequency coordinated by software: 1
maximum transition latency: 8.0 us.
hardware limits: 800 MHz - 1.50 GHz
available frequency steps: 1.50 GHz, 1.30 GHz, 1000 MHz, 800 MHz
available cpufreq governors: conservative, ondemand, userspace, powersave, performance
current policy: frequency should be within 800 MHz and 1.50 GHz.
The governor "ondemand" may decide which speed to use
within this range.
current CPU frequency is 800 MHz.
cpufreq stats: 1.50 GHz:14.56%, 1.30 GHz:1.06%, 1000 MHz:0.79%, 800 MHz:83.59% (384089)
我希望此功能发挥作用的原因是:节省能源、运行更安静(不太热)以及简单的好奇心,以更好地理解为什么此功能不起作用以及如何使其发挥作用。
答案1
调整一经请求CPU DVFS 调速器
按需调节器有一组参数可以在启动动态频率调节(或用于动态电压和频率调节的 DVFS)时进行控制。这些参数位于 sysfs 树下:/sys/devices/system/cpu/cpufreq/ondemand/
其中一个参数up_threshold
正如其名称所暗示的那样是一个阈值(单位是 CPU 的百分比,但我还没有弄清楚这是每个核心还是合并核心),高于该阈值时,按需调速器就会启动并开始动态更改频率。
使用 sudo 将其更改为 50%(例如)很简单:
sudo bash -c "echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold"
如果您是 root,则可以使用更简单的命令:
echo 50 > /sys/devices/system/cpu/cpufreq/ondemand/up_threshold
注意:这些更改将在下次主机重新启动后丢失。您应该将它们添加到启动期间读取的配置文件中,就像/etc/init.d/rc.local
在 Ubuntu 上一样。
我发现我的来宾虚拟机虽然在主机上消耗了大量 CPU (80-140%),但却在两个核心上分配负载,因此没有一个核心超过 95%,因此令我恼火的是,CPU保持在 800 MHz。现在,通过上述补丁,CPU 可以更快地动态更改每个核心的频率,这更适合我的需求,50% 似乎是我的访客使用情况的更好阈值,您的里程可能会有所不同。
(可选)验证您是否使用 HPET
某些不正确实现计时器的应用程序可能会受到 DVFS 的影响。这可能是主机和/或来宾环境上的问题,尽管主机可以有一些复杂的算法来尝试最小化这个问题。然而,现代 CPU 有更新的 TSC(时间戳计数器),它们独立于当前的 CPU/核心频率,它们是:常量 (constant_tsc)、不变 (invariant_tsc) 或不间断 (nonstop_tsc),请参阅这篇 Chromium 文章TSC 重新同步有关每个的更多信息。所以如果你的CPU配备了这种TSC之一,你就不需要强制HPET。要验证您的主机 CPU 是否支持它们,请使用类似的命令(将 grep 参数更改为相应的 CPU 功能,这里我们测试常量 TSC):
$ grep constant_tsc /proc/cpuinfo
如果您没有这种现代 TSC,您应该:
- 活性HPET,这将在下文中描述;
- 如果虚拟机中有任何依赖于精确计时的应用程序,则不要使用 CPU DVFS红帽推荐。
一个安全的解决方案是启用 HPET 定时器(更多详细信息请参见下文),它们的查询速度比 TSC 定时器慢(TSC 在 CPU 中,而 HPET 在主板中),并且可能不精确(HPET >10MHz;TSC通常是最大 CPU 时钟),但它们更加可靠,特别是在 DVFS 配置中,其中每个内核可以具有不同的频率。 Linux 足够聪明,可以使用最好的可用定时器,它会首先依赖 TSC,但如果发现太不可靠,它会使用 HPET。这在主机(裸机)系统上运行良好,但由于虚拟机管理程序无法正确导出所有信息,因此对于来宾虚拟机检测行为不良的 TSC 来说更具挑战性。诀窍是强制在来宾中使用 HPET,尽管您需要虚拟机管理程序来使该时钟源可供来宾使用!
您可以在下面找到如何在 Linux 和 FreeBSD 上配置和/或启用 HPET。
Linux HPET 配置
HPET,即高精度事件定时器,是一种硬件定时器,自 2005 年以来,您可以在大多数商用 PC 中找到该定时器。现代操作系统可以有效地使用该定时器(Linux 内核从 2.6 开始支持它,自最新 9.x 以来对 FreeBSD 的稳定支持,但在 6.3 中引入)始终为 CPU 电源管理提供一致的时序。它也允许构建更简单的无滴答调度程序实现。
基本上,HPET 就像一个安全屏障,即使主机启用了 DVFS,主机和访客计时事件也将受到较小的影响。
有一个来自 IBM 的关于启用 HPET 的好文章,它解释了如何验证您的内核正在使用哪个硬件定时器以及哪些硬件定时器可用。我在这里提供一个简短的总结:
检查可用的硬件定时器:
cat /sys/devices/system/clocksource/clocksource0/available_clocksource
检查当前活动计时器:
cat /sys/devices/system/clocksource/clocksource0/current_clocksource
如果您有可用的 HPET,强制使用 HPET 的更简单方法是修改引导加载程序以要求启用它(从内核 2.6.16 开始)。此配置取决于发行版,因此请参阅您自己的发行版文档以正确设置它。您应该在内核引导行上启用hpet=enable
或clocksource=hpet
(这又取决于内核版本或发行版,我没有找到任何一致的信息)。
这可确保访客正在使用 HPET 计时器。
注意:在我的内核 3.5 上,Linux 似乎自动拾取 hpet 计时器。
FreeBSD 来宾 HPET 配置
在 FreeBSD 上,可以通过运行以下命令来检查哪些计时器可用:
sysctl kern.timecounter.choice
当前选择的计时器可以通过以下方式验证:
sysctl kern.timecounter.hardware
FreeBSD 9.1 似乎自动地更喜欢 HPET 而不是其他计时器提供程序。
Todo:如何在 FreeBSD 上强制使用 HPET。
管理程序 HPET 导出
当主机支持 HPET 时,KVM 似乎会自动导出 HPET。然而,对于 Linux 客户机,他们更喜欢另一个自动导出的时钟,即 kvm-clock(主机 TSC 的半虚拟化版本)。有些人报告首选时钟出现问题,您的里程可能会有所不同。如果您想在来宾中强制使用 HPET,请参阅上面的部分。
默认情况下,VirtualBox 不会将 HPET 时钟导出到客户机,并且 GUI 中没有选项可以执行此操作。您需要使用命令行并确保虚拟机已关闭。命令是:
./VBoxManage modifyvm "VM NAME" --hpet on
如果在上述更改后,客户机继续选择 HPET 以外的其他时钟源,请参阅上面的如何强制内核使用 HPET 时钟作为时钟源的部分。
答案2
触发高档的不是客人——主人必须这样做。所以你必须降低主机上相应的触发电平。
答案3
在主机上,一个kvm cpu看起来就像一个进程。缩放机制不观察进程,只观察总体 CPU 消耗。
通常,最佳实践是在运行虚拟机时禁用 CPU 缩放/限制等