当前位置: 首页 > 面试题库 >

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

缑泓
2023-03-14
问题内容

我一直在寻找一些方法来轻松地对我的一些简单分析代码进行多线程处理,因为我注意到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])

问题答案:

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

谁说它应该是多线程的?

numpy主要是为了在单个内核上尽可能快地设计,并且在需要时尽可能并行化。但是您仍然必须并行化它。

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

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

有关详细信息,请参见使用numpy和scipy并行编程。

因此,您如何知道哪些方法是并行的,哪些不是?而且,在那些不是的情况下,您如何知道哪些可以很好地进行手动线程化,哪些需要进行多处理呢?

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

但是通常,最好的办法是尝试并测试。如果代码使用一个内核的100%,另一个内核的0%,请添加手动线程。如果现在使用的是一个内核的100%,另一个内核的10%,并且运行速度几乎不快,请将多线程更改为多处理。(幸运的是,Python使此操作非常容易,特别是如果您使用来自的Executor类concurrent.futures或来自的Pool类multiprocessing。但是,如果阵列很大,您仍然经常需要考虑一些问题,并测试共享与传递的相对成本。

而且,正如kwatford所指出的,仅仅因为某种方法似乎不是隐式并行的,并不意味着它在下一版numpy,下一版BLAS或另一平台上不会并行。即使在安装了稍微不同的东西的机器上。因此,准备重新测试。然后执行类似的操作my_mean = numpy.mean,然后my_mean在任何地方使用,因此您只需将一行更改为即可my_mean = pool_threaded_mean



 类似资料:
  • 本文向大家介绍请为什么说js是单线程,而不是多线程呢?相关面试题,主要包含被问及请为什么说js是单线程,而不是多线程呢?时的应答技巧和注意事项,需要的朋友参考一下 JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。 JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript

  • 我正在通过quartz调度程序调用spring批处理作业,它应该每1分钟运行一次。当作业第一次运行时,成功打开ItemReader并运行作业。但是,当作业尝试第二次运行时,它使用的是第一次运行的相同实例,该实例已经初始化,并接收“java.lang.IllegalStateException:Stream is eignitialized.Close before re-opening”。我已经将

  • 主要内容:1 什么是Java多线程,2 Java多线程的优点,3 进程与线程区别,4 Java Thread类,5 Java Thread类的方法1 什么是Java多线程 Java 多线程指的是同时执行多个线程的处理。 线程是轻量级子进程,是最小的处理单元。多处理和多线程都用于实现多任务。 但是,我们使用多线程而不是多进程,因为线程使用共享内存区域。它们不分配单独的内存区域,因此节省了内存,并且线程之间的上下文切换比进程花费的时间更少。 线程是轻量级子进程,是最小的处理单元。这是一条单独的执行路

  • 问题内容: 是当今的浏览器是否经过深思熟虑的设计决策或存在问题,这些问题将在以后的版本中得到解决? 问题答案: JavaScript不支持多线程,因为浏览器中的JavaScript解释器是单线程(AFAIK)。甚至谷歌浏览器也不允许单个网页的JavaScript同时运行,因为这会在现有网页中引起大量的并发问题。Chrome所做的全部工作就是将多个组件(不同的选项卡,插件等)分离到单独的进程中,但是

  • 问题内容: 我知道没有线程可以访问当前视图,除非它是UI线程。我想知道为什么?哪个线程更改视图为什么很重要?是出于安全原因吗?这是我使用的解决方法: 每当我想更改布局时,这样做都是一种痛苦。是否有其他解决方法?我了解异步任务,但从未找到一种使用它的好方法,它比我正在做的更好吗?所有相关的答案都适用! 问题答案: 是的,您的权利:为了安全起见,您不能在另一个线程上修改视图(这就是为什么将其称为UI线

  • 此答案指示如何将转换为,同时管理将发生阻塞的位置: 我的问题和评论中的问题一样: 怎么了?为什么你使用一个额外的线程与Promise结合? 答复如下: 它会在你拉线的时候卡住线。如果您已经为这样的未来配置了ExecutionContext,这很好,但是默认的ExecutionContext包含的线程与您拥有的处理器一样多。 我不确定我是否理解这个解释。重申: 有什么问题?在未来内部阻塞不是和手动创