Почему прошедшее пользовательское время, измеренное с помощью getrusage(), близко к точно согласованному?
Эта программа на C++ дает переменные результаты. Иногда вариация велика. Я вызываю getrusage() один раз, чтобы узнать время начала. Затем я вызываю rand() 500000000 раз в цикле. Затем я снова вызываю getrusage() и выводит прошедшее пользовательское и системное время между двумя вызовами getrusage(). В зависимости от того, что оно включает, я могу понять, почему "системное время" не будет согласованным. Но я ожидал, что "пользовательское время" будет временем, когда поток (основного процесса) находился в рабочем состоянии. Я думал, что это будет очень близко к полной последовательности от одного запуска к другому. Но это не так.
#include <iostream>
#include <exception>
#include <cstdlib>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
using std::cout;
// tm is end time on intput, time different from start to end on output.
void since(const struct timeval start, struct timeval &tm)
{
if (tm.tv_sec == start.tv_sec)
{
tm.tv_sec = 0;
tm.tv_usec -= start.tv_usec;
}
else
{
tm.tv_usec += 1000000 - start.tv_usec;
tm.tv_sec -= start.tv_sec;
if (tm.tv_usec >= 1000000)
{
tm.tv_usec -= 1000000;
++tm.tv_sec;
}
}
}
void out_tm(const struct timeval &tm)
{
cout << "seconds: " << tm.tv_sec;
cout << " useconds: " << tm.tv_usec;
}
void bail(const char *msg)
{
cout << msg << '\n';
std::terminate();
}
int main()
{
struct rusage usage;
if (getrusage(RUSAGE_SELF, &usage))
bail("FAIL: getrusage() call failed");
struct timeval user_tm = usage.ru_utime;
struct timeval sys_tm = usage.ru_stime;
for (unsigned i = 0; i < 500000000; ++i)
std::rand();
if (getrusage(RUSAGE_SELF, &usage))
bail("FAIL: getrusage() call failed");
since(user_tm, usage.ru_utime);
user_tm = usage.ru_utime;
since(sys_tm, usage.ru_stime);
sys_tm = usage.ru_stime;
cout << "User time: ";
out_tm(user_tm);
cout << "\nSystem time: ";
out_tm(sys_tm);
cout << '\n';
return(0);
}
1 ответ
GNU рекомендует следующий код для измерения разницы во времени.
Есть некоторые отличия от вашего кода, которые могут вызвать скачок во времени, попробуйте.
int
timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y)
{
/* Perform the carry for the later subtraction by updating y. */
if (x->tv_usec < y->tv_usec) {
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
y->tv_usec -= 1000000 * nsec;
y->tv_sec += nsec;
}
if (x->tv_usec - y->tv_usec > 1000000) {
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
y->tv_usec += 1000000 * nsec;
y->tv_sec -= nsec;
}
/* Compute the time remaining to wait.
tv_usec is certainly positive. */
result->tv_sec = x->tv_sec - y->tv_sec;
result->tv_usec = x->tv_usec - y->tv_usec;
/* Return 1 if result is negative. */
return x->tv_sec < y->tv_sec;
}