Логическое время против физического времени в 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( &paramStruct);
processed_time0 = paramStruct.ru_utime;

...stuff happening 

// end of period measurement
int result = getrusage( &paramStruct );
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,

Другие вопросы по тегам