2014-06-12 130 views
0

我的代碼計算時鐘週期來創建線程計算時鐘週期給出了截然不同的結果

# 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。我環顧四周,但沒有真正找到解釋。這種行爲的原因是什麼?

+0

究竟爲什麼你感到驚訝,如果算上完整的線程執行,而不是隻在啓動時你會得到一個更大的數字? – Voo

回答

2

不同之處在於您是否等待線程完成執行。很明顯,如果你等待,那麼這樣做將允許線程使用更多的時鐘週期。

請注意,您不計時創建線程的過程。您正在計時執行線程過程。讓我清楚,由QueryThreadCycleTime返回的值是執行線程所消耗的週期數,而不是執行CreateThread所花費的週期數,或者實際上是從調用CreateThread開始執行的線程所花費的掛鐘時間。

而你這樣做是在一個不確定的點。例如,在您的代碼中,QueryThreadCycleTime有時會返回0,因爲該線程在主線程調用QueryThreadCycleTime時甚至沒有開始執行。

如果您想要創建線程時間,則需要多長時間才能返回CreateThread。或者更好的方法是,測量在撥打CreateThread之間經過的掛鐘時間,並開始執行線程。

例如,代碼可能是這樣的:

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

# define RUN 100000 

DWORD WINAPI Calc(LPVOID Param){ 
    QueryPerformanceCounter((LARGE_INTEGER*)Param); 
} 

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

    for (int i = 0; i < RUN; i++) 
    { 
     LARGE_INTEGER PerformanceCountBeforeCreateThread, PerformanceCountWhenThreadStartsExecuting; 
     DWORD ThreadId; 
     HANDLE ThreadHandle; 

     /* create the thread */ 
     QueryPerformanceCounter(&PerformanceCountBeforeCreateThread); 
     ThreadHandle = CreateThread(NULL, 0, Calc, 
      &PerformanceCountWhenThreadStartsExecuting, 0, &ThreadId);  
     WaitForSingleObject(ThreadHandle, INFINITE); 
     CloseHandle(ThreadHandle); 

     Sum += PerformanceCountWhenThreadStartsExecuting.QuadPart - PerformanceCountBeforeCreateThread.QuadPart; 
    } 

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

    LARGE_INTEGER Frequency; 
    QueryPerformanceFrequency(&Frequency); 
    printf_s("Frequency %lu\n", Frequency.QuadPart); 

    _getch(); 
    return 0; 
} 
相關問題