在WINAPI中计算时钟周期会产生非常不同的结果

时间:2014-06-12 10:42:47

标签: c multithreading winapi

我计算用于创建线程的时钟周期的代码是

# include <Windows.h>
# include <stdio.h>
# include <conio.h>

# define RUN 20000

DWORD WINAPI Calc(LPVOID Param){}

int main(int argc, char* agrv[])
{
    ULONG64 Sum = 0;

    for (int i = 0; i < RUN; i++)
    {
        ULONG64 ret = 0;
        DWORD ThreadId;
        HANDLE ThreadHandle;

        /* create the thread */
        ThreadHandle = CreateThread(
            NULL,           /* default security attributes */
            0,              /* default stack size */
            Calc,           /* thread function */
            NULL,           /* parameter to thread function */
            0,              /* default creation flags */
            &ThreadId);     /* returns the thread identifier */

        QueryThreadCycleTime(ThreadHandle, &ret);

        WaitForSingleObject(ThreadHandle, INFINITE);

        CloseHandle(ThreadHandle);

        Sum += ret;
    }

    printf_s("The Average no of cycles in %d runs is %lu\n", RUN, (DWORD)(Sum/RUN));

    _getch();
    return 0;
}

此代码的结果在我的中等笔记本电脑上大约有1000个时钟周期。但是如果我在WaitForSingleObject函数之后调用QueryThreadCycleTime函数,结果会非常不同,大约为200,000。我环顾四周,但没有找到解释。这种行为的原因是什么?

1 个答案:

答案 0 :(得分:2)

区别在于您是否等待线程完成执行。显然,如果你等待,那么这样做将允许线程使用更多的时钟周期。

请注意,您没有计算创建线程的过程。您正在执行线程过程。让我明确一点,QueryThreadCycleTime返回的值是执行线程所消耗的周期数,而不是执行CreateThread所花费的周期数,或者实际上是调用{{1}所花费的挂钟时间开始执行的线程。

你是在一个不确定的时刻这样做的。例如,在您的代码中,CreateThread有时会返回QueryThreadCycleTime,因为线程甚至没有在主线程调用0的位置开始执行。

如果您想要创建线程,请计算QueryThreadCycleTime返回所需的时间。或者甚至更好,衡量正在调用CreateThread和开始执行的线程之间经过的挂钟时间。

例如,代码可能如下所示:

CreateThread