0

I am profiling Direct3D9 API calls. I have read a lot of documentation here that describes the process. I have a question though about calculating the elapsed clock cycles. Here is my current method:

// measurement vars
LARGE_INTEGER start, stop, freq;

//
// flush command buffer here
//

// 
// issue begin query here
//

// start timer
QueryPerformanceCounter(&start);

//
//draw
//

//
// issue end query here and wait on results
//

// stop timer
QueryPerformanceCounter(&stop);

// calc elapsed ticks
stop.QuadPart -= start.QuadPart;

// get frequency
QueryPerformanceFrequency(&freq);

// ticks for easier handling
ULONG ticks = stop.QuadPart;

// calc elapsed clock cycles
cycles = (2.8E9 * ticks) / (double)freq.QuadPart;

My question concerns the value 2.8E9 which is supposed to represent the speed of the processor. Is this the correct way of calculating clock cycles? I am profiling single API calls and my results differ from those found on the above link. If I set the processor speed to 1E9 then the numbers are within range...I just wanted to check my method...

Jon 'links in bio' Ericson
  • 20,880
  • 12
  • 98
  • 148
P. Avery
  • 779
  • 1
  • 16
  • 34
  • ``ticks`` is already in cycles. You use the frequency to convert cycles to seconds. Read [Acquiring high-resolution time stamps](https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408.aspx) on MSDN. – Chuck Walbourn Apr 01 '15 at 06:12
  • Thanks Chuck I agree. But why does the link I provided in the above question suggest that cycle are calculated like this: cycles = processor speed * ticks / frequency? It seems like it has something to do with the frequency with which the timer samples with respect to the processor's speed? – P. Avery Apr 01 '15 at 16:27
  • 1
    Frequency is defined as 'cycles per second'. The processor speed determines the frequency in the first place--plus other factors thanks to the complexities of modern power management techniques as discussed in the linked article. – Chuck Walbourn Apr 01 '15 at 17:01
  • @ChuckWalbourn thanks I guess the method I'm using is correct. It seems to work. I just wanted to make sure – P. Avery Apr 01 '15 at 23:55
  • Except that with that multiplier you are changing from seconds to some other random unit that is ``2.8e9``th of a second – Chuck Walbourn Apr 02 '15 at 05:49

1 Answers1

0

The number of processor cycles is (approximately) the difference.

LONGLONG cycles = stop.QuadPart - start.QuadPart;

The correct way to convert to SECONDS is:

double seconds = (double)cycles / (double)freq.QuadPart;

QueryPerformanceCounter used to be implemented as a wrapper around RDTSC but this doesn't work well with modern clock frequency stepping power-management. Therefore, QPC is now usually some other stable clock on the system so it might not necessarily be ' CPU processor cycles'.

If you actually want true 'CPU processor cycles' then you should use __rdtsc() intrinsic directly, but remember you don't have a robust way to convert it directly to time--and that on old AMD Athalon 64 machines you have problems of it not being sync'd between cores.

Reserve the use of ticksfor calls to GetTickCCount64 (or the deprecated GetTickCCount) which returns "ticks in milliseconds".

See Acquiring high-resolution time stamps.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81