1

在最新的 Python 的 C API 中是否有可能使用所有 CPU 内核?

由于 GIL Python 一次只能使用一个 CPU 内核,因此在多核机器上性能较低。

但是 C API 在一个 C++ 程序中具有多个解释器的可能性并没有得到充分证明。

是否有可能通过合并多个解释器,甚至每个 C++ 线程一个解释器,在每个线程/解释器中拥有单独的 GIL,从而允许使用单独的内核运行每个 C++ 线程,从而使用所有 100% 的 CPU 性能?

文档中说,如果我理解正确,一个程序中只有一个 GIL,所以Py_NewInterpreter()创建的不同解释器共享相同的 GIL,并且它们都不能有单独的 GIL。这意味着如果我获得 GIL,那么所有其他解释器都将被阻止。也许我错误地解释了文档......

该任务是这样的,在我想执行PyRun_String(...)的每个单独线程中的 C++ 程序中,所有线程都不会共享任何内容。如果有帮助,每个这样的 PyRun_String() 都可以在单独的解释器中运行。

因为所有 C++ 线程不共享任何东西(因此不共享 PyObject * 实例),也许根本不获取 GIL?我不知道 Python C API 的全局状态(全局变量)是否需要 GIL 保护?也许只需要保护 PyObject * 实例,因此如果 C++ 线程不共享 PyObject* 那么可能不需要获取 GIL,有人知道吗?

当然,我知道可以产生多个运行这个 C++ 程序的进程。但是现在我想了解任务(使用所有 100% CPU 内核)是否可以在一个 C++ 进程中解决。

我也在想也许可以通过下一个解决方案:Python C API 是通过 链接的python39.lib,它有一些全局 C 变量,这些全局变量保持 C 解释器的状态。也许有可能以某种方式链接库,使所有全局变量都进入某个可重定位区域,以便稍后在每个 C++ 线程中,我使用全局变量创建单独的内存区域。因此,每个线程都将拥有其全局变量的副本,从而导致每个线程中的解释器状态完全分离。但是我不知道有什么方法可以使全局变量为单个给定.lib文件重定位,你知道有什么方法吗?

4

2 回答 2

1

目前,cpython 为所有解释器使用一个共享 GIL。运行 python 代码时需要持有 GIL 以保护内部结构。因此,即使在单独的解释器中,python 代码也不能同时执行。

Python 3.10 将对此提供不完整的支持([subinterpreters] Meta issue: per-interpreter GIL),但需要在构建时使用--experimental-isolated-subinterpreters.

于 2021-02-01T15:25:57.177 回答
0

在最新的 Python 的 C API 中是否有可能使用所有 CPU 内核?

不,不容易。我假设一个 Linux 系统(根据你的操作系统调整我的答案)。

您可以使用Pthreads在 C 中编写一些扩展,或者使用C++ 线程在 C++ 中编写一些扩展,或者运行多个 Python 进程(例如与unix(7)套接字或fifo(7) ...)

请注意,Python 实现是开源软件。您可以研究它并改进它以实现您的目标。

于 2021-01-14T13:03:10.410 回答