Mic*_*yer 5 linux multi-core power-management
我正在寻找一种在 Linux 中动态禁用内核的机制,以最大限度地减少功耗。
不幸的是,根据Watts Up?的读数,使用以下简单方法禁用内核实际上会增加功率。Pro测量系统总功率:
echo 0 > /sys/devices/system/cpu/cpu7/online
Run Code Online (Sandbox Code Playgroud)
我的经验似乎得到了其他人的证实(尽管这个错误已被标记为“CLOSED PATCH_ALREADY_AVAILABLE”): https://bugzilla.kernel.org/show_bug.cgi ?id=5471
由于机器已卸载,我希望除了一个核心之外的所有核心(或者可能是两个“核心”,因为 CPU 是超线程的)都处于尽可能深度的睡眠状态。根据 acpitool 的输出,这似乎不会单独发生:
Processor ID : 7
Bus mastering control : no
Power management : yes
Throttling control : no
Limit interface : no
Active C-state : C0
C-states (incl. C0) : 3
Usage of state C1 : 899 (99.3 %)
Usage of state C2 : 6 (0.7 %)
Run Code Online (Sandbox Code Playgroud)
顺便说一句,令我困惑的一点是 acpitool 和 /proc/acpi 似乎对可用的 C 状态不一致,或者它们可能使用不同的命名方案。
$ cat /proc/acpi/processor/CPU7/power
active state: C0
max_cstate: C8
maximum allowed latency: 2000000000 usec
states:
C1: type[C1] promotion[--] demotion[--] latency[001] usage[00000000] duration[00000000000000000000]
C2: type[C2] promotion[--] demotion[--] latency[017] usage[00001248] duration[00000000001877531423]
C3: type[C3] promotion[--] demotion[--] latency[017] usage[00000006] duration[00000000000012580727]
Run Code Online (Sandbox Code Playgroud)
这似乎表明有 4 个 C 状态 (C0-C3),但 acpitool 仅报告 3 个 C 状态。
其实这可以归结为两个问题:
请注意,从深度睡眠状态醒来的延迟不是一个问题。FWIW,我在 Intel i7 920 上运行 Ubuntu 10.04.3(内核 2.6.32-38)。
小智 -1
上述限制 C 状态的方法都是永久性的(直到系统重新启动)。如果您希望系统在特定时间内具有极低的延迟,但希望在其他时间节省更多电量,可以使用一种方法来动态控制使用哪些 C 状态。
\n\n要动态控制 C 状态,请打开文件 /dev/cpu_dma_latency 并将最大允许延迟写入其中。只要文件 /dev/cpu_dma_latency 保持打开状态,这将阻止使用转换延迟高于指定值的 C 状态。写入最大允许延迟 0 将使处理器保持在 C0 状态(如使用内核参数 \xe2\x80\x9cidle=poll\xe2\x80\x9d),写入较低值(通常为 5 或更低)应强制处理器空闲时C1。将处理器限制为 C1 状态所需的确切值取决于各种因素,例如您正在使用的空闲驱动程序、您正在使用的 CPU,以及系统中可能的 ACPI 表。还可以写入更高的值来限制使用延迟大于写入值的 C 状态。使用的值应对应于 /sys/devices/system/cpu/cpuX/cpuidle/stateY/latency 中的延迟值(其中 X 是 CPU 编号,Y 是空闲状态)\xe2\x80\x94CPU 空闲状态具有不应使用比写入 /dev/cpu_dma_latency 更大的延迟。
\n\n执行此操作的一种简单方法是编译一个简单的程序,该程序将写入该文件,并保持打开状态直到该文件被终止。下面是此类程序的一个示例,可以通过将代码剪切并粘贴到名为 setcpulatency.c 的文件中,然后运行 \xe2\x80\x9cmake setcpulatency\xe2\x80\x9d 来进行编译。因此,为了最大限度地减少某些时段(例如上午 8 点到下午 5 点)的延迟,可以将 cron 作业设置为在上午 8 点运行。这个 cron 作业可以在后台运行 setcpulatency,参数为 0,并且 cron 表条目如下:
\n\n00 08 * * * /path/to/setcpulatency 0 &\nRun Code Online (Sandbox Code Playgroud)\n\n然后,在下午 5 点,另一个 cron 作业可能会杀死任何保持 /dev/cpu_dma_latency 打开的程序:
\n\n00 17 * * * kill -9 `lsof \xe2\x80\x93t /dev/cpu_dma_latency`\nRun Code Online (Sandbox Code Playgroud)\n\n当然,这只是一个示例,用于展示如何动态控制 C 状态... crond 服务通常在低延迟环境中被禁用,但这些步骤可以手动执行或通过其他方式运行。
\n\n#include <stdio.h>\n#include <fcntl.h>\n\nint main(int argc, char **argv) {\n int32_t l;\n int fd;\n\n if (argc != 2) {\n fprintf(stderr, "Usage: %s <latency in us>\\n", argv[0]);\n return 2;\n }\n\n l = atoi(argv[1]);\n printf("setting latency to %d us\\n", l);\n\n fd = open("/dev/cpu_dma_latency", O_WRONLY);\n\n if (fd < 0) {\n perror("open /dev/cpu_dma_latency");\n return 1;\n }\n\n if (write(fd, &l, sizeof(l)) != sizeof(l)) {\n perror("write to /dev/cpu_dma_latency");\n return 1;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
3883 次 |
| 最近记录: |