2014-04-22 259 views
1

我目前正在使用Python中的minmax树ai。为了从ai中挤出额外的性能,我一直在使用cython来优化瓶颈,并试图对树木进行多处理。使用cython进行缓慢多处理

我遇到的问题是,使用cython进行多处理时,ai确实比较慢。我知道有多处理的开销,有时会导致它变慢。但是,使用cython时只会变慢。当使用等效的Python代码时,多处理提供了2-3倍的性能提升。

我已经运行了几个测试来排除任何明显的问题。例如,我运行了启用和不启用alpha-beta修剪的测试(在没有多处理的情况下,这可能会在某些情况下执行得更好),但它没有区别。我已经将cython对象设置为pickleable,并且多处理的cython ai构建了一个适当的树。我正在使用的多处理实现(仅将根子项传递给pool.map函数)只会在使用纯Python代码时提高性能。

有没有一些古怪的cython,我失踪了?通过多处理使用cython代码(或一般的c扩展)会带来额外的开销吗?或者这是cython本身的问题?

编辑:下面是一些示例定时:

鉴于7的深度,并且没有α-β修剪:(所有时间以秒计)

用Cython,无多处理:
12.457

用Cython,多重:
15.440

没有用Cython,没有多重:
26.010

没有用Cython,多重:
17.609

多的测试之后,我已经找到了开销的原因。 @Veedrac是正确的,因为使用c扩展会带来额外的开销,而python的缓慢掩盖了没有cython的开销。具体而言,从多个处理器返回分支并将其添加到根节点时发生开销。这解释了为什么开销不是恒定的,并且随着树的深度增加而实际扩大。

我实际上已经怀疑过这一点,并且在此之前进行了测试。然而,看起来我之前用来测试这个开销的代码是被窃听的。我现在已经修复了多处理,只返回了必要的信息,并且开销已经被消除了。具有多处理功能的Cython现在运行速度非常快。

+0

你看过[Cython分析](http://docs.cython.org/src/tutorial/profiling_tutorial.html)吗? – Schollii

+0

@Schollii我试着分析多处理代码,但它似乎不能很好地处理多处理。它只显示占用所有程序时间的thread.lock。 – PaintingInAir

+0

@PaintingInAir看看[在这个答案](http://stackoverflow.com/a/22839233/832621),展示了如何在Cython的prange()中包装openMP,使用'nogil'函数 –

回答

1

如果您在C和Python类型之间过多,Cython可能会产生翻译成本,这可能会有所贡献。还有一个事实是Python的加速比将会更高,其中隐藏了的开销。

一个建议是使用nogil函数,看看threading是否具有较低的开销。

+0

不幸的是,第一部分尝试多线程大量使用python对象,如果没有gil就不能访问或修改它。 – PaintingInAir

+0

什么样的Python对象? – Veedrac