resource_plan: count physical cores on Windows (GetLogicalProcessorInformationEx)
os.cpu_count() returns logical processors, so on SMT machines the plan sets OMP_NUM_THREADS to 2 threads/core, which thrashes the AVX-512 units during expert matmul (9950X3D: 32 logical vs 16 physical). Count RelationProcessorCore records instead, with the existing lscpu/cpu_count fallbacks intact. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -167,6 +167,30 @@ def discover_gpus():
|
||||
|
||||
|
||||
def physical_cpu_count():
|
||||
if sys.platform == "win32":
|
||||
# os.cpu_count() conta i processori logici (SMT): 2 thread/core saturano
|
||||
# le unita' AVX-512 e peggiorano il matmul. Contiamo i core fisici veri
|
||||
# con GetLogicalProcessorInformationEx(RelationProcessorCore).
|
||||
try:
|
||||
import ctypes
|
||||
k32 = ctypes.windll.kernel32
|
||||
need = ctypes.c_ulong(0)
|
||||
k32.GetLogicalProcessorInformationEx(0, None, ctypes.byref(need))
|
||||
buf = (ctypes.c_char * need.value)()
|
||||
if k32.GetLogicalProcessorInformationEx(0, buf, ctypes.byref(need)):
|
||||
raw, cores, off = bytes(buf), 0, 0
|
||||
while off + 8 <= need.value:
|
||||
relationship = int.from_bytes(raw[off:off + 4], "little")
|
||||
size = int.from_bytes(raw[off + 4:off + 8], "little")
|
||||
if size <= 0:
|
||||
break
|
||||
if relationship == 0: # RelationProcessorCore
|
||||
cores += 1
|
||||
off += size
|
||||
if cores:
|
||||
return cores
|
||||
except (OSError, ValueError, AttributeError):
|
||||
pass
|
||||
try:
|
||||
result = subprocess.run(["lscpu", "-p=core,socket"], text=True,
|
||||
capture_output=True, check=True, timeout=5)
|
||||
|
||||
Reference in New Issue
Block a user