- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在玩 concurrent.futures.ThreadPoolExecutor 看看我是否可以从我的四核处理器(具有 8 个逻辑内核)中挤出更多的工作。所以我写了下面的代码:
from concurrent import futures
def square(n):
return n**2
def threadWorker(t):
n, d = t
if n not in d:
d[n] = square(n)
def master(n, numthreads):
d = {}
with futures.ThreadPoolExecutor(max_workers=numthreads) as e:
for i in e.map(threadWorker, ((i, d) for i in range(n))):
pass # done so that it actually fetches each result. threadWorker has its own side-effects on d
return len(d)
if __name__ == "__main__":
print('starting')
print(master(10**6, 6))
print('done')
有趣的是,同样的功能,当写在 for 循环中时大约需要一秒钟:
>>> d = {}
>>> for i in range(10**6):
... if i not in d: d[i] = i**2
... 而线程池代码需要超过 10 秒。现在我知道它至少使用了 4 个线程,因为我看到每个内核上的处理器负载。但即使使用共享内存(我能理解为什么进程可能需要一段时间,因为内存复制),我觉得运行时的这种差异太大了。
有人知道为什么这会花这么长时间吗?看起来一个简单的平方运算,确实是高度可并行化的,真的不应该花这么长时间。可能是由于字典的数量(如果是这样,是什么导致那里速度变慢的原因?)?
技术细节:
最佳答案
与其他答案相反,我会声称这里的罪魁祸首不是 GIL(尽管这是一个问题),而是使用线程的开销。
在系统级线程之间产生和切换的开销很小(小于 1 毫秒),但仍然可能超过对单个整数求平方的成本。理想情况下,您希望在使用任何类型的并行性时将计算分成更大的部分(可能是一百万个整数的平方)。
如果您使用数字 Python 堆栈 (NumPy/Pandas/C/Fortran/Cython/Numba),则可以绕过 GIL。例如,以下函数将对数字数组求平方并释放 GIL。
import numpy as np
x = np.array(my_list)
import numba
@numba.jit(nogil=True)
def square(x):
for i in range(len(x)):
x[i] = x[i]**2
return x
或者大多数 numpy 操作释放 GIL
x = x**2
没有系统能够在仅对整数求平方的同时使用多个内核。您的 CPU 计算整数平方的速度远快于您的内存层次结构能够提供它们的速度。
关于python - concurrent.futures.ThreadPoolExecutor.map 比 for 循环慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21210254/
这是正确的吗? ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor)
我只是对我编写的一些代码感到非常困惑。我惊讶地发现: with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
我正在尝试同时使用 InheritableThreadLocal 和 ThreadPoolExecutor。 这是因为 ThreadPoolExecutor 为每个池重用线程(毕竟它是一个池),这意味
concurrent.futures.ThreadPoolExecutor 通过 传递 function 到执行器 executor.submit(my_function) 像这样: def my_f
将一个简单的测试程序放在一起,应该并行执行一些任务。每次我们提交6个任务,等待完成。然后,又提交了一组任务。 import java.util.concurrent.*; public class
我正在运行一段 python 代码,其中多个线程通过线程池执行程序运行。每个线程都应该执行一项任务(例如获取网页)。我想要做的是终止所有线程,即使其中一个线程失败。例如: with ThreadPoo
我有一个使用阻塞队列的ThreadPoolExecutor,并且正在尝试调试一个问题,在该问题中,我怀疑任务在ThreadPoolExecutor的队列中停留的时间太长,无法执行。我正在尝试验证这一理
我正在尝试使用 futures backport 包在 Python 中使用 ThreadPoolExecutor。然而,问题是所有线程都是同时执行的,所以没有实际的池化发生。更具体地说,我得到了该函
我有两个 list : a = [1, 2, 3, 4] b = [9, 8, 7, 6] 我希望将这两个列表的每个组合作为参数传递给我正在执行多线程处理的函数: def test(hello, wo
当我们谈论ThreadPoolExecutor时,核心池大小和最大池大小之间到底有什么区别? 可以用例子来解释吗? 最佳答案 来自this blog post : Take this example.
我对“concurrent.futures”的并行处理相当陌生,我正在测试一些简单的实验。我编写的代码似乎可以工作,但我不确定如何存储结果。我尝试创建一个列表(“ future ”)并将结果附加到该列
我审查了多线程,并尝试实现一个创建单独线程来运行收集进程的应用程序。该过程中的主要方法需要一个变量数组列表,我正在尝试找出一种将数组列表传递给每个线程的方法。 ApplicationContext c
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我需要读取一个大的 csv 文件(328 MB)并对其进行处理。每行的处理还包括调用 Web 服务。 我是第一次使用ThreadPoolExecutor。我的逻辑是,我将从 csv 中每 100 行吐
from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED def div_zero(x): print('I
我有一个带有 run 方法的类,该类的 main 方法中的计时器正在使用以下代码调用该类: Timer timer = new Timer(); timer.scheduleAtFixedRate(n
尝试调试竞争条件,其中我们的应用程序的轮询器线程之一永远不会返回,导致 future 的轮询器永远不会被调度。用抽象术语来说,在捕获问题时隐藏我们的业务逻辑,这就是我们的代码路径。 我们必须更新远程服
下面的错误是什么意思?我怎样才能恢复它? Exception in thread "UserActionProcessor-8811" java.util.concurrent.RejectedExe
我正在致力于增强现有的 Java 应用程序。该应用程序是一个消息处理器,每天处理数百万条消息。它基本上是使用 Core Java 编写的,线程和队列是使用 Collection 类实现的。 在此应用程
我想更新使用用户定义线程池的旧代码。我想使用 java ThreadPoolExecutor,但问题是发送到线程池的请求不是可运行的。有什么方法可以将 ThreadPoolExecutor 与现有请求
我是一名优秀的程序员,十分优秀!