GeezerVison is showing github.com — os.cpu_count() returns wrong number of processors on system with > 64 logical processors · Issue #74766 · python/cpython
os.cpu_count() returns wrong number of processors on system with > 64 logical processors #74766Description
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
assignee = None
closed_at = <Date 2017-09-01.19:29:13.752>
created_at = <Date 2017-06-06.12:49:39.499>
labels = ['type-bug', '3.7', 'OS-windows']
title = 'os.cpu_count() returns wrong number of processors on system with > 64 logical processors'
updated_at = <Date 2017-12-01.09:45:38.001>
user = 'https://github.com/robbuckley'
bugs.python.org fields:
activity = <Date 2017-12-01.09:45:38.001>
actor = 'pitrou'
assignee = 'none'
closed = True
closed_date = <Date 2017-09-01.19:29:13.752>
closer = 'pitrou'
components = ['Windows']
creation = <Date 2017-06-06.12:49:39.499>
creator = 'robbuckley'
dependencies = []
files = ['46928']
hgrepos = []
issue_num = 30581
keywords = []
message_count = 18.0
messages = ['295254', '295255', '295258', '295365', '295377', '299462', '299476', '299477', '299480', '301017', '301018', '301033', '301146', '301147', '301150', '301151', '307374', '307376']
nosy_count = 10.0
nosy_names = ['paul.moore', 'pitrou', 'vstinner', 'giampaolo.rodola', 'tim.golden', 'zach.ware', 'steve.dower', 'tzickel', 'crwilcox', 'robbuckley']
pr_nums = ['2934', '3267']
priority = 'normal'
resolution = 'fixed'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue30581'
versions = ['Python 3.6', 'Python 3.7']
Activityrobbuckley commented on Jun 6, 2017 MannequinAuthor More actions os.cpu_count() seems to report incorrect values on windows systems with >64 logical processors
tried it on 2 similar systems, both running windows 7 / 10 with python 3.6.1 64bit (anaconda):
platform1 - 2x Xeon E5-2698v4. 20 cores/CPU = total 80 logical cpus with hyperthreading
platform2 - 2x Xeon E5-2697v3. 14 cores/CPU = total 56 logical cpus with hyperthreading
os.cpu_count() reports 40 cores on platform1 and 56 on platform2
I would expect 80 and 56 respectively.
I suppose this is because the windows api call used is not aware of processor groups, and reports only the number of processors in the current processor group ( eg GetSystemInfo vs GetMaximumProcessorCount ) vstinner commented on Jun 6, 2017 On Windows, os.cpu_count() is currently implemented with:
"GetSystemInfo(&sysinfo); return sysinfo.dwNumberOfProcessors;"
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724958(v=vs.85).aspx
It seems to return the number of *logical* CPUs:
"""
dwNumberOfProcessors
The number of logical processors in the current group.
Note: For information about the physical processors shared by logical processors, call GetLogicalProcessorInformationEx with the RelationshipType parameter set to RelationProcessorPackage (3).
"""
It seems like you have two physical CPU packages. Maybe the function only returns infos from the first package? robbuckley commented on Jun 6, 2017 MannequinAuthor More actions yes, i believe its reporting the number of processors in the current group only, not across all groups.
attached output of windows sysinternals/coreinfo showing 2 processor groups
see giampaolo/psutil#771 for some further disucssion of this topic
the maintainer of psutil asked me to raise this bug, also had a quick check on #python IRC. Its my first bug on bugs.python.org so if you need more info just let me know crwilcox commented on Jun 7, 2017 I am going to work on this if no one else has started. giampaolo commented on Jun 7, 2017 giampaolo commented on Jul 29, 2017 crwilcox commented on Jul 29, 2017 I agree that the MS Docs for this are a bit confusing. I ended up reaching out to the guy who authored the GetMaximumProcessorCount function. I had also written an implementation that iterated over GetProcessorInformationEx and he advised against it.
One of the things that makes this interesting is that in 32 bit processes (wow64) your processor is simulated to fit in the confines of that old system. This method will only report 32 cores under 32 bit as that is all the program can access in 32 bit mode. giampaolo commented on Jul 29, 2017 About GetMaximumProcessorCount, MS doc states that it returns the "maximum number of logical processors that a processor group or the system can have", so maybe it also includes "empty" CPU sockets.
GetActiveProcessorCount, on the other hand, returns "the number of active processors in a processor group or in the system", which adds even more confusion. crwilcox commented on Jul 29, 2017 I was reviewing the docs for the os module and cpu_count should always return the number of cpus on the system, not the usable CPUs. GetMaximumProcessorCount returns a simulated count in WoW64. I have reached back out to the Windows API dev and will see if GetLogicalProcessorInformationEx will allow us to do this. He had thought that my solution that way had other limitations under WoW64. pitrou commented on Aug 30, 2017 New changeset c67bae0 by Antoine Pitrou (Christopher Wilcox) in branch 'master':
bpo-30581: Windows: os.cpu_count() returns wrong number of processors (bpo-2934)
c67bae0 pitrou commented on Aug 30, 2017 Fixed. Someone might backport this to 3.6 if they want. vstinner commented on Aug 30, 2017 I reopen the issue to backport the bugfix to 3.6. pitrou commented on Sep 1, 2017 pitrou commented on Sep 1, 2017 Backport merged. Thanks Chris! tzickel commented on Sep 1, 2017 pitrou commented on Sep 1, 2017 robbuckley commented on Dec 1, 2017 MannequinAuthor More actions hi,
as the reporter i just want to say this is working for me with 3.6.3.
Regarding https://bugs.python.org/issue30581#msg301150, I take your point that a lot of multiprocessing using the standard libraries may not benefit, as processes may be restricted to the processor group of the parent process (python).
For my use case it works well: I launch a queue of blocking jobs, using a thread pool. Each thread launches 1 jobsubprocess.subprocess.run(), where the thread pool size is equal to number of processors reported by os.cpu_count(). Since the OS controls the scheduling in this case, it works perfectly well with 2 processor groups.
thanks :-) pitrou commented on Dec 1, 2017 Thanks for the heads up Rob!
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|