Intel® Moderncode for Parallel Architectures
Support for developing parallel programming applications on Intel® Architecture.

How to detect active core

dpotages
Beginner
537 Views

Hi,

For some reasons, i need to be able to detect the current active core, ie the one on which my code is currently running. Sounds like a basic thing, but really don't find a way to do it...

For info I'm running on WinXP/Vista, with several multicore computers, so any generic answer would be more than welcome.

Thanks in advance for any tip!

/david

0 Kudos
8 Replies
jimdempseyatthecove
Honored Contributor III
537 Views

David,

If you have access to Visual Studion C++ there are several functions to look at.

First thing to know is WinXP/Vista use logical processor information structures where core association is not necessarily in sequential order. HT capable processors as well as dual/quad core processors complicate issues.

The WindowsC++ library has a system function call GetLogicalProcessorInformation. Look up this function in your MSDN if you have it or Google for it

"GetLogicalProcessorInformation site:microsoft.com"

You are warned against calling this function directly since your application with the call may be running ona version of the O/S that does not have this function. To accomidate ths, it is recommended to make a system call to check for and obtain the address of this function. (returns NULL if not available.) If you receive the address of the function then you use this address to make the call.

The information returned by GetLogicalProcessorInformation is complex but the documentation will guide you in the right direction.

Alternately you can use the __cpuid function call

This function is processor dependent. Anything WinXP runs on is likely to support this function however the return data is processor dependent. Various flavors of Intel processors return different extents of data and AMD,Transmeta and other "x86" processors have different return values. So there is no simple answer.

Additionaly, the __cpuid will return the information regarding the processor your code was on at the moment of the CPUID instruction. If your application affinity is not locking you to a specific logical processor then the data returned from CPUID could refer to a different processor (i.e. when your code is examining the return data your thread could have migrated to a different processor). Similar thing with GetLogicalProcessorInformation.

The information returned from GetLogicalProcessorInformationwill remain static from boot time (unless your system permits hot-swap of processors available on some servers) but unless your thread has it's affinity locked to a logical processor you won't know which processor you are running on (logical or physical).

There is your tip (of the iceburg).

Jim Dempsey

0 Kudos
dpotages
Beginner
537 Views

Hi Jim,

Thanks alot for you detailled answer.

So to sum it up, there's no proper way on XP+vista to determine on which LP a thread is currently running, when this thread has not its affinity locked to a specific LP. That would indeed explain why i don't find a solution to that :)

Well i'll find out an alternative solution to my problem, thanks for the tip!

/david

0 Kudos
jimdempseyatthecove
Honored Contributor III
537 Views

Why not use Affinity to lock the thread to s specific (list of) processor(s)?

What it sounds like is you want an after the fact thing. This may require you to hook into the O/S thread scheduler. Something not for the timid.

You can statistically sample which CPU the thread is running on (as with a thread profiler), but this will not give you an absolutely correct assessment. Sometimes "good enough approximation" is good enough.

For your desktop machine try using CPUID with EAX=1 and use the high byte of EBX. This is the APIC ID field. This may be good enough to identify the processor at the time of the CPUID. Do not assume APIC ID is sequentially numbered. Make an array of 256 counters (64-bit), initialize all to 0. Then in your app, periodically poll with CPUID, use the APIC ID as an index, then accumulate runtime ticks using interlocked add. With long enough run times you should get a good enough statistical sample.

Jim Dempsey

0 Kudos
dpotages
Beginner
537 Views
Hi Jim, Among several other things, I was trying to run several instances of the same program, with each instance locked to one core, ideally the one on which the main thread was running on. I actually solved the problem by using named mutex to "lock" the cores, so that if one process crashed, the lock was automatically released. Thanks for the tips, the "good enough approximation" is indeed a solution for some of my other problems, but that's another story :) /david
0 Kudos
jimdempseyatthecove
Honored Contributor III
537 Views

David,

When a thread with an affinity lockcrashes there is nothing to hold the lock. Note, affinity lock does not exclude other threads (of your or other apps) from using the processor(s) in the affinity. Your main thread should know when one of it's spawned threads crashes. You don't need a mutex for that. Using an "I'm still running" mutex probably has no disadvantage so changing the code would have no benefit.

I made this suggestion to a different thread. I will rephrase it here.

Have the control thread spawn a new thread without affinity selected. I would imagine that each spawned thread has some major loop. In the major loop, have each thread determine if it is running without an affinity selected. (static bool or int) if not, determine the processor it is currently running on, tick a counter specific to the processor. Continue running without affinity setting until one of the counters reaches a threshold (could be 1).When the threshold is reached, set the thread'saffinity to that processor.

The main thread, in addition to it's other duties, monitors thread toprocessor association. Having more than one thread assigned to one processor is OK if you have more assigned threads than processors. As threads retire or expire the main control thread might notice one processor having fewer than the average number of thread assignments and a different processor having more than the average number of thread assignments. The main thread would then notify (via shared variable)one of the threads in the more than group to releaseits affinity association and then re enable the favorable affinity discovery routine.

A few shared variables and a tad of code is all it takes.

Jim Dempsey

0 Kudos
dpotages
Beginner
537 Views
Hi Jim, > Your main thread should know when one of it's spawned threads crashes. I indeed wasn't clear enough when i explained my problem, let's put it on the fact i'm really tired, deadline's coming faaast :) Okay, now i'll try to use the right words: i have an application that can be started several times by the user. This application spawn several threads, and their processor usage really vary with time. I wanted a simple solution to lock each application's main thread to a specific core (as according to my benchmarks that greatly improves the overall speed). The mutex solution was the simplest way i found to workaround the fact that the application may crash, and that the threads constantly used to be rescheduled to other LP due to their non constant CPU usage in some cases. I like the ideas of having a controlling thread and using the cpu usage sampling, even though as i said earlier the processor usage varies a lot. Moreover each process would need regularly check if there's a "controlling thread" active, and i can't have a separate application. If i got some free time before my milestone, i'll try it out. /david
0 Kudos
jimdempseyatthecove
Honored Contributor III
537 Views

David,

System
Application Process 1instance ("main thread")
worker thread 1.1
...
worker thread 1.n
Application Process2instance ("main thread")
worker thread 2.1
...
worker thread 2.n
...
Application Processminstance ("main thread")
...

Where "controlling thread" code is included in all Application Processes (peer managed) but performed by one of the Application Processes worker threads.

What I would suggest doing (you probably figured this out already) is to use a named mutex for purpose of the "controlling thread". Then when an Application Processbegins always start the controlling thread which creates/opens thenamed mutex andgets blocked on named mutex if mutex held by another application thread. Then if later, the application holding the named mutex exits or crashes, the named mutex is released and if another application is running, its "controlling thread" takes over. There is no need to check for "controlling thread" active since if any application is running then there is always a controlling thread active.

Inter-Application Process communication would use pipe, disk file, or memory mapped file.

The situation is not as easy as described above. Your prior posts indicated that your Application Process is susceptible to crashing. In which case your "controlling thread" code must be written with this consideration in mind. If the "controlling thread" monitors progress and accepts guidance controls (dialog box input) then there is likely little to no defensive code to write. If the "controlling thread" takes an active part in populating a database then you may have a significant chore ahead in writing defensive code.

Good luck, and sorry about the deadline pressure.

Jim Dempsey

0 Kudos
dpotages
Beginner
537 Views
Thanks for all the tips Jim :)
0 Kudos
Reply