Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

GetCurrentProcessorNumber() for XP?

278 views
Skip to first unread message

Ron Kuper

unread,
May 9, 2006, 3:11:03 PM5/9/06
to
We need a way to tell which logical processor the current thread is running
on. I see that GetCurrentProcessorNumber() exists but only for Server 2003
and Vista. We need an API like this on Win XP.

I did some web searching and learned that there is a way to do this using
CPUID, by manipulating the APIC ID and also knowing the number of physical
processors and number of cores per processor. However there is no clear
cookbook example that does exactly what GetCurrentProcessorNumber() does.

Does anyone have any pointers or code fragments for doing this?

Kellie Fitton

unread,
May 9, 2006, 4:15:17 PM5/9/06
to
Hi,

You can use the following APIs to retrieve information about
the current system, including the the number of processors in
the system:

GetSystemInfo()
GetNativeSystemInfo()

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getsysteminfo.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/getnativesysteminfo.asp

Hope these suggestions helps,

Kellie.

Ron Kuper

unread,
May 9, 2006, 4:32:02 PM5/9/06
to
Hi Kellie,

Thanks for the info, but it's not quite what I need. I already know about
these APIs, which tell me how many processors are on the system. What I need
to know (for my multithreaded app), is for a thread to query which processor
it is running on at any particular instance. IOW, I need
GetCurrentProcessorNumber() -- but on Win XP.

-Ron

Don Burn

unread,
May 9, 2006, 4:37:10 PM5/9/06
to
Ron,

The problem is that by the time you get the data it can be incorrect,
you call for the processor number and a scheduling event occurs and you
change processors. There is such a call in the kernel, but even there it
is of limited use unless you either block scheduling or set the threads
affinitiy to a specific processor.

--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Remove StopSpam from the email to reply


"Ron Kuper" <RonK...@discussions.microsoft.com> wrote in message
news:9F858DC7-F47F-4997...@microsoft.com...

Kellie Fitton

unread,
May 9, 2006, 4:48:49 PM5/9/06
to
Hi Ron,

How about the following API, you can explicitly decide on
which CPU each thread will be executed:

SetThreadIdealProcessor()

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/setthreadidealprocessor.asp

Kellie.

Ron Kuper

unread,
May 9, 2006, 5:00:06 PM5/9/06
to
Hi Don,

I know that the data might be incorrect. What we're trying to do is
implement an "approximate CPU meter" in our application (multithreaded
digital audio workstation). It doesn't have to be perfect. I just want to
know, before one of our threads starts performing expensive DSP, which CPU is
it running on, so that we can show a per-CPU measure. (Note I don't want to
use the APIs that perfom uses because that measures more overhead than I want
to provide.)

So back to the original question -- anybody have code to mimic what
GetCurrentProcessorNumber does?

-Ron

Ron Kuper

unread,
May 9, 2006, 5:00:06 PM5/9/06
to
No, that doesn't help. I don't want to force a thread to a processor. I
want to know, "which processor is this thread running on." IOW, I want
GetCurrentProcessorNumber for XP...

-Ron

Phil Wilson

unread,
May 9, 2006, 7:19:21 PM5/9/06
to
Isn't it NTGetCurrentProcessorNumber? (GetProcessorNumber etc on Vista).
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/ntgetcurrentprocessornumber.asp?frame=true
--
Phil Wilson [MVP Windows Installer]
----

"Ron Kuper" <RonK...@discussions.microsoft.com> wrote in message
news:8C8E4004-6152-4DC8...@microsoft.com...

Ron Kuper

