Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting... Please check out the Community Guidelines in the
Announcements and Administration Category, below.

How to find out TSC frequency?

Michael_RolleMichael_Rolle Posts: 69
On my computer, the TSC (time stamp counter) counts at 3.09 GHz. A call to QueryPerformanceFrequency, or the equivalent kernel side, returns 3.02 MHz. This differs by a factor of 1,024. That is, a system 'tick' is 1024 cycles of the TSC.

I want to set a kernel timer duration for a given number of cycles of the processor. I realize that these days, actual CPU clock speed varies, so I'm content to use the TSC speed, as when a program is running full tilt, the CPU will probably run at that speed (or more if overclocking is enabled).

Anyway, I don't want to assume that the system tick is always 1024 TSC cycles, and I don't want to start my driver spinning for awhile and comparing the difference in rdtsc () and KeQueryPerformanceCounter () intervals.

So, anyone know a way to get the TSC frequency from the system?

Comments

  • Tim_RobertsTim_Roberts Posts: 12,567
    On Mar 3, 2018, at 3:16 PM, xxxxx@rolle.name <xxxxx@lists.osr.com> wrote:
    >
    > On my computer, the TSC (time stamp counter) counts at 3.09 GHz. A call to QueryPerformanceFrequency, or the equivalent kernel side, returns 3.02 MHz. This differs by a factor of 1,024. That is, a system 'tick' is 1024 cycles of the TSC.

    No, the system tick is much, much longer than that. The QPF interval has no fundamental meaning in the system, except for that function. All you can say is that QPF bumps about 1,000 times less often than the cycle counter.


    > I want to set a kernel timer duration for a given number of cycles of the processor. I realize that these days, actual CPU clock speed varies, so I'm content to use the TSC speed, as when a program is running full tilt, the CPU will probably run at that speed (or more if overclocking is enabled).
    >
    > Anyway, I don't want to assume that the system tick is always 1024 TSC cycles, and I don't want to start my driver spinning for awhile and comparing the difference in rdtsc () and KeQueryPerformanceCounter () intervals.
    >
    > So, anyone know a way to get the TSC frequency from the system?

    What are you actually trying to accomplish here? Your request has no real-world value. The kernel timer granularity is nowhere NEAR as fine as either of the timekeeping functions. Kernel timer granularity (the "system tick") is measured in milliseconds, not nanoseconds. Even if you set a timer for 3 microseconds, which would be 1 QPF or 1,024 cycles, the interrupt isn't going to happen for many millions of cycles.

    Tim Roberts, xxxxx@probo.com
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • R0b0t1R0b0t1 Posts: 129
    On Sat, Mar 3, 2018 at 7:53 PM, xxxxx@probo.com <xxxxx@lists.osr.com> wrote:
    > On Mar 3, 2018, at 3:16 PM, xxxxx@rolle.name <xxxxx@lists.osr.com> wrote:
    >>
    >> On my computer, the TSC (time stamp counter) counts at 3.09 GHz. A call to QueryPerformanceFrequency, or the equivalent kernel side, returns 3.02 MHz. This differs by a factor of 1,024. That is, a system 'tick' is 1024 cycles of the TSC.
    >
    > No, the system tick is much, much longer than that. The QPF interval has no fundamental meaning in the system, except for that function. All you can say is that QPF bumps about 1,000 times less often than the cycle counter.
    >
    >
    >> I want to set a kernel timer duration for a given number of cycles of the processor. I realize that these days, actual CPU clock speed varies, so I'm content to use the TSC speed, as when a program is running full tilt, the CPU will probably run at that speed (or more if overclocking is enabled).
    >>
    >> Anyway, I don't want to assume that the system tick is always 1024 TSC cycles, and I don't want to start my driver spinning for awhile and comparing the difference in rdtsc () and KeQueryPerformanceCounter () intervals.
    >>
    >> So, anyone know a way to get the TSC frequency from the system?
    >
    > What are you actually trying to accomplish here? Your request has no real-world value. The kernel timer granularity is nowhere NEAR as fine as either of the timekeeping functions. Kernel timer granularity (the "system tick") is measured in milliseconds, not nanoseconds. Even if you set a timer for 3 microseconds, which would be 1 QPF or 1,024 cycles, the interrupt isn't going to happen for many millions of cycles.
    >

    I think the OP should look at the documentation for
    QueryPerformanceCounter and the informational page on why to avoid
    using the processor timestamps. It says that the performance counter
    may be based on timestamps, not that it will have the same resolution.

    It does not mention average resolution however, and I had no idea that
    what was available was not high resolution. So it would be possible to
    consider it misleading.

    For portability I would avoid relying on high resolution timers. Many
    developers remove them for security's sake, ignoring legitimate use.

    Cheers,
    R0b0t1
  • Here's why I am using timers.

    My driver manages the IBS (instruction-based sampling) features of the AMD processors.

    Normally, the way to use it is that every time it gathers some information, it signals an interrupt and waits until the information is read by the cpu and sampling is re-enabled by the cpu.

    I've been having trouble with interrupt storms (apparently) and various bugchecks when I use an ISR to handle this work. So as a fallback, I'm using a timer Dpc to poll the hardware.

    Ideally, I'd like to poll the hardware often, say, at microsecond intervals, but alas, I'm limited to polling at 1 msec intervals by the OS. It's better than nothing, and I can test the code that manipulates the IBS hardware without the complications of using an ISR.

    This driver is not for publication (at least not for now), and so you're right that it's not something I would want a driver to do in a production environment.

    I also did not realize that functions like KeSetTimer are based on interrupts from the system clock (1 msec on my system), so I was puzzled that I wasn't getting nearly as many data samples from the driver as I was expecting. I assumed that Windows, like realtime operating systems, would program something like the APIC timer to interrupt after intervals shorter than the system clock; I see I was wrong.
  • Here's your problem:

    ...I assumed that Windows, like realtime operating systems, ...

    Windows is not an RTOS.

    ---
    NTDEV is sponsored by OSR

    Visit the list online at: <http://www.osronline.com/showlists.cfm?list=ntdev>;

    MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
    Details at <http://www.osr.com/seminars>;

    To unsubscribe, visit the List Server section of OSR Online at <http://www.osronline.com/page.cfm?name=ListServer>;
  • R0b0t1R0b0t1 Posts: 129
    On Sun, Mar 4, 2018 at 8:36 AM, xxxxx@PDQ.NET <xxxxx@lists.osr.com> wrote:
    >
    > Here's your problem:
    >
    > ...I assumed that Windows, like realtime operating systems, ...
    >
    > Windows is not an RTOS.
    >

    In his defence I think Linux can do this, but you may need to be root.
  • Loren_WiltonLoren_Wilton Posts: 447
    If it is of any use to you, the following registry value seems tobe a
    reasonably accurate description of the RDTSC frequency in MHz:

    "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\\~MHz"

    You can of course develop this value yourself without a lot of work, but the
    system does it for you at boot and stuffs it here. Assuming a system with an
    invariant timestamp counter this value should only be inaccurate by the
    amount of rounding to MHz and/or by the results of temperature drift on the
    crystal. If you don't have an invariant TSC all bets are off, of course.

    This doesn't help you in the slightest with your timer interrupt interval
    problem. The best you can do is approximately 1ms, as others have noted, and
    this requires changing the system time period, which can easily be done from
    userland. I don't recall if there is a way to do it from kernel mode, I've
    never had occasion to try to find such an interface. I don't know if you
    have solved this problem youself, or if it just happens that you have
    something running on your system that has done timeBeginPeriod (1) (or the
    lower-level equivilent) If you want to depend on an interrupt faster than
    15.625ms you need to see to it yourself.

    Loren
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!