为什么我得到不同的时间值

发布于 2024-12-17 14:11:27 字数 2362 浏览 4 评论 0原文

我在 Win7x64 平台上使用 MSVC++ 在 C++ 中尝试了这段代码,我得到的 CPU 频率约为每秒 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;
}

I've tried this code in C++ on Win7x64 platform with MSVC++, and I got CPU frequency about 2900000 ticks per second.

When I run this program, my stopwatch returns about 10,000,000 tick, which means it take about 4 seconds to process my program, but my program results are ready for me in 1 second (or less) O_o.

Could you please tell me what is wrong in my code?

#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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏雨凉 2024-12-24 14:11:27

我认为您在这里有一个误解,认为 QueryPerformanceFrequency 告诉您有关处理器速度的信息 - 但事实并非如此。 QueryPerformanceFrequency 检索高分辨率性能计数器的频率,不保证该频率与您的 CPU 时钟速度有任何可预测的关系。该值需要与 QueryPerformanceCounter 为了获得质量计时值,而不是使用直接查询 RDTSC 的程序集。

I think you have a misconception here that QueryPerformanceFrequency is telling you something about the speed of your processor - it isn't. QueryPerformanceFrequency retrieves the frequency of the high-resolution performance counter, which is not guaranteed to have any predictable relationship to your CPU clock speed. This value needs to be used in conjunction with QueryPerformanceCounter in order to get quality timing values, not with assembly that directly queries the RDTSC.

不忘初心 2024-12-24 14:11:27

下面是如何使用高频定时器对代码块进行计时的示例:

#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";
}

Here is an example of how to use the high-frequency timer to time a block of code:

#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";
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文