當你說「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
值,所以你應該看到「full_load」返回的數字接近該數字,因爲我們正在「滿載」大約一秒鐘。空閒負載應該非常小(當然)。我在我的Mac Pro的生成這裏的數字:
Idle Time: 31
Load Time: 1000099
這樣似乎有點在線與你在找什麼,只要知道時鐘多少個週期還是可以看到clock()
返回。我當然會多次運行這個數據,並以平均值來更好地顯示您可能會看到的差異。
您是在測量您正在使用的進程的CPU利用率,還是單獨的進程? – Spudd86 2011-05-10 13:31:00
@ Spudd86:我自己的過程 – psihodelia 2011-05-10 13:32:30