Я хочу запустить некоторые тесты для алгоритма 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-файла.
Одной из возможностей было бы получить РУЧКУ на системный вызов, это возможно как-то?
Linux:
На самом деле он печатает время процессора, которое занимает ваша программа. Но если вы используете потоки в вашей программе, она не будет работать должным образом. Вы должны подождать, пока поток завершит свою работу, прежде чем использовать процессорное время. В общем, вы должны написать это:
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;
}
Вы можете попробовать использовать таймер повышения. Это кроссплатформенный способ. Пример кода с сайта 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;
}
Если вы используете C ++ 11 (или имеете к нему доступ) std::chrono
имеет все функции, необходимые для расчета продолжительности работы программы.
Вам нужно будет добавить свой процесс в объект Job перед созданием дочерних процессов. Дочерние процессы будут автоматически выполняться в том же задании, а необходимую информацию можно найти в TotalUserTime
а также TotalKernelTime
члены JOBOBJECT_BASIC_ACCOUNTING_INFORMATION
структура, доступная через QueryInformationJobObject
функция.
Дальнейшая информация:
Начиная с Windows 8, поддерживаются вложенные задания, так что вы можете использовать этот метод, даже если некоторые программы уже используют объекты заданий.
Я не думаю, что есть кроссплатформенный механизм. Использование CreateProcess для запуска приложения с WaitForSingleObject для завершения приложения позволит вам получать прямые потомки. После этого вам понадобятся объекты работы для полного учета (если вам нужно время внуков)
Вы также можете попробовать внешние профилировщики выборки. Я использовал халяву «Сонный» [http://sleepy.sourceforge.net/]and даже лучше «Очень Сонный» [http://www.codersnotes.com/sleepy/] профилировщики под Windows и были очень довольны результатами — приятно отформатированная информация за несколько минут практически без усилий.
Есть похожий проект под названием «Блестящий» [http://sourceforge.net/projects/shinyprofiler/] это должно работать как на Windows, так и * nix.