手动设置互斥可以提高性能吗?

2024-09-28 05:17:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我的python程序肯定是cpu受限的,但是40%到55%的时间是在z3解算器中的C代码中执行的(它对gil一无所知),每次调用C函数(z3_optimize_check)都要花费将近一分钟的时间来完成(到目前为止,parallel_enable参数仍然导致该函数在单线程模式下工作,并且堵塞主螺纹)。你知道吗

我不能使用多重处理,因为z3u对象是不可序列化友好的(除非这里有人能证明不是这样)。由于它们是多个任务(其中每个任务在dict中为其他任务添加更多的z3工作),我最初直接设置mulithreading。但是Gil对性能的伤害肯定大于它的好处(尤其是超读),尽管它花费了大量的时间在解算器上。你知道吗

但是,如果我在z3py模块中手动(通过threading.Lock.aquire())设置了一个阻塞互斥锁,就在从C代码切换之后,它只允许其他线程在所有其他线程都执行解算器工作的情况下运行,这会不会消除gil性能损失(因为它们在执行python代码时只有1个线程,而且总是这样)在z3_optimize_check之前释放锁之前是同一个吗?
我的意思是,使用threading.Lock.aquire()会不会触发对PyEval_SaveThread()的调用,就好像z3是直接做的一样?


Tags: 函数代码程序lockcheck时间cpu性能
1条回答
网友
1楼 · 发布于 2024-09-28 05:17:47

so far the parallel_enable parameter still result in this function working in single thread mode and blocking the main thread

我想你误解了。z3以并行模式运行意味着您从一个Python线程调用它,然后它为自己生成多个OS级线程,执行该任务,清理线程并为您返回结果。它不能奇迹般地使Python在没有GIL的情况下运行。
从Python的角度来看,它仍然一次只做一件事,那就是调用z3。它一直在控制着吉尔。因此,如果您看到在运行计算时使用了多个CPU核心/线程,这就是z3的并行模式的效果,即内部分支到多个线程。你知道吗

还有一件事,释放GIL,比如阻塞I/O操作。这不是魔法造成的,有一个呼叫对:

PyThreadState* PyEval_SaveThread()
Release the global interpreter lock (if it has been created) and reset the thread state to NULL, returning the previous thread state (which is not NULL). If the lock has been created, the current thread must have acquired it.

void PyEval_RestoreThread(PyThreadState *tstate)
Acquire the global interpreter lock (if it has been created) and set the thread state to tstate, which must not be NULL. If the lock has been created, the current thread must not have acquired it, otherwise deadlock ensues.

这些是C调用,因此扩展开发人员可以访问它们。当开发人员知道代码将运行很长时间,而不需要访问Python内部构件时,就可以使用PyEval_SaveThread(),然后Python可以继续处理其他Python线程。当长线程完成任何操作时,线程可以重新介绍自己并使用PyEval_RestoreThread()申请GIL。
但是,只有开发人员让这些事情发生,这些事情才会发生。而对于z3,情况可能并非如此。你知道吗

直接回答您的问题:不,Python代码不能释放GIL并使其保持释放状态,因为GIL是Python线程在运行时必须持有的锁。因此,每当Python“指令”返回时,GIL就会再次被持有。你知道吗


很明显,我设法不包含我想要的链接,所以它们在第https://docs.python.org/3/c-api/init.html#thread-state-and-the-global-interpreter-lock页(链接的段落讨论了我很快总结的内容)。你知道吗

Z3是开源的(https://github.com/Z3Prover/z3),源代码既不包含PyEval_SaveThread,也不包含包装快捷方式Py_BEGIN_ALLOW_THREADS字符序列。你知道吗


但是,它有一个并行Python示例,顺便说一句https://github.com/Z3Prover/z3/blob/master/examples/python/parallel.py,其中

from multiprocessing.pool import ThreadPool

所以我假设它可能会被测试并使用multiprocessing。你知道吗

相关问题 更多 >

    热门问题