Как я могу измерить процессорное время в C ++ на окнах и включить вызовы system ()?

Я хочу запустить некоторые тесты для алгоритма C ++ и получить время процессора, которое требуется, в зависимости от входных данных. Я использую Visual Studio 2012 в Windows 7. Я уже нашел один способ подсчета времени процессора в Windows: Как я могу измерить время процессора и время настенных часов в Linux / Windows?

Тем не менее, я использую Система () команда в моем алгоритме, который не измеряется таким образом. Итак, как я могу измерить процессорное время и включить время моих вызовов скриптов через system ()?

Я должен добавить небольшой пример. Это моя функция get_cpu_time (по ссылке, описанной выше):

double get_cpu_time(){
FILETIME a,b,c,d;
if (GetProcessTimes(GetCurrentProcess(),&a,&b,&c,&d) != 0){
//  Returns total user time.
//  Can be tweaked to include kernel times as well.
return
(double)(d.dwLowDateTime |
((unsigned long long)d.dwHighDateTime << 32)) * 0.0000001;
}else{
//  Handle error
return 0;
}
}

До сих пор это прекрасно работало, и когда я создал программу, которая сортирует какой-то массив (или выполняет некоторые другие вещи, которые занимают некоторое время), он работает нормально. Однако, когда я использую команду system () — как в этом случае, она не делает:

int main( int argc, const char* argv[] )
{
double start = get_cpu_time();
double end;
system("Bla.exe");
end = get_cpu_time();

printf("Everything took %f seconds of CPU time", end - start);

std::cin.get();

}

Выполнение данного exe-файла измеряется таким же образом и занимает около 5 секунд. Когда я запускаю его через system (), все это занимает процессорное время 0 секунд, что, очевидно, не включает выполнение exe-файла.

Одной из возможностей было бы получить РУЧКУ на системный вызов, это возможно как-то?

7

Решение

Linux:

  • Для настенных часов используйте gettimeofday() или же clock_gettime()
  • Для процессорного времени используйте getrusage() или же раз()
0

Другие решения

На самом деле он печатает время процессора, которое занимает ваша программа. Но если вы используете потоки в вашей программе, она не будет работать должным образом. Вы должны подождать, пока поток завершит свою работу, прежде чем использовать процессорное время. В общем, вы должны написать это:

WaitForSingleObject(threadhandle, INFINITE);

Если вы не знаете, что именно вы используете в своей программе (если она многопоточная или нет ..), вы можете создать поток для выполнения этой работы, дождаться завершения потока и измерить время.

DWORD WINAPI MyThreadFunction( LPVOID lpParam );
int main()
{
DWORD   dwThreadId;
HANDLE  hThread;

int startcputime, endcputime, wcts, wcte;

startcputime = cputime();

hThread = CreateThread(
NULL,                   // default security attributes
0,                      // use default stack size
MyThreadFunction,       // thread function name
NULL,                   // argument to thread function
0,                      // use default creation flags
dwThreadIdArray);

WaitForSingleObject(hThread, INFINITE);

endcputime = cputime();

std::cout << "it took " << endcputime - startcputime << " s of CPU to execute this\n";

return 0;
}

DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
//do your job here
return 0;
}
0

Вы можете попробовать использовать таймер повышения. Это кроссплатформенный способ. Пример кода с сайта Boost:

#include <boost/timer/timer.hpp>
#include <cmath>

int main() {
boost::timer::auto_cpu_timer t;

for (long i = 0; i < 100000000; ++i)
std::sqrt(123.456L); // burn some time

return 0;
}
0

Если вы используете C ++ 11 (или имеете к нему доступ) std::chrono имеет все функции, необходимые для расчета продолжительности работы программы.

0

Вам нужно будет добавить свой процесс в объект Job перед созданием дочерних процессов. Дочерние процессы будут автоматически выполняться в том же задании, а необходимую информацию можно найти в TotalUserTime а также TotalKernelTime члены JOBOBJECT_BASIC_ACCOUNTING_INFORMATION структура, доступная через QueryInformationJobObject функция.

Дальнейшая информация:

Начиная с Windows 8, поддерживаются вложенные задания, так что вы можете использовать этот метод, даже если некоторые программы уже используют объекты заданий.

0

Я не думаю, что есть кроссплатформенный механизм. Использование CreateProcess для запуска приложения с WaitForSingleObject для завершения приложения позволит вам получать прямые потомки. После этого вам понадобятся объекты работы для полного учета (если вам нужно время внуков)

0

Вы также можете попробовать внешние профилировщики выборки. Я использовал халяву «Сонный» [http://sleepy.sourceforge.net/]and даже лучше «Очень Сонный» [http://www.codersnotes.com/sleepy/] профилировщики под Windows и были очень довольны результатами — приятно отформатированная информация за несколько минут практически без усилий.

Есть похожий проект под названием «Блестящий» [http://sourceforge.net/projects/shinyprofiler/] это должно работать как на Windows, так и * nix.

0