Почему я получаю разные значения времени - PullRequest
2 голосов
/ 22 ноября 2011

Я пробовал этот код на C ++ на платформе Win7x64 с MSVC ++, и у меня частота процессора составила около 2900000 тиков в секунду.

Когда я запускаю эту программу, мой секундомер возвращает около 10 000 000 тиков, что означает, что для обработки моей программы требуется около 4 секунд, но результаты моей программы готовы для меня через 1 секунду (или меньше) O_o.

Не могли бы вы сказать, что не так в моем коде?

#include <iostream>
#include "header.h"
#include <fstream>
#include <string>
#include <sstream>
#include <strsafe.h>
#include <direct.h>
#include <string.h>



using namespace std;

#define CV_TO_NANO 1000000000
#define CV_TO_MICRO 1000000
#define CV_TO_MILLI 1000

 unsigned __int64 inline GetRDTSC()
{
   __asm
   {
      ; Flush the pipeline
      XOR eax, eax
      CPUID
      ; Get RDTSC counter in edx:eax
      RDTSC
   }
}

unsigned __int64 RunTest(TCHAR *AppName, TCHAR *CmdLine);

 void main()
 {  
     unsigned __int64 start = 0;
     unsigned __int64 stop = 0;
     unsigned __int64 freq = 0;
     float rps;
     ofstream dataFile;


     // get processor freq
     QueryPerformanceFrequency((LARGE_INTEGER *)&freq);
     cout <<"freq (count per second): "<< freq << endl;
     // round per second
     rps = 1.0/(freq);
     cout <<"rps (1/rps): "<< rps << endl;
     dataFile.open ("d:/dataC.txt",ios::out );
     for(int i = 0;i<200;i++)
     {
        SetProcessAffinityMask(GetCurrentProcess(),0x0001);
        SetThreadAffinityMask(GetCurrentThread(),0x0001);
        cout << RunTest(L"D:\\Child\\Child.exe", NULL);
     }
    getchar();
    return;
 }

unsigned __int64 RunTest(TCHAR *AppName, TCHAR *CmdLine)
{
    unsigned __int64 start = 0;
    unsigned __int64 stop = 0;
    PROCESS_INFORMATION processInformation;
    STARTUPINFO startupInfo;
    memset(&processInformation, 0, sizeof(processInformation));
    memset(&startupInfo, 0, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);

    BOOL result;
    start = GetRDTSC();
    result = ::CreateProcess(AppName, CmdLine, NULL, NULL, FALSE, REALTIME_PRIORITY_CLASS, NULL, NULL, &startupInfo, &processInformation);
    stop = GetRDTSC();
    getchar();
    if (result == 0)
    {
        wprintf(L"ERROR: CreateProcess failed!");
    }
    else
    {
        WaitForSingleObject( processInformation.hProcess, 0 );
        CloseHandle( processInformation.hProcess );
        CloseHandle( processInformation.hThread );
    }
    return stop - start;
}

Ответы [ 2 ]

2 голосов
/ 22 ноября 2011

Я думаю, у вас есть неправильное представление о том, что QueryPerformanceFrequency говорит вам что-то о скорости вашего процессора - это не так.QueryPerformanceFrequency извлекает частоту счетчика производительности с высоким разрешением, которая не гарантирует предсказуемое отношение к тактовой частоте вашего процессора.Это значение необходимо использовать вместе с QueryPerformanceCounter, чтобы получить качественные временные значения, а не со сборкой, которая напрямую запрашивает RDTSC.

1 голос
/ 22 ноября 2011

Вот пример того, как использовать высокочастотный таймер для измерения времени блока кода:

#include <Windows.h>
#include <iostream>
using namespace std;

int main()
{
    LARGE_INTEGER li = {};
    __int64 freq, start, stop;

    QueryPerformanceFrequency(&li);
    freq = li.QuadPart;

    cout << "Counter Frequency: " << freq << "\n";

    QueryPerformanceCounter(&li);
    start = li.QuadPart;

    for( int i = 0; i < 1000000; ++i )
    {
        int n = i * rand();
    } 

    QueryPerformanceCounter(&li);
    stop = li.QuadPart;

    double elapsed_seconds = static_cast<double>(stop-start) / static_cast<double>(freq);

    cout << "Elapsed Time: " << elapsed_seconds << " seconds\n";
}
...