【问题标题】:Does multi-threading help when the CPU utilization is already near 100%?当 CPU 利用率已经接近 100% 时,多线程是否有帮助?
【发布时间】:2015-01-05 15:44:43
【问题描述】:

我们有一个 python 程序,它读取大约 120,000 个 XML 文件,解析它们(使用 ElementTree),提取标签值(fromstring().findall())等。这需要很长时间。我们考虑使用线程并行化程序。但是top 显示这个单个进程的 CPU 消耗在 100% 左右。所以,我的问题是线程真的有帮助。我的直觉是线程只有在有空闲 CPU 时才有用。

我的系统配置是 -

pavan8085@Xeek:/media/pavan8085/Projects/Pavan/CompBio$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                4
On-line CPU(s) list:   0-3
Thread(s) per core:    2
Core(s) per socket:    2
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 69
Stepping:              1
CPU MHz:               782.000
BogoMIPS:              3392.44
Virtualization:        VT-x
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              3072K
NUMA node0 CPU(s):     0-3

PS:我对 Python 完全陌生。所以可能有一些特定于语言的技巧可以帮助提高速度。如果这是问题所在,我很乐意提供更多信息。

【问题讨论】:

  • Do some profiling 看看时间在哪里。
  • 另外,请确保您没有使用太多内存。您使用 fromstring 的事实意味着您一次至少将一个文件完全读入内存,这是没有理由的。如果您正在阅读所有这些内容,那么您的时间都可以花在交换上。

标签: python multithreading xml-parsing operating-system


【解决方案1】:

假设您使用的是标准 CPython 实现,多线程在这种情况下不太可能有帮助,因为它具有全局解释器锁并且 Python 中的线程不能同时运行。因此,您不能使用多个 CPU 内核。

XML 解析实际上非常昂贵,并且内置解析器不是最快的可用解析器。 Lxml 速度更快,但如果您愿意编写自己的与 C 或 C++ 库的绑定,还有更快的选择。

您可能想look here 或提出自己的基准。

您需要分析您的代码,但在使用 Python 分析工具时要小心,因为它们经常会被扩展模块弄糊涂,如果您正在解析您正在使用扩展模块的 XML,这很可能是这样。

同样取决于 XML 的结构,解析 XML 文件通常不利于并行性。你可能会有很多共享状态。如果您正在处理 XML 并对每个元素执行一些操作,那么这些操作更有可能是可并行化的工作,因为您可以独立地执行每个操作。我会根据您的分析显示的内容在那儿花费我的精力。

【讨论】:

    【解决方案2】:

    关于 Python 和并发以及 Python 和 XML 处理的三件事:

    1. Python 的多线程功能仅限于处理 IO 绑定操作。如需更多解释,请查看“全局解释器锁”或“GIL”。相反,当您有多个 CPU 时,要拆分并同时处理 CPU 密集型工作,请使用 multiprocessing 模块
    2. 当需要更快地处理大型 XML 文件时,您不想使用在纯 Python 中实现的ElementTree。 CPython 附带了一个用 C 编写的相同 API 的实现,名称为 cElementTree。它将执行得更快。
    3. 虽然 cElementTree 速度很快,但同样实现 elementtree API 的世界标准 lxml 库仍然更快。它的安装相对简单,具体取决于您的操作系统。

    查看https://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers,了解将工作分散到工作进程池中的简单方法。

    【讨论】:

    • 第 2 点仅在 Python 2.x 中为真;在 3.x 中,ElementTree 自动使用 C 加速器。
    • 此外,虽然 lxml 通常比 stdlib 的 C 实现更快,但并非总是如此,因此值得同时尝试和测试。
    【解决方案3】:

    肯定是因为这里最可能的瓶颈实际上是 I/O 而不是 CPU。因此,您在这里所做的是按顺序处理每个文件,因此每次等待从磁盘读取文件时,您都会遇到瓶颈,阻止一切发生。如果您使用了多个线程,您可以同时处理多个文件,并且在一个等待 I/O 的同时可以处理其余的文件。

    这很好地解释了为什么 I/O 阻塞会导致 CPU 使用率过高http://www.chileoffshore.com/en/interesting-articles/126-linux-wait-io-problem

    仅仅因为它是 100% 并不意味着它在这段时间内实际上在做计算工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-28
      • 2019-09-12
      • 1970-01-01
      • 2014-03-22
      • 1970-01-01
      相关资源
      最近更新 更多