unread,
May 9, 2006, 7:41:02 PM5/9/06
to
I tried NtGetCurrentProcessorNumber, too. That API is also only on Server
2003 and Vista, alas. :-(

frank

unread,
May 10, 2006, 10:55:02 AM5/10/06
to

take a look in <ntdd.h>

...

//
// Get the current processor number
//

__inline ULONG KeGetCurrentProcessorNumber(VOID)
{
__asm { movzx eax, _PCR KPCR.Number }
}

with

#define _PCR fs:[0]

...

Skywing

unread,
May 10, 2006, 11:07:08 AM5/10/06
to
That shall only work on kernel mode.

"frank" <fr...@discussions.microsoft.com> wrote in message
news:DB239684-C416-462A...@microsoft.com...

frank

unread,
May 10, 2006, 12:24:02 PM5/10/06
to

why not writing a little helper driver (the old style - not that wdm/kmdf
stuff), that does the KeGetCurrentProcessorNumber() call in a read request
(or ioctl) if he wants to know the number in ring3 ?

Pavel A.

unread,
May 12, 2006, 2:19:56 PM5/12/06
to
"frank" <fr...@discussions.microsoft.com> wrote in message news:C21625F3-41CD-448B...@microsoft.com...

> why not writing a little helper driver (the old style - not that wdm/kmdf
> stuff), that does the KeGetCurrentProcessorNumber() call in a read request
> (or ioctl) if he wants to know the number in ring3 ?

Because of the high overhead of kernel call.

--PA


Ron Kuper

unread,
May 12, 2006, 1:34:03 PM5/12/06
to
Thanks for the help, everyone. I figured out a way to do it.

The CPUID instruction, called with EAX=1, returns the APIC ID in the upper 8
bits of EBX. This isn't the processor number, but it is unique for each
logical CPU. I simply take that number and use a tiny map (implemented as
256 byte array) to map APIC ID -> processor number, i.e., if I don't see an
APIC ID in the map I increment a processor number counter and assign it to
the APIC ID. Does the trick, all in user mode, and quite efficient.

Steve Dispensa

unread,
May 13, 2006, 5:33:31 PM5/13/06
to
On 5/12/06 12:34 PM, in article
D203BD13-2430-4A4B...@microsoft.com, "Ron Kuper"
<RonK...@discussions.microsoft.com> wrote:

> Thanks for the help, everyone. I figured out a way to do it.
>
> The CPUID instruction, called with EAX=1, returns the APIC ID in the upper 8
> bits of EBX. This isn't the processor number, but it is unique for each
> logical CPU. I simply take that number and use a tiny map (implemented as
> 256 byte array) to map APIC ID -> processor number, i.e., if I don't see an
> APIC ID in the map I increment a processor number counter and assign it to
> the APIC ID. Does the trick, all in user mode, and quite efficient.

I'm sure you understand this already, but just for the record, the results
of your CPUID call can be wrong by the very next CPU instruction. There is
nothing stopping the OS from context switching away and scheduling you
elsewhere next time you come up for cycles. This will probably be right a
lot of the time, but it will be wrong some of the time.

Also, this is obviously not terribly portable or easy to maintain (no inline
ASM on x64, etc).

Otherwise, interesting solution.

-Steve

Skywing

unread,
May 13, 2006, 10:07:47 PM5/13/06
to
The former can be easily solved by taking the process affinity mask and then
in sequence setting a thread to be assigned to only one processor, executing
the appropriate cpuid instruction, then changing the affinity to the next
processor.

"Steve Dispensa" <disp...@positivenetworks.net> wrote in message
news:C08BBADB.AC51%disp...@positivenetworks.net...

Alexander Grigoriev

unread,
May 14, 2006, 10:01:46 AM5/14/06
to
Well, if you set the affinity, you know on what process you'll be running
and then there's no point whatsoever to query the processor number!

On the other hand, I think the problem being discussed (custom CPU meter of
an multimedia app) is not worth bothering. That's one of bells and whistles
without real return on investment, other than bragging rights of the
programmer.

"Skywing" <skywing_...@valhallalegends.com> wrote in message
news:O5suzsvd...@TK2MSFTNGP02.phx.gbl...

Pavel A.

unread,
May 14, 2006, 6:46:11 PM5/14/06
to
"Alexander Grigoriev" <al...@earthlink.net> wrote in message news:el$Cz71dG...@TK2MSFTNGP04.phx.gbl...

> On the other hand, I think the problem being discussed (custom CPU meter of an multimedia app) is not worth bothering. That's
> one of bells and whistles without real return on investment, other than bragging rights of the programmer.

Then... how you explain that this useless API that has no value but
bells and whistes has been added in win2003? What for?

--PA


Skywing

unread,
May 14, 2006, 7:23:56 PM5/14/06
to
You would set the affinity for each processor in sequence to build a mapping
of apic id to cpu number.

Then, later, when you execute cpuid on a thread with multiprocessor
affinity, you can map the returned id to say processor 0, processor 1, etc.

"Alexander Grigoriev" <al...@earthlink.net> wrote in message
news:el$Cz71dG...@TK2MSFTNGP04.phx.gbl...

Steve Dispensa

unread,
May 14, 2006, 11:12:14 PM5/14/06
to
Maybe I don't understand you here, Skywing, but it seems like you're just
building a one->one mapping of APIC ID to CPU number; that doesn't really
speak to whether or not the OS can context switch you immediately after the
instruction executes (but before the very next instruction executes),
causing an incorrect result.

The more I think about it, the more I think it'd be rather unlikely that the
answer would actually be wrong very often. This would only happen if your
quantum expires and if the OS then switches your thread as a result (which
is not necessarily the case). On an otherwise lightly loaded system, I bet
this is very accurate indeed. Good lord, how many instructions execute in
17ms or whatever the quantum is on the OS/computer in question... We're
probably talking about round-off error here.

And, I can't think of too many (any?) cases in which that level of
uncertainty would matter, and particularly not in the arena of perf
monitoring. Heck, the monitoring itself skews the results; a little extra
uncertainty about the active processor will probably just vanish in the
noise floor.

On 5/14/06 6:23 PM, in article #vMXfe7d...@TK2MSFTNGP03.phx.gbl,

Skywing

unread,
May 15, 2006, 9:32:42 AM5/15/06
to
No, of course it does not protect against potential inaccuracies after you
have a correct mapping of apic id to processor number.

The question was how to do something like GetCurrentProcessorNumber in user
mode on pre-Win2003 systems. By saving the apic id and then using the
mapping of apic id to processor number you can log which processor a thread
appeared to have been running on with a similar degree of accuracy as to
what GetCurrentProcessorNumber would have provided on more recent platforms.

"Steve Dispensa" <disp...@positivenetworks.net> wrote in message

news:C08D5BBE.AD2A%disp...@positivenetworks.net...

0 new messages