CPU 轮询模式的利用率
CPU utlization on poll mode
对于我们用 c++ 编写的项目,我们 运行 处理器核心在轮询模式下轮询驱动程序 (dpdk),但在轮询模式下 cpu 利用率显示为 100% top/htop。当我们开始看到丢包故障时,计算了内核上每秒执行的循环或轮询次数(因处理器速度和类型而异)。
用于计算 polls/second 有无驱动程序轮询函数开销的示例代码如下。
#include <iostream>
#include <sys/time.h>
int main() {
unsigned long long counter;
struct timeval tv1, tv2;
gettimeofday(&tv1, NULL);
gettimeofday(&tv2, NULL);
while(1) {
gettimeofday(&tv2, NULL);
//Some function here to measure the overhead
//Poll the driver
if ((double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec) > 1.0) {
std::cout << std::dec << "Executions per second = " << counter << " per second" << std::endl;
counter = 0;
gettimeofday(&tv1, NULL);
}
counter++;
}
}
轮询计数结果各不相同,有时我们会看到一个小故障,数字下降 50% 或低于正常计数,认为这可能是 linux 调度任务的问题所以
使用 linux 命令行 (isolcpus=...) 隔离核心,设置亲和力,将 process/thread 的优先级提高到最高 nice 值并将类型设置为实时 (RT)
但没有区别。
所以问题是,
我们可以依赖轮询模式下在处理器核心上每秒执行的 loops/polls 的数量吗?
有没有一种方法可以计算 CPU 轮询模式的占用率,因为核心 CPU 利用率在顶部显示为 100%?
这是解决这个问题的正确方法吗?
环境:
- 英特尔(R) 至强(R) CPU E5-2680 v3 @ 2.50GHz
- 8G 内存
- Ubuntu Vmware 管理程序上的虚拟机。
不确定以前是否回答过这个问题,任何参考资料都会有所帮助。
不,你不能依赖"the number of loops/polls per sec executed on a processor core in poll mode"。
这是传统操作系统中执行环境的一个基本方面,例如您正在使用的操作系统:主流Linux。
在任何时候,一个重量级的 cron 作业可能会启动,对某些资源提出即时需求,并且内核的调度程序决定抢占您的应用程序并执行其他操作。这只是您的进程被抢占的数百个可能原因之一。
即使您 运行 是根用户,您也无法完全控制进程的资源。
您在轮询指标中看到如此广泛、偶然的差异应该是一个重要的线索:多任务操作系统不是这样工作的。
还有其他 "realtime" 操作系统,其中用户空间应用程序可以有特定的 "service level" 保证,即最少 CPU 或 I/O 可用资源,您可以依赖这些保证特定代码序列每秒或某些其他指标可以执行的次数。
在 Linux 上,有一些东西可以摆弄,例如进程的 nice
级别,以及其他一些东西。但这仍然不能给你任何绝对的保证。
特别是因为您甚至没有 运行 在裸机上,而是 运行 在虚拟管理程序中。因此,您的实际执行配置文件不仅会受到主机操作系统的影响,还会受到客户操作系统的影响!
保证您正在寻找的指标类型的唯一方法是使用实时操作系统,而不是 Linux。几年前,我听说过 Linux 内核的实时扩展(Google 食物:"linux rtos"),但最近没怎么听说过。我不认为主流 Linux 发行版包含该内核扩展,因此,如果您想走那条路,您将靠自己。
intel cpu 上的现代 linux 确实提供了使轮询循环完全占据 cpu 内核接近 100% 的方法。您没有考虑的事情是,删除会导致上下文切换的系统调用,关闭超线程或不使用同一缓存行上的其他线程,关闭 bios 中的动态 cpu 频率提升,移动中断处理。
对于我们用 c++ 编写的项目,我们 运行 处理器核心在轮询模式下轮询驱动程序 (dpdk),但在轮询模式下 cpu 利用率显示为 100% top/htop。当我们开始看到丢包故障时,计算了内核上每秒执行的循环或轮询次数(因处理器速度和类型而异)。
用于计算 polls/second 有无驱动程序轮询函数开销的示例代码如下。
#include <iostream>
#include <sys/time.h>
int main() {
unsigned long long counter;
struct timeval tv1, tv2;
gettimeofday(&tv1, NULL);
gettimeofday(&tv2, NULL);
while(1) {
gettimeofday(&tv2, NULL);
//Some function here to measure the overhead
//Poll the driver
if ((double) (tv2.tv_usec - tv1.tv_usec) / 1000000 + (double) (tv2.tv_sec - tv1.tv_sec) > 1.0) {
std::cout << std::dec << "Executions per second = " << counter << " per second" << std::endl;
counter = 0;
gettimeofday(&tv1, NULL);
}
counter++;
}
}
轮询计数结果各不相同,有时我们会看到一个小故障,数字下降 50% 或低于正常计数,认为这可能是 linux 调度任务的问题所以 使用 linux 命令行 (isolcpus=...) 隔离核心,设置亲和力,将 process/thread 的优先级提高到最高 nice 值并将类型设置为实时 (RT)
但没有区别。
所以问题是, 我们可以依赖轮询模式下在处理器核心上每秒执行的 loops/polls 的数量吗?
有没有一种方法可以计算 CPU 轮询模式的占用率,因为核心 CPU 利用率在顶部显示为 100%?
这是解决这个问题的正确方法吗?
环境:
- 英特尔(R) 至强(R) CPU E5-2680 v3 @ 2.50GHz
- 8G 内存
- Ubuntu Vmware 管理程序上的虚拟机。
不确定以前是否回答过这个问题,任何参考资料都会有所帮助。
不,你不能依赖"the number of loops/polls per sec executed on a processor core in poll mode"。
这是传统操作系统中执行环境的一个基本方面,例如您正在使用的操作系统:主流Linux。
在任何时候,一个重量级的 cron 作业可能会启动,对某些资源提出即时需求,并且内核的调度程序决定抢占您的应用程序并执行其他操作。这只是您的进程被抢占的数百个可能原因之一。
即使您 运行 是根用户,您也无法完全控制进程的资源。
您在轮询指标中看到如此广泛、偶然的差异应该是一个重要的线索:多任务操作系统不是这样工作的。
还有其他 "realtime" 操作系统,其中用户空间应用程序可以有特定的 "service level" 保证,即最少 CPU 或 I/O 可用资源,您可以依赖这些保证特定代码序列每秒或某些其他指标可以执行的次数。
在 Linux 上,有一些东西可以摆弄,例如进程的 nice
级别,以及其他一些东西。但这仍然不能给你任何绝对的保证。
特别是因为您甚至没有 运行 在裸机上,而是 运行 在虚拟管理程序中。因此,您的实际执行配置文件不仅会受到主机操作系统的影响,还会受到客户操作系统的影响!
保证您正在寻找的指标类型的唯一方法是使用实时操作系统,而不是 Linux。几年前,我听说过 Linux 内核的实时扩展(Google 食物:"linux rtos"),但最近没怎么听说过。我不认为主流 Linux 发行版包含该内核扩展,因此,如果您想走那条路,您将靠自己。
intel cpu 上的现代 linux 确实提供了使轮询循环完全占据 cpu 内核接近 100% 的方法。您没有考虑的事情是,删除会导致上下文切换的系统调用,关闭超线程或不使用同一缓存行上的其他线程,关闭 bios 中的动态 cpu 频率提升,移动中断处理。