Вычисление времени процессора в C++ на Windows

есть ли способ в C++ вычислить, сколько времени требуется для запуска данной программы или подпрограммы во время процессора?

Я работаю с Visual Studio 2008, работающим в Windows 7.

5 ответов


если вы хотите знать общее количество процессорного времени, используемого процессом, ни clock, ни rdtsc (либо напрямую, либо через встроенный компилятор) - действительно лучший выбор, по крайней мере IMO. Если вам нужен код для переноски, лучшее, что вы можете сделать, это использовать clock, тест с системой как можно спокойнее, и надеюсь на лучшее (но если вы это сделаете, имейте в виду, что разрешение clock is CLOCKS_PER_SEC, которое может или не может быть 1000, и даже если оно, ваше фактическое разрешение времени часто это будет не так хорошо - это может дать вам время в миллисекундах, но, по крайней мере, обычно продвигается на десятки миллисекунд за раз).

поскольку, однако, вы, похоже, не возражаете, что код специфичен для Windows, вы можете сделать немного лучше. По крайней мере, если мое понимание того, что вы ищете, правильно, то, что вы действительно хотите, вероятно GetProcessTimes, который (отдельно) расскажет вам как в режиме ядра, так и в пользовательском режиме использования процессора процесса (а также запуска время и время выхода,из которого вы можете вычислить используемое время стены, если вы заботитесь). Есть также QueryProcessCycleTime, который сообщит вам общее количество тактовых циклов процессора, используемых процессом (общее количество пользователей и режима ядра во всех потоках). Лично мне трудно представить себе большую пользу для последнего, хотя-подсчет отдельных тактов может быть полезен для маленький разделы кода, подлежащие интенсивной оптимизации, но я менее уверен в том, как вы примените его к полный процесс. GetProcessTimes использует структуры FILETIME, которые поддерживают разрешения 100 наносекунд, но на самом деле в большинстве случаев вы увидите, что будет кратно временному срезу планировщика (который варьируется в зависимости от версии windows, но составляет порядка миллисекунд до десятков миллисекунд).

в любом случае, если вы действительно хотите, время от начала и до конца, GetProcessTimes позволит вам сделать это-если вы создадите программу (например, с CreateProcess), вы получите ручку процесса, который будет сигнализируется при выходе дочернего процесса. Затем вы можете позвонить GetProcessTimes на этом дескрипторе и получить время, даже если ребенок уже вышел-дескриптор останется действительным, пока по крайней мере один дескриптор процесса остается открытым.


вот один из способов. Он измеряет обычное время exeution в миллисекундах.

clock_t begin=clock(); начинается до выполнения маршрута и clock_t end=clock(); начинается сразу после рутинную выходы.

затем два набора времени вычитаются друг из друга, и результатом является значение миллисекода.

#include <stdio.h>
#include <iostream>
#include <time.h>
using namespace std;

double get_CPU_time_usage(clock_t clock1,clock_t clock2)
{
    double diffticks=clock1-clock2;
    double diffms=(diffticks*1000)/CLOCKS_PER_SEC;
    return diffms;
} 

void test_CPU_usage()
{
  cout << "Standby.. measuring exeution time:  ";

  for (int i=0; i<10000;i++)
  {
        cout << "\b\" << std::flush;
        cout << "\b|" << std::flush;
        cout << "\b/" << std::flush;
        cout << "\b-" << std::flush;
  }

  cout << " \n\n";
}

int main (void)
{

    clock_t begin=clock();

    test_CPU_usage();

    clock_t end=clock();

    cout << "Time elapsed: " << double(get_CPU_time_usage(end,begin)) << " ms ("<<double(get_CPU_time_usage(end,begin))/1000<<" sec) \n\n";
    return 0;
}

на __rdtscp intrinsic даст вам время в циклах процессора с некоторыми оговорками. Вот!--2-->статья MSDN

Это зависит от того, что вы хотите измерить. Для получения лучших результатов возьмите в среднем несколько миллионов (если не миллиардов) итераций.


функция clock () [как предусмотрено Visual C++ 2008] не возвращает процессорное время, используемое программой, в то время как она должны (согласно стандарту C и / или стандарту C++). Тем не менее, чтобы измерить время процессора в Windows, у меня есть этот вспомогательный класс (который неизбежно не переносится):

class ProcessorTimer
{
  public:
    ProcessorTimer() { start(); }
    void start() { ::GetProcessTimes(::GetCurrentProcess(), &ft_[3], &ft_[2], &ft_[1], &ft_[0]); }
    std::tuple<double, double> stop()
    {
        ::GetProcessTimes(::GetCurrentProcess(), &ft_[5], &ft_[4], &ft_[3], &ft_[2]);
        ULARGE_INTEGER u[4];
        for (size_t i = 0; i < 4; ++i)
        {
            u[i].LowPart = ft_[i].dwLowDateTime;
            u[i].HighPart = ft_[i].dwHighDateTime;
        }
        double user = (u[2].QuadPart - u[0].QuadPart) / 10000000.0;
        double kernel = (u[3].QuadPart - u[1].QuadPart) / 10000000.0;
        return std::make_tuple(user, kernel);
    }
  private:
    FILETIME ft_[6];
};


class ScopedProcessorTimer
{
  public:
    ScopedProcessorTimer(std::ostream& os = std::cerr) : timer_(ProcessorTimer()), os_(os) { }
    ~ScopedProcessorTimer()
    {
        std::tuple<double, double> t = timer_.stop();
        os_ << "user " << std::get<0>(t) << "\n";
        os_ << "kernel " << std::get<1>(t) << "\n";
    }
  private:
    ProcessorTimer timer_;
    std::ostream& os_;
}

этот код является процесс Cpu Usage

ULONGLONG LastCycleTime = NULL;
LARGE_INTEGER LastPCounter;
LastPCounter.QuadPart = 0; // LARGE_INTEGER Init

                           // cpu get core number
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
int numProcessors = sysInfo.dwNumberOfProcessors;

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, Process::pid);

if (hProcess == NULL)
    nResult = 0;

int count = 0;
while (true)
{
    ULONG64 CycleTime;
    LARGE_INTEGER qpcLastInt;

    if (!QueryProcessCycleTime(hProcess, &CycleTime))
        nResult = 0;

    ULONG64 cycle = CycleTime - LastCycleTime;

    if (!QueryPerformanceCounter(&qpcLastInt))
        nResult = 0;

    double Usage = cycle / ((double)(qpcLastInt.QuadPart - LastPCounter.QuadPart));

    // Scaling
    Usage *= 1.0 / numProcessors;
    Usage *= 0.1;

    LastPCounter = qpcLastInt;
    LastCycleTime = CycleTime;

    if (count > 3)
    {
        printf("%.1f", Usage);
        break;
    }

    Sleep(1); // QueryPerformanceCounter Function Resolution is 1 microsecond

    count++;
}

CloseHandle(hProcess);