Pasted below is the code from Intel to determine the number of physical CPUs on a Windows System. The affinity stuff looks like the only non portable code. Short of hacking the Kernel to expose the information it looks like I am out of luck. Thanks, Ken //---------------------------------------------------------------------- --------------------------- // // Copyright C 2001, Intel Corporation . Other brands and names may be claimed as the property of others. // // // CPU Counting Utility // Date : 10/30/2001 // Version: 1.4 // // // // File Name: CPUCount.cpp // // Note: 1) LogicalNum = Number of logical processors per PHYSICAL PROCESSOR. If you want to count // the total number of logical processors, multiply this number with the total number of // physical processors (PhysicalNum) // // 2) To detect whether hyper-threading is enabled or not is to see how many logical ID exist // per single physical ID in APIC // // 3) For systems that don't support hyper-threading like AMD or PIII and below. the variable // LogicalNum will be set to 1 (which means number of logical processors equals to number of // physical processors.) // // 4) Hyper-threading cannot be detected when application cannot access all processors in // the system. The number of physical processors will be set to 255. Make sure to enable ALL // physical processors at startup of windows, and applications calling this function, CPUCount, // are NOT restricted to run on any particular logical or physical processors(can run on ALL // processors.) // // 5) Windows currently can handle up to 32 processors. // // //---------------------------------------------------------------------- --------------------------- #define HT_BIT 0x10000000 // EDX[28] Bit 28 is set if HT is supported #define FAMILY_ID 0x0F00 // EAX[11:8] Bit 8-11 contains family processor ID. #define PENTIUM4_ID 0x0F00 #define EXT_FAMILY_ID 0x0F00000 // EAX[23:20] Bit 20-23 contains extended family processor ID #define NUM_LOGICAL_BITS 0x00FF0000 // EBX[23:16] Bit 16-23 in ebx contains the number of logical // processors per physical processor when execute cpuid with // eax set to 1 #define INITIAL_APIC_ID_BITS 0xFF000000 // EBX[31:24] Bits 24-31 (8 bits) return the 8-bit unique // initial APIC ID for the processor this code is running on. // Default value = 0xff if HT is not supported // Status Flag #define HT_NOT_CAPABLE 0 #define HT_ENABLED 1 #define HT_DISABLED 2 #define HT_SUPPORTED_NOT_ENABLED 3 #define HT_CANNOT_DETECT 4 unsigned int HTSupported(void); unsigned char LogicalProcPerPhysicalProc(void); unsigned char GetAPIC_ID(void); unsigned char CPUCount(unsigned char *, unsigned char *); #include <windows.h> #include <stdio.h> void main(void) { unsigned char LogicalNum = 0, // Number of logical CPU per ONE PHYSICAL CPU PhysicalNum = 0, // Total number of physical processor HTStatusFlag = 0; printf("CPU Counting Utility\n"); printf("Version 1.4\n"); printf("Copyright (C) 2001 Intel Corporation. All Rights Reserved\n\n"); HTStatusFlag = CPUCount(&LogicalNum, &PhysicalNum); switch(HTStatusFlag) { case HT_NOT_CAPABLE: printf("Hyper-threading technology not capable\n"); break; case HT_DISABLED: printf("Hyper-threading technology disabled\n"); break; case HT_ENABLED: printf("Hyper-threading technology enabled\n"); break; case HT_SUPPORTED_NOT_ENABLED: printf("Hyper-threading technology capable but not enabled\n"); break; case HT_CANNOT_DETECT: printf("Hyper-threading technology cannot be detected\n"); break; } printf("Number of logical processors per physical processor: %d\n", LogicalNum); if (PhysicalNum != (unsigned char)-1) printf("Number of physical processors: %d\n", PhysicalNum); else { printf("Can't determine number of physical processors\n"); printf("Make sure to enable ALL processors\n"); } printf("\n\nPress Enter To Continue\n"); getchar(); } unsigned int HTSupported(void) { unsigned int Regedx = 0, Regeax = 0, VendorId[3] = {0, 0, 0}; __try // Verify cpuid instruction is supported { __asm { xor eax, eax // call cpuid with eax = 0 cpuid // Get vendor id string mov VendorId, ebx mov VendorId + 4, edx mov VendorId + 8, ecx mov eax, 1 // call cpuid with eax = 1 cpuid mov Regeax, eax // eax contains family processor type mov Regedx, edx // edx has info about the availability of hyper-Threading } } __except (EXCEPTION_EXECUTE_HANDLER) { return(0); // cpuid is unavailable } if (((Regeax & FAMILY_ID) == PENTIUM4_ID) || (Regeax & EXT_FAMILY_ID)) if (VendorId[0] == 'uneG') if (VendorId[1] == 'Ieni') if (VendorId[2] == 'letn') return(Regedx & HT_BIT); // Genuine Intel with hyper-Threading technology return 0; // Not genuine Intel processor } unsigned char LogicalProcPerPhysicalProc(void) { unsigned int Regebx = 0; if (!HTSupported()) return (unsigned char) 1; // HT not supported // Logical processor = 1 __asm { mov eax, 1 cpuid mov Regebx, ebx } return (unsigned char) ((Regebx & NUM_LOGICAL_BITS) >> 16); } unsigned char GetAPIC_ID(void) { unsigned int Regebx = 0; if (!HTSupported()) return (unsigned char) -1; // HT not supported // Logical processor = 1 __asm { mov eax, 1 cpuid mov Regebx, ebx } return (unsigned char) ((Regebx & INITIAL_APIC_ID_BITS) >> 24); } unsigned char CPUCount(unsigned char *LogicalNum, unsigned char *PhysicalNum) { unsigned char StatusFlag = 0; SYSTEM_INFO info; *PhysicalNum = 0; *LogicalNum = 0; info.dwNumberOfProcessors = 0; GetSystemInfo (&info); // Number of physical processors in a non-Intel system // or in a 32-bit Intel system with Hyper-Threading technology disabled *PhysicalNum = (unsigned char) info.dwNumberOfProcessors; if (HTSupported()) { unsigned char HT_Enabled = 0; *LogicalNum= LogicalProcPerPhysicalProc(); if (*LogicalNum >= 1) // >1 Doesn't mean HT is enabled in the BIOS // { HANDLE hCurrentProcessHandle; DWORD dwProcessAffinity; DWORD dwSystemAffinity; DWORD dwAffinityMask; // Calculate the appropriate shifts and mask based on the // number of logical processors. unsigned char i = 1, PHY_ID_MASK = 0xFF, PHY_ID_SHIFT = 0; while (i < *LogicalNum) { i *= 2; PHY_ID_MASK <<= 1; PHY_ID_SHIFT++; } hCurrentProcessHandle = GetCurrentProcess(); GetProcessAffinityMask(hCurrentProcessHandle, &dwProcessAffinity, &dwSystemAffinity); // Check if available process affinity mask is equal to the // available system affinity mask if (dwProcessAffinity != dwSystemAffinity) { StatusFlag = HT_CANNOT_DETECT; *PhysicalNum = (unsigned char)-1; return StatusFlag; } dwAffinityMask = 1; while (dwAffinityMask != 0 && dwAffinityMask <= dwProcessAffinity) { // Check if this CPU is available if (dwAffinityMask & dwProcessAffinity) { if (SetProcessAffinityMask(hCurrentProcessHandle, dwAffinityMask)) { unsigned char APIC_ID, LOG_ID, PHY_ID; Sleep(0); // Give OS time to switch CPU APIC_ID = GetAPIC_ID(); LOG_ID = APIC_ID & ~PHY_ID_MASK; PHY_ID = APIC_ID >> PHY_ID_SHIFT; if (LOG_ID != 0) HT_Enabled = 1; } } dwAffinityMask = dwAffinityMask << 1; } // Reset the processor affinity SetProcessAffinityMask(hCurrentProcessHandle, dwProcessAffinity); if (*LogicalNum == 1) // Normal P4 : HT is disabled in hardware StatusFlag = HT_DISABLED; else if (HT_Enabled) { // Total physical processors in a Hyper-Threading enabled system. *PhysicalNum /= (*LogicalNum); StatusFlag = HT_ENABLED; } else StatusFlag = HT_SUPPORTED_NOT_ENABLED; } } else { // Processors do not have Hyper-Threading technology StatusFlag = HT_NOT_CAPABLE; *LogicalNum = 1; } return StatusFlag; } > -----Original Message----- > From: redhat-devel-list-admin@redhat.com [mailto:redhat-devel-list- > admin@redhat.com] On Behalf Of Matt Wilson > Sent: Saturday, May 18, 2002 10:25 PM > To: redhat-devel-list@redhat.com > Subject: Re: Detecting number of Physical CPUs in Intel Hyperthreaded CPU > systems > > To really do this you need ACPI. Outside of ACPI there's no way to > tell if the logical CPUs are coming from one physical processor or > not. > > Cheers, > > Matt > > On Sat, May 18, 2002 at 07:15:54PM -0700, Ken Sheppard wrote: > > > > Does anyone know how I can determine the number of physical processors > > on a machine with Intel Hyperthreaded CPUs? I have code from Intel which > > will report the number of physical CPUs on a windows system. It uses the > > Win32 process affinity stuff to issue commands on specific CPUs so it > > isn't portable to Linux. I was hoping I could simply read /proc/cpuinfo. > > The /proc/cpuinfo I looked at on a 2.4.? machine didn't appear to have > > enough information. > > > > _______________________________________________ > Redhat-devel-list mailing list > Redhat-devel-list@redhat.com > https://listman.redhat.com/mailman/listinfo/redhat-devel-list _______________________________________________ Redhat-devel-list mailing list Redhat-devel-list@redhat.com https://listman.redhat.com/mailman/listinfo/redhat-devel-list