News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

switching process to another logical processor

Started by vogelsang, June 07, 2013, 12:42:37 AM

Previous topic - Next topic

vogelsang

hi guys,

How to switch process to another logical processor? I need to enumerate all logical processors in my process. Could someone give some hints how to do it. I know this needs setting affinity masks. I've read about it on MSDN. But i'm not sure do i understand it right. Could someone explain me what exactly are doing subrutines such as GetCurrentProcess, GetProcessAffinityMask, SetProcessAffinityMask, SetThreadAffinityMask.

thanks in advance

dedndave

http://msdn.microsoft.com/en-us/library/windows/desktop/ms684841%28v=vs.85%29.aspx

for processes, GetProcessAffinityMask, SetProcessAffinityMask
you will want to use GetCurrentProcess, to get the process handle

for threads, SetThreadAffinityMask - the initial thread affinity is that of the process that created it
when you use CreateThread, it returns a thread handle
or, you can use GetCurrentThread

http://msdn.microsoft.com/en-us/library/windows/desktop/ms683179%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683213%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686223%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683182%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682453%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms686247%28v=vs.85%29.aspx

the affinity mask is a bit mask
if you have 4 logical processors, the system affinity mask would probably be 1111 b (0Fh)
if you want to select processor # 0 only, set it to 1
if you want to select processor # 1 only, set it to 2,
if you want to select processor # 2 only, set it to 4, and so on

for processes, the bit mask you select must be a subset of the system affinity mask
for threads, the bit mask you select must be a subset of the process affinity mask
if you try to select an invalid mask, nothing happens and GetLastError returns ERROR_INVALID_PARAMETER

if you have more than 32 logical processors, things get messy - lol

vogelsang

so first i must use GetCurrentProcess. this will give me hProcess to GetProcessAffinityMask. by that i'll get SystemAffinityMask and ProcessAffinityMask.  now i must iterate SetProcessAffinityMask with shifting value 1 by 1 as parameter dwProcessAffinityMask. I must also compare it if not exceeded SystemAffinityMask. do i understand it right?

dedndave

well - in a way
no need for shifting   :P
    .DATA?

hProcess   dd ?
dwSystMask dd ?
dwProcMask dd ?

    .CODE

    INVOKE  GetCurrentProcess
    mov     hProcess,eax
    INVOKE  GetProcessAffinityMask,eax,offset dwProcMask,offset dwSystMask

;at that point, you'll know:
;1) which logical cores are available in the system
;2) which logical cores the current process is using
;generally, these will be the same


you can select any combination of bits that is a subset of the system affinity mask
you must, of course, select at least one logical processor to be valid

let's say we just want core 0
    INVOKE  SetProcessAffinityMask,hProcess,1

normally, this is a valid selection, as all computers have a core 0
and, unless you have started the process with that core disabled, it will be available

vogelsang

thanks for now dedndave. i think this is what i needed.

vogelsang

Hi again,
I asked earlier how to switch logical processors, but what to do if there is more than 32 logical processors in computer. Dedndave mentioned something about it, but i was not familiar with this issue, so i didn't asked about it.
Next question: is there any function to get number of physical package(cpu) or other way to get this number?

thanks in advance

dedndave

first of all, it is going to be EXTREMELY rare that you see a computer with more than 32 processors
the only place you might see them is server farms, or something similar - and they won't be running windows - lol
besides the fact that manufacturers aren't likely to spend the time to overcome the hardware issues,
microsoft licenses the operating systems on a per-package basis (i think 2 packages is the limit - maybe 4)

secondly, such a computer would only be fully supported under windows 7 or newer
i don't think the API functions of previous OS's were robust enough to really handle it

that having been said, there are several functions to look at
processors are divided into groups in such cases

http://msdn.microsoft.com/en-us/library/windows/desktop/ms686223%28v=vs.85%29.aspx

when you open that page, look on the left side
there are numerous process/thread functions to browse

for most practical software, you can use GetSystemAffinityMask and count bits to know how many logical processors a computer has
you can use CPUID to test for HyperThreading support (Intel only)
if hyperthreading is supported, there are 2 logical cores for each physical core
otherwise, the number of logical cores is the number of physical cores

trying to figure out how many packages there are can be a bit more involved
it may require ring 0 access to get the correct answer

Gunther

Dave,

Quote from: dedndave on June 25, 2013, 04:02:34 AM
you can use CPUID to test for HyperThreading support (Intel only)

I think it's available for AMD processors, too.

Gunther
You have to know the facts before you can distort them.

vogelsang

sorry for break - strom disconnected me...
so, if its extremly rare to meet multipackage computer and most of such cases will be on newer windows or even not on microsoft's OSes and geting number of physical CPU will require accessing ring 0 - this deterred me from trying to count the packages, but how to prepare algo to avoid checking multipackage computer or should i leave it and display message that program doesnt support multipackage systems and in such cases will display not reliable infos. i think the last solution will be possible and the best for me. any hints?

dedndave

as for packages, i wouldn't worry about it
it really doesn't affect software

what i do is use CPUID to see if it supports hyperthreading
and count bits in GetProcessAffinityMask system mask

that gives you physical cores and logical cores fairly easily

you have to get into the APIC stuff to go further - and some CPU's can "hide" the results you get
that's where ring 0 comes in - i.e., for some machines, it may require a driver to find out

so - who really cares if they have 4 cores in 2 packages or 4 cores in 4 packages - lol

vogelsang

Quoteso - who really cares if they have 4 cores in 2 packages or 4 cores in 4 packages - lol

unfortunately it is important to my program. Its CPUID program. I already made this stuff with extracting sub IDs from APIC ID.
What means:
Quoteand some CPU's can "hide" the results you get

dedndave

that was an over-simplifcation

actually, i forget all the details, now
but, a few years ago i was working on something like that
and i gave up on it because, to do a complete job, you need ring 0
and - newer OS's have WHQL - so i said, ok - simple is good enough - lol

http://www.masmforum.com/board/index.php?topic=13044.0

that thread will be of interest to you, as it shows results on several machines   :t

vogelsang

thanks for now. I'll ask when i'll get confused again.