Я понимаю, что упреждающая многозадачная ОС может прерывать процесс в любой «позиции кода».
Учитывая следующий код:
int main() {
while( true ) {
doSthImportant(); // needs to be executed at least each 20 msec
// start of critical section
int start_usec = getTime_usec();
doSthElse();
int timeDiff_usec = getTime_usec() - start_usec;
// end of critical section
evalUsedTime( timeDiff_usec );
sleep_msec( 10 );
}
}
Я ожидаю, что этот код будет обычно давать правильные результаты для timeDiff_usec, особенно в том случае, если doSthElse () а также getTime_usec () не занимает много времени, поэтому они редко прерываются планировщиком ОС.
Но программа будет время от времени прерываться где-то в «критической секции». Переключатель контекста будет делать то, что должен, и все же в таком случае программа выдаст неправильные результаты для timeDiff_usec.
Это единственный пример, который я имею в виду на данный момент, но я уверен, что будут другие сценарии, в которых многозадачность может привести к проблемам с программой (мер), поскольку время не является единственным состоянием, которое может быть изменено при повторном входе.
Редактировать:
Я изменил пример кода, чтобы сделать его более точным.
Я хочу проверить время, затрачиваемое на то, чтобы doSthElse () не занимал около 50 мсек или около того, и в этом случае я бы искал лучшее решение.
- Есть ли способ гарантировать, что измерение времени для определенного действия работает нормально?
Это зависит от вашей операционной системы и вашего уровня привилегий. В некоторых системах для некоторых уровней привилегий вы можете назначить процессу или потоку приоритет, который предотвращает вытеснение его чем-либо с более низким приоритетом. Например, в Linux вы можете использовать sched_setscheduler
дать потоку приоритет в реальном времени. (Если вы действительно серьезны, вы также можете установить сходство потоков и сходство SMP, чтобы предотвратить обработку прерываний на процессоре, на котором работает ваш поток.)
Ваша система может также обеспечить отслеживание времени, которое учитывает потраченное время. Например, POSIX определяет getrusage
функция, которая возвращает структуру, содержащую ru_utime
(количество времени, проведенное процессом в «режиме пользователя») и ru_stime
(количество времени, проведенное процессом в «режиме ядра»). Они должны суммировать общее время, затраченное ЦП на процесс, исключая интервалы, в течение которых процесс был приостановлен. Обратите внимание, что если ядру необходимо, например, тратить время на подкачку от имени вашего процесса, то не определено, сколько (если таковое имеется) этого времени отводится вашему процессу.
В любом случае, обычный способ измерить время, потраченное на какое-то критическое действие, состоит в том, чтобы измерять его время (по существу, так, как это показывает ваш вопрос), в другой бездействующей системе, отбрасывать измерения выбросов и принимать среднее значение (после устранения выбросов) или принимать средний или 95-й процентиль измерений, в зависимости от того, зачем вам нужно измерение.
Какие другие общие проблемы имеют решающее значение для многозадачности и должны быть рассмотрены? (Я не думаю о безопасности потоков — но могут быть общие проблемы).
Слишком широк. Есть целые книги, написанные на эту тему.