Search code examples
c++winapiperformancecounterpdh

PdhGetFormattedCounterValue and correct Format


Im trying to understand the performance API but I have a problem to understand the PdhGetFormattedCounterValue function and the dwFormat parameter.

How do I know which format to choose when calling this function?

I found the PDH_COUNTER_INFO structure on MSDN and saw that this structure has a dwType member but I still not understand how to use this structure to get information about the counter format to successfully call the PdhGetFormattedCounterValue function.


Solution

  • You get to choose.

    Many counters are calculated as fractions or they are scaled or both, so they have fractional parts. Which makes PDH_FMT_DOUBLE a good choice.

    Some counter types never have fractional parts. You could read all the documentation and work out which, and then add two code paths to handle "counters that might be fractional" and "counters that won't be fractional", but this would be a lot of work for very little gain or none.

    Just use PDH_FMT_DOUBLE.

    Update

    For most counters the precision is only a concern during the calculation of the final value, which happens within the PDH library. But, as you say, the precision of bulk totals (such as disk free space) could be an issue. Happily, it isn't.

    A double has 52 bits of significand. For a counter reported in bytes this has room for 4 petabytes without any loss of precision.

    But disk free space is reported in megabytes, not bytes, so a double can report up to 272 bytes or 4 zettabytes with no loss of precision. And I'm pretty sure you can't have a single volume bigger than 264 bytes.

    Memory use (of processes and so) is reported in bytes but the values are always multiples of the page size (4096 bytes), so the bottom 12 bits of any reported value are zero. Hence a double can represent a memory size of up to 264 bytes - i.e. the entire 64-bit memory space - without loss of precision.

    Precision isn't a problem. Just use PDH_FMT_DOUBLE.