… …
BeginScene();
… …
// Start profiling
LARGE_INTEGER start, stop, freq;
QueryPerformanceCounter(&start);
SetTexture(...);
DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
QueryPerformanceCounter(&stop);
stop.QuadPart -= start.QuadPart;
QueryPerformanceFrequency(&freq);
// Stop profiling
… …
EndScene();
Present();
Example 2: Custom Profiling Implementation with QPC
start and stop are two large integers that will hold the start and stop values returned by the high-performance timer. Notice that QueryPerformanceCounter(&start) is called just before IDirect3DDevice9::SetTexture and QueryPerformanceCounter(&stop) is called just after IDirect3DDevice9::DrawPrimitive. After getting the stop value, QueryPerformanceFrequency is called to return freq, which is the frequency of the high-resolution timer. In this hypothetical example, suppose you get the following results for start, stop, and freq:
Local Variable |
Number of Ticks |
start |
1792998845094 |
stop |
1792998845102 |
freq |
3579545 |
You could convert these values to the number of cycles it takes to execute the API calls like this:
# ticks = (stop - start) = 1792998845102 - 1792998845094 = 8 ticks
# cycles = CPU speed * number of ticks / QPF
# 4568 = 2 GHz * 8 / 3,579,545
In other words, it takes about 4568 clock cycles to process IDirect3DDevice9::SetTexture and IDirect3DDevice9::DrawPrimitive on this 2 GHz machine. You could convert these values to the actual time it took to execute all the calls like this:
(stop - start)/ freq = elapsed time
8 ticks / 3,579,545 = 2.2E-6 seconds or between 2 and 3 microseconds.
需要清楚:
TICK,滴答,计算机的计时器的单位。
Hz,CLOCK CYCLE,CPU的时钟周期的单位。
QueryPerformanceFrequency()取出的TICK数是1秒钟内计算机计时器的滴答数。这个数值通常来自8253计时芯片。
2 GHz是1秒钟内CPU的时钟周期数。显然这个数据来自CPU。
在一个TICK里,计算机通过CPU要做(开、关开关)许多次。所以通常一秒钟时间里,CPU的CLOCK CYCLE都会比TICK大很多,这样在一个TICK里才可以让CPU跑很多个CLOCK CYCLE,完成很多操作。