Note from jkriegshauser: This code sample does not work as expected on Multi-core processors (i.e. Core2 Duo/Quad, etc). The reason is because the newer multi-core processors define the HTT flag as "hardware multithreading" and the logical processor count will include the cores even though Core2 Duo processors do not have HTT. See the following Intel publications:
Intel Processor Identification and the CPUID Instruction: http://www.intel.com/assets/pdf/appnote/241618.pdf
Intel 64 and IA-32 Architectures Software Developer's Manual Vol 3A (section 7.10.2): http://www.intel.com/design/processor/manuals/253668.pdf
Also, the original MSDN article mentioned in this comment can be found here: http://msdn.microsoft.com/en-us/magazine/cc300701.aspx
The following code sample comes from "Juice Up Your App with the Power of Hyper-Threading", an MSDN article:
public void SetProcessAffinityToPhysicalCPUForHyperthreadOnly(int processid)
{
int res;
int hProcess;
int ProcAffinityMask = 0, SysAffinityMask = 0;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, processid);
res = GetProcessAffinityMask(
hProcess, ref ProcAffinityMask, ref SysAffinityMask);
if (SysAffinityMask == 3) // 1 proc, 2 logical CPUs
res = SetProcessAffinityMask(hProcess, 1);
else if (SysAffinityMask == 15) //dual proc, 4 virtual CPUs
res = SetProcessAffinityMask(hProcess, 3);
res = CloseHandle(hProcess);
}
From the sample above, we see that the affinity mask is such that all physical processors come first in the mask, then the logical (Hyper-threaded) processors.
If your process is a heavy user of floating point instructions, setting the affinity mask to (number of processors/2) - 1 will make sure your threads will give preference for the physical processors which have FPU.
For a sample on how to detect if Hyper-Thread is on in C/C++, you could use this:
__inline BOOL hyperThreadingOn()
{
DWORD rEbx, rEdx;
__asm {
push eax // save registers used
push ebx
push ecx
push edx
xor eax,eax // cpuid(1)
add al, 0x01
_emit 0x0F
_emit 0xA2
mov rEdx, edx // Features Flags, bit 28 indicates if HTT (Hyper-Thread Technology) is
// available, but not if it is on; if on, Count of logical processors > 1.
mov rEbx, ebx // Bits 23-16: Count of logical processors.
// Valid only if Hyper-Threading Technology flag is set.
pop edx // restore registers used
pop ecx
pop ebx
pop eax
}
return (rEdx & (1<<28)) && (((rEbx & 0x00FF0000) >> 16) > 1);
}