【问题标题】:How to use C extensions in python to get around GIL如何在 python 中使用 C 扩展来绕过 GIL
【发布时间】:2011-03-31 16:18:52
【问题描述】:

我想在 Python 中跨多个内核运行一个 CPU 密集型程序,并试图弄清楚如何编写 C 扩展来执行此操作。有这方面的代码示例或教程吗?

【问题讨论】:

    标签: python python-c-extension


    【解决方案1】:

    您已经可以将 Python 程序分解为多个进程。操作系统已将您的进程分配给所有内核。

    这样做。

    python part1.py | python part2.py | python part3.py | ... etc.
    

    操作系统将确保该部分使用尽可能多的资源。您可以通过在sys.stdinsys.stdout 上使用cPickle 轻松地沿此管道传递信息。

    如果没有太多工作,这通常会导致显着的加速。

    是的——对讨厌的人来说——有可能构建一个如此折磨的算法,以至于它可能不会加速太多。然而,这通常会为最少的工作带来巨大的好处。

    还有。

    为此目的的重组将完全匹配最大化线程并发所需的重组。所以。从无共享进程并行开始,直到您可以证明共享更多数据会有所帮助,然后转向更复杂的无共享线程并行。

    【讨论】:

      【解决方案2】:

      看看multiprocessing。一个经常被忽视的事实是,操作系统更喜欢不全局共享数据,也不将大量线程塞进一个进程中。

      如果您仍然坚持您的 CPU 密集型行为需要线程,请查看working with the GIL in C 的文档。信息量很大。

      【讨论】:

      • 我在尝试使用多处理与线程时遇到的最大问题是,在尝试运行 1000 多个线程(进程)时,每个线程都会获得一个单独的 Python 解释器实例。这在内存方面变得非常昂贵。
      • @nalroff:这听起来不对。大多数解释器使用的内存由该解释器的所有实例共享。只有不同的页面才会增加总内存使用量。确保您正在查看正确的值。还值得注意的是,进程使用的内存并不比额外线程多得多。
      • 在我使用 Python 中的多处理模块的每个实例中,我总是看到进程和线程之间的内存使用量存在巨大差异。无论如何,threading 模块似乎对于网络应用程序的线程化网络抓取和性能测试来说足够快,这就是我使用它的全部。
      【解决方案3】:

      这是一个很好的使用C扩展。您应该搜索的关键字是Py_BEGIN_ALLOW_THREADS

      http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock

      附:我的意思是,如果您的处理已经在 C 中,例如图像处理,那么释放 C 扩展中的锁定是好的。如果你的处理代码主要是Python,其他人建议multiprocessing更好。用 C 语言重写代码以进行后台处理通常是不合理的。

      【讨论】:

        【解决方案4】:

        您是否考虑过使用诸如mpi4py 之类的python mpi 库之一?尽管 MPI 通常用于跨集群分配工作,但它在单个多核机器上运行良好。缺点是您必须重构代码以使用 MPI 的通信调用(这可能很容易)。

        【讨论】:

          【解决方案5】:

          多处理很容易。如果这还不够快,那你的问题就很复杂了。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-10-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-07-29
            • 1970-01-01
            相关资源
            最近更新 更多