Логическое время против физического времени в Ubuntu Linux
Я измеряю физическое время между двумя событиями, как это:
#include <time.h>
#include <sys/time.h>
timeval wall_time0;
timeval wall_time1;
// start of period measurement
gettimeofday( &wall_time0 , 0);
...stuff happening
// end of period measurement
gettimeofday( &wall_time1 , 0);
return ( ( wall_time1.tv_sec - wall_time0.tv_sec ) + (( wall_time1.tv_usec - wall_time0.tv_usec )/(double)1000000) );
Но теперь мне нужен способ измерить логическое время, которое поток фактически использует. То есть, теоретически, это должно быть физическое время, меньше времени, затрачиваемого на выполнение других потоков и / или системы и логики ядра.
Я думал, что это был способ сделать это:
clock_t mTime0;
clock_t mTime1;
//start of period measurement
mTime0=clock();
... stuff happening
//end of period measurement
mTime1=clock();
return (mTime1-mTime0)/(double)CLOCKS_PER_SEC;
но сделав несколько измерений, я заметил две проблемы:
1) для некоторых измерений оно больше физического времени, что неверно (то есть: для определенного цикла физическое время будет равно 0,2495, а "логическое" (измеренное с помощью часов ()) будет равно 0,27, для меньших измерений - просто округлить до нуля, что приводит ко второму вопросу...)
2) результирующее время кажется намного грубее, чем возвращаемое gettimeofday
Есть ли лучший способ измерить время локального потока в Linux?
3 ответа
Хорошо, после небольшого исследования я обнаружил, что getrusage удовлетворяет обе упомянутые потребности:
страница руководства getrusage
поэтому в основном требуемый код очень похож на то, как я измеряю физическое время с gettimeofday
, только то, что сейчас я использую getrusage
#include <time.h>
#include <sys/time.h>
#include <sys/resource.h>
timeval processed_time0;
timeval processed_time1;
rusage paramStruct
// start of period measurement
int result = getrusage( ¶mStruct);
processed_time0 = paramStruct.ru_utime;
...stuff happening
// end of period measurement
int result = getrusage( ¶mStruct );
processed_time1 = paramStruct.ru_utime;
return ( ( processed_time1.tv_sec - processed_time0.tv_sec ) + (( processed_time1.tv_usec - processed_time0.tv_usec )/(double)1000000) );
этот способ дает мне оба
1) текущий процесс потребляет время
2) микросекундное разрешение
Я исследовал Boost Date.Time, но в документации ничего не говорится о времени процесса или пользователя по сравнению с системным временем, я думаю, что библиотека просто занимается измерением физического времени
Есть несколько вариантов более высокой точности, которые вы можете использовать - посмотрите на sys/timex.h
, Также Boost Date.Time, например, имеет таймеры миллисекунды и более высокой точности.
Что касается "общего времени> физического истекшего времени", я видел это в многопоточной синхронизации. Это просто "учетная" вещь: все "потребление" процессора добавляется, и в многопоточном коде может потребоваться больше времени, чем если бы все потоки работали, некоторые накладные расходы на планирование добавлялись, и у вас было больше времени.
tv_usec
поле struct timeval
в микросекундах, а не в единицах 1/(double)CLOCKS_PER_SEC
,