python - 为什么不是 numpy.mean 多线程?

标签 python multithreading performance numpy

我一直在寻找方法来轻松地对一些简单的分析代码进行多线程处理,因为我注意到 numpy 它只使用一个内核,尽管它应该是多线程的。

我知道 numpy 是为多个内核配置的,因为我可以看到使用 numpy.dot 的测试使用了我所有的内核,所以我只是将 mean 重新实现为一个点积,它运行得更快。是否有某种原因意味着无法自行运行这么快?我发现较大数组的行为类似,尽管该比率比我的示例中显示的 3 接近 2。

我一直在阅读大量关于类似 numpy 速度问题的帖子,显然它的方式比我想象的要复杂。任何见解都会有所帮助,我宁愿只使用均值,因为它更具可读性且代码更少,但我可能会切换到基于点的均值。

In [27]: data = numpy.random.rand(10,10)

In [28]: a = numpy.ones(10)

In [29]: %timeit numpy.dot(data,a)/10.0
100000 loops, best of 3: 4.8 us per loop

In [30]: %timeit numpy.mean(data,axis=1)
100000 loops, best of 3: 14.8 us per loop

In [31]: numpy.dot(data,a)/10.0 - numpy.mean(data,axis=1)
Out[31]: 
array([  0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
         0.00000000e+00,   1.11022302e-16,   0.00000000e+00,
         0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
        -1.11022302e-16])

最佳答案

I've been looking for ways to easily multithread some of my simple analysis code since I had noticed numpy it was only using one core, despite the fact that it is supposed to be multithreaded.

谁说它应该是多线程的?

numpy主要设计为在单核上尽可能快,并且在需要时尽可能可并行化。但是你仍然需要并行化它。

特别是,您可以同时对独立的子对象进行操作,并且缓慢的操作会在可能的情况下释放 GIL——尽管“尽可能”可能还不够。另外,numpy对象被设计为尽可能容易地在进程之间共享或传递,以方便使用multiprocessing .

有一些专门的方法可以自动并行化,但大多数核心方法不是。特别是,dot尽可能在 BLAS 之上实现,并且 BLAS 在大多数平台上自动并行化,但是 mean用纯 C 代码实现。

Parallel Programming with numpy and scipy了解详情。


那么,您如何知道哪些方法是并行化的,哪些不是?而且,在那些不是,你怎么知道哪些可以很好地手动线程化,哪些需要多处理?

对此没有好的答案。您可以做出有根据的猜测(X 似乎可能是在 ATLAS 之上实现的,而我的 ATLAS 副本是隐式线程的),或者您可以阅读源代码。

但通常情况下,最好的办法是尝试并测试。如果代码使用 100% 的一个内核和 0% 的其他内核,请添加手动线程。如果它现在使用 100% 的一个内核和 10% 的其他内核并且几乎没有运行得更快,请将多线程更改为多处理。 (幸运的是,Python 使这非常容易,特别是如果您使用 concurrent.futures 中的 Executor 类或 multiprocessing 中的 Pool 类。但是您仍然经常需要考虑一下,并测试共享与共享的相对成本。如果您有大型数组,则通过。)

另外,正如 kwatford 指出的那样,仅仅因为某些方法似乎不是隐式并行的,并不意味着它不会在下一个版本的 numpy 或下一个版本的 BLAS 中或在不同的平台,甚至在安装了稍微不同的东西的机器上。所以,准备重新测试。并执行类似 my_mean = numpy.mean 的操作然后使用 my_mean无处不在,因此您只需将一行更改为 my_mean = pool_threaded_mean .

关于python - 为什么不是 numpy.mean 多线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16617973/

相关文章:

java - 带 ArrayBlockingQueue 的 ThreadPoolExecutor

java - java中如何停止一个线程

linux - 如何在性能测试期间监控 cpu 使用率和网络使用率

java - 确定数字是否为 2 的幂的最有效编程方法是什么?

performance - JMeter 不记录任何客户端服务器事件

python - 在哪里克隆 Python 模块 git 存储库?

python - 如何替换所有未出现在预定义字符串/列表中的符号?

javascript - 当满足条件时在python中执行javascript

python - 通过 VS Code 部署 Azure Function V2 : Cannot see list of functions

c++ - 从两个线程访问计数器