python - Python 进程和线程如何映射到硬件线程?

标签 python multithreading concurrency hardware

我的问题类似于 this one ,但我正在寻找有关它如何使用的最新信息:

  • python
  • 在 Linux 上运行
  • 在线程多于内核的 CPU 上。

  • 例如,假设一个 CPU 有 4 个内核和 8 个线程,并给出以下代码:
    from multiprocessing.dummy import Pool as ThreadPool
    from multiprocessing import Pool as ProcessPool
    
    
    with ThreadPool(number_of_threads) as pool:
        pool.map(some_function, some_iterable)
    
    with ProcessPool(number_of_processes) as pool:
        pool.map(some_function, some_iterable)
    

    我想知道这些线程和进程将如何映射到 CPU 内核和线程,如果有的话。例如 :
  • 如果 number_of_processes 为 8,每个进程可能最终都在一个 CPU 线程上吗?
  • 如果 number_of_threads 为 8,每个线程可能最终都在 CPU 线程上吗?
  • 如果 number_of_threads 远高于核心/CPU 线程数,这意味着什么?
  • some_function 是受 IO 限制还是受 CPU 限制,对上述任何一项都有影响吗?

  • 我总是将 ThreadPool 用于 IO 绑定(bind),将 ProcessPool 用于 CPU 绑定(bind)。使用 ProcessPool,我发现使用与 CPU 内核相同的 number_of_processes 效果很好。但我不知道 ThreadPool 我的基准应该是什么。

    最佳答案

    我认为一个很大的免责声明是:理论上的“它应该如何工作”只会到目前为止。对于实际性能比较,即 4、6、8 或任意数量线程的线程池之间的性能差异,唯一的具体答案来自使用实际工作负载对目标系统进行基准测试。

    此处提供答案的最重要问题之一是:

    Does it make a difference to any of the above whether some_function is IO bound or CPU bound?



    这是 IMO 最重要的性能问题。您的工作量是多少 (some_iterable)?是 I/O 绑定(bind)还是 CPU 绑定(bind)? I/O 绑定(bind)是发出 http 请求,或查询数据库或文件系统。 CPU 限制正在执行某种计算、散列、添加、解析等。大多数工作负载(根据我的经验是混合的,但如果我不得不根据经验说,偏爱 I/O)。如果工作负载是 I/O 和 some_iterable正在执行同步 I/O,而您很可能通过创建更大的工作池来扩展性能,因为大多数时间进程/线程正在执行将花费在等待 I/O 上!

    If number_of_processes is 8, will each process likely end up on a cpu thread?



    种类:p。你有 8 个物理线程。每个池有 8 个进程/主线程,加上执行程序的线程,以及操作系统的所有其他进程/线程 :)。您的处理器已饱和。如果您有一个 CPU 绑定(bind)的工作负载,它们将会饱和,并且您可能不会看到超过 7-8 个池大小的性能提升。如果您的工作负载受 I/O 限制,您可能仍会看到池大小大于您拥有的处理器数量时性能提高。

    If number_of_threads is 8, will each thread likely end up on a cpu thread?



    与上面的处理器问题相同。是的,它们很可能最终会出现在 CPU 线程上。如果您的工作负载受 I/O 限制,则增加池大小可能仍会在一段时间内提高性能。
    对于受 CPU 限制的工作负载,这就是事情变得复杂的地方。 Python的GIL prevents python from executing multiple python bytecode at once .即使您将有足够的物理 CPU 线程来执行您的程序,但您一次只能执行一个线程!如果 CPU 绑定(bind)的工作负载 number_of_threads,我会感到惊讶。 = 8 提供比 number_of_threads 更好的性能= 4 用于 CPU 绑定(bind)的工作负载!

    What are the implications if number_of_threads are much higher than the number of cores/cpu threads?



    对于 I/O 绑定(bind)的工作负载,什么都没有!根据您的机器调度和执行大量线程的能力或上游服务为您发出的所有请求提供服务的能力,您有时会遇到性能限制。对于受 CPU 限制的工作负载,请参阅上面的答案(由于 GIL,您会更快地达到限制)。

    引用:
  • How to utilize all cores with python multiprocessing
  • How to pin different processes to individual cpu cores in Python


  • 同样,在我主要从事基于 http 的服务的经验中,将逻辑核心(硬件线程)视为与物理核心相同,并没有回来咬我。因此,在您的情况下,我只会认为您有 8 个可用内核。区别可能对您的工作量不重要(在黑暗中拍摄)?

    关于python - Python 进程和线程如何映射到硬件线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59408539/

    相关文章:

    .net - 这种情况下需要STA消息循环吗?

    c# - 为什么对级联 ManualResetEvent 的多次等待会使执行时间增加三倍?

    java - 由于 ehcache,许多并发读取 + 一个写入导致 ObjectNotFoundException

    kotlin - Kotlin:在列表 “in parallel”上应用暂停功能?

    java - 使用双重检查阻塞方法实例化单例

    WPF ObservableCollection 不更新?

    python - 误解 web.py 应用程序

    python - Python 中 Win32_ComputerSystem 的 __name__ 属性?

    python - 在给定高度和值的情况下递归生成三角形格式的列表列表

    python - Perl 6 的 comb 方法在 Python 中的等价物是什么?