【问题标题】:Portable way of detecting number of *usable* CPUs in Python在 Python 中检测 * 可用 * CPU 数量的便携式方法
【发布时间】:2015-09-29 13:39:35
【问题描述】:

根据这个问题和答案 -- Python multiprocessing.cpu_count() returns '1' on 4-core Nvidia Jetson TK1 -- Python 的 multiprocessing.cpu_count() 函数在某些系统上的输出反映了活跃的 CPU 数量正在使用,而不是实际的 CPU 数量可供调用的 Python 程序使用

一个常见的 Python 习惯用法是使用cpu_count() 的返回值来初始化Pool 中的进程数。但是,在使用这种“动态 CPU 激活”策略的系统上,这种习惯用法的破坏性相当严重(至少在相对静止的系统上)。

是否有一些直接(且可移植)的方法可以从 Python 获取可用处理器的数量(而不是当前使用的数量)?

注意事项:

  1. How to find out the number of CPUs using python 的已接受答案未回答此问题,因为如 问题顶部链接的问题中所述,打印 /proc/self/status 的内容显示所有4 个内核可供程序使用。

  2. 在我看来,“便携”不包括任何涉及解析 /proc/self/status 内容的方法,其格式可能因 Linux 发行版而异,甚至在 OS X 上都不存在。(任何其他伪文件也是如此。)

【问题讨论】:

    标签: python cpu


    【解决方案1】:

    我认为你不会得到任何真正可移植的答案,所以我会给出一个正确的答案。

    Linux 的正确* 答案是len(os.sched_getaffinity(pid)),其中pid 可能是当前进程的0。此函数在 Python 3.3 及更高版本中公开;如果你更早需要它,你将不得不做一些花哨的cffi 编码。

    编辑:您可能会尝试查看是否可以使用函数 int omp_get_num_procs();(如果存在),这是我在 this question 上找到的唯一有意义的答案,但我还没有在 Python 中尝试过。

    【讨论】:

    • 该死,我很讨厌,我使用的是 Python 2.7。 :-) 暂时搁置(得到了真正的可交付成果,你知道吗?),但最终我可能会深入研究cffi,这给了我一个很好的尝试案例。
    【解决方案2】:

    使用psutil:

    来自文档https://psutil.readthedocs.io/en/latest/

    >>> import psutil
    >>> psutil.cpu_count()
    4
    >>> psutil.cpu_count(logical=False)  # Ignoring virtual cores
    2
    

    这是便携的

    【讨论】:

      【解决方案3】:

      在实现sched_getaffinity 和 Windows 的系统上,这是一种获取当前进程可用 CPU 内核数的方法:

      import ctypes
      import ctypes.wintypes
      import os
      from platform import system
      
      
      def num_available_cores() -> int:
          if hasattr(os, 'sched_getaffinity'):
              return len(os.sched_getaffinity(0))
          elif system() == 'Windows':
              kernel32 = ctypes.WinDLL('kernel32')
              DWORD_PTR = ctypes.wintypes.WPARAM
              PDWORD_PTR = ctypes.POINTER(DWORD_PTR)
              GetCurrentProcess = kernel32.GetCurrentProcess
              GetCurrentProcess.restype = ctypes.wintypes.HANDLE
              GetProcessAffinityMask = kernel32.GetProcessAffinityMask
              GetProcessAffinityMask.argtypes = (ctypes.wintypes.HANDLE, PDWORD_PTR, PDWORD_PTR)
              mask = DWORD_PTR()
              if not GetProcessAffinityMask(GetCurrentProcess(), ctypes.byref(mask), ctypes.byref(DWORD_PTR())):
                  raise Exception("Call to 'GetProcessAffinityMask' failed")
              return bin(mask.value).count('1')
          else:
              raise Exception('Cannot determine the number of available cores')
      

      在 Linux 和任何其他实现 sched_getaffinity 的系统上,我们使用 Python 的内置包装器。

      在 Windows 上,我们使用 ctypes 调用 GetProcessAffinityMask

      据我所知,没有用户 API 或工具可以在 macOS 上获取/设置 CPU 亲和性。在大多数情况下,os.cpu_count() 可以正常工作,但如果您确实需要 可用 内核的数量,那么您可能会不走运。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-24
        • 2013-05-19
        • 2010-11-30
        • 1970-01-01
        • 2018-06-09
        • 2010-11-11
        • 2016-06-20
        • 2013-11-16
        相关资源
        最近更新 更多