当您说“full_load”时,您只需要一个负载下的 CPU 或虚拟内核,一个简单的紧密循环就可以解决问题。当然,它不会使用芯片上的所有晶体管(即,我们不是在谈论“满载”的老化测试),但它会在预定的时间片内使用 CPU ,使用所有可用的时钟周期,没有系统调用会放弃对内核的控制,并可能导致稍后重新调度正在执行的线程。您也可以使用带有信号处理程序的警报来退出循环。这样一来,您就可以在大约一秒钟的执行时间内运行循环(警报的时间并不完全准确......它们很接近,但不会精确到时钟周期)。
此外,对于“空闲”负载部分,您可以执行相同的操作,但使用 sigsuspend() 而不是紧密循环,这将等待警报响起。
所以您的代码可能如下所示:
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <stdio.h>
static sig_atomic_t alarm_flag = 1;
void alarm_handler(int arg)
{
alarm_flag = 0;
}
clock_t idle()
{
//setup the alarm flag
alarm_flag = 1;
//setup the signal masks
sigset_t old_signal_set;
sigset_t new_signal_set;
sigemptyset(&old_signal_set);
sigemptyset(&new_signal_set);
//block the alarm signal
sigaddset(&new_signal_set, SIGALRM);
sigprocmask(SIG_BLOCK, &new_signal_set, &old_signal_set);
//setup the alarm
alarm(1);
clock_t time_before = clock();
//sit idle while we wait for the alarm to go off
while(alarm_flag)
sigsuspend(&old_signal_set);
clock_t time_after = clock();
//restore the old signal mask
sigprocmask(SIG_SETMASK, &old_signal_set, NULL);
return time_after - time_before;
}
clock_t full_load()
{
//set the alarm signal
alarm_flag = 1;
//set the 1-second alarm
alarm(1);
clock_t time_before = clock();
//loop until the alarm goes off
while(alarm_flag);
clock_t time_after = clock();
return time_after - time_before;
}
int main()
{
//setup the signal handler for the alarm
sigset(SIGALRM, alarm_handler);
//call the functions
clock_t idle_time = idle();
clock_t load_time = full_load();
//... do whatever else you need to-do with this info
printf("Idle Time: %d\n", (int)idle_time);
printf("Load Time: %d\n", (int)load_time);
return 0;
}
请记住,根据 POSIX 标准,clock_t 值的时基应为每秒 100 万个时钟,因此您应该看到“full_load”返回的数字接近这个数字,因为我们要“满载”大约一秒钟。空载应该非常小(当然)。这是我在 Mac Pro 上生成的数字:
Idle Time: 31
Load Time: 1000099
因此,就您可能看到从clock() 返回的时钟周期数而言,这似乎与您正在寻找的内容有些一致。我当然会多次运行此程序并取平均值,以便更好地指示您可能会看到的差异。