Когда вы говорите «full_load», и вам нужен только один процессор или виртуальное ядро под нагрузкой, простой тугой цикл поможет вам.Конечно, он не будет использовать все транзисторы в чипе (т. Е. Мы не говорим о тесте прожига для «полной нагрузки»), но он будет использовать для запланированного промежутка времени, который получает процессориспользуйте все доступные тактовые циклы без системных вызовов, которые бы передавали управление ядру и, возможно, приводили к перепланированию исполняющего потока на более позднее время.Также вы можете использовать сигнализацию с обработчиком сигнала для выхода из цикла.Так что это позволило бы вам запустить цикл примерно на секунду времени выполнения (сигналы тревоги не являются точно точными по времени ... они близки, но не до такта).
В дополнениедля «пустой» части нагрузки вы могли бы сделать то же самое, но с использованием 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 должно быть 1 миллион часов в секунду в качестве временной базы для значения clock_t
, поэтому вы должны увидеть числовозвращается для "full_load", который близок к этому числу, так как мы собираемся "полная загрузка" в течение примерно секунды.Холостая нагрузка должна быть очень маленькой (конечно).Вот числа, которые я сгенерировал на своем Mac Pro:
Idle Time: 31
Load Time: 1000099
Так что это выглядит несколько в соответствии с тем, что вы ищете, насколько вы знаете, сколько тактовых циклов вы можете увидеть из clock()
.Я бы, конечно, запустил это несколько раз и взял бы среднее значение, чтобы получить лучший показатель дисперсии, которую вы можете увидеть.