我目前在python中使用线程功能,并得到以下信息:
In [1]:
import threading
threading.activeCount()
Out[1]:
4
现在在我的终端上,我使用lscpu并了解到每个内核有2个线程,并且我可以访问4个内核:
kitty@FelineFortress:~$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 8
On-line CPU(s) list: 0-7
Thread(s) per core: 2
Core(s) per socket: 4
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 60
Stepping: 3
CPU MHz: 800.000
BogoMIPS: 5786.45
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 8192K
NUMA node0 CPU(s): 0-7
因此,我应该有4个以上的线程可以访问。我是否可以使用python函数来增加正在使用的内核数(带有示例)以获取4个以上的线程?甚至在启动ipython笔记本时在终端上键入以下内容:
ipython notebook n_cores=3
您可以使用多重处理来允许Python使用多个内核。只是一个很大的警告:在Python会话之间传递的所有数据必须是可腌制的或通过继承传递的,并且在Windows上生成了一个新的Python实例,而在Unix系统上则可以对其进行分叉。这在Windows系统上具有显着的性能影响。
以下是“本周的Python模块”中使用多重处理的一个基本示例:
import multiprocessing
def worker():
"""worker function"""
print 'Worker'
return
if __name__ == '__main__':
jobs = []
for i in range(5):
p = multiprocessing.Process(target=worker)
jobs.append(p)
p.start()
执行后,输出:
Worker
Worker
Worker
Worker
Worker
多重处理使您可以在不同的内核上进行独立的计算,从而使CPU绑定任务以很少的开销比传统进程更快地执行。
您还应该认识到Python中的线程并不能提高性能。它的存在是为了方便(例如在长时间计算期间保持GUI的响应能力)。原因是由于Python的Global Interpreter Lock或GIL导致这些线程不是本机线程。
这仍然非常适用,并将在可预见的将来使用。Cpython实现使用以下定义进行引用计数:
typedef struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} PyObject;
值得注意的是,这不是线程安全的,因此必须实现全局解释器锁,以仅允许一个线程与Python对象一起执行,以避免数据争用导致内存问题。
除了多重处理(这需要Windows上解释器的完整副本,而不是fork,这使其非常慢且无法改善性能)之外,还有许多工具可以尝试避开全局解释器锁定。
您最简单的解决方案是Cython。只需cdef一个没有任何内部对象的函数,然后使用with nogil
关键字释放GIL 。
来自文档的一个简单示例,向您展示了如何释放和临时重新启用GIL:
from cython.parallel import prange
cdef int func(Py_ssize_t n):
cdef Py_ssize_t i
for i in prange(n, nogil=True):
if i == 8:
with gil:
raise Exception()
elif i == 4:
break
elif i == 2:
return i
CPython有一个GI,而Jython和IronPython没有。请注意,因为许多用于高性能计算的C库可能不适用于IronPython或Jython(SciPy早已支持IronPython,但很早就删除了它,并且在现代Python版本中不起作用)。
MPI(或消息传递接口)是用于C和C ++等语言的高性能接口。它允许高效的并行计算,并且MPI4Py为MPI for Python创建绑定。为了提高效率,您应该仅将MPI4Py与NumPy数组一起使用。
他们的文档中的一个示例是:
from mpi4py import MPI
import numpy
def matvec(comm, A, x):
m = A.shape[0] # local rows
p = comm.Get_size()
xg = numpy.zeros(m*p, dtype='d')
comm.Allgather([x, MPI.DOUBLE],
[xg, MPI.DOUBLE])
y = numpy.dot(A, xg)
return y
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句