Python 是否可以在多个内核上运行依赖于上一个任务的程序?
我有一个非常大的python程序,需要几个小时才能完成,运行在一个内核上 有什么方法可以在我的电脑上的所有8个i7内核之间进行分割吗 唯一的问题是任务依赖于前面的计算,例如,下面是我的代码的简化版本:Python 是否可以在多个内核上运行依赖于上一个任务的程序?,python,python-3.x,multiprocessing,Python,Python 3.x,Multiprocessing,我有一个非常大的python程序,需要几个小时才能完成,运行在一个内核上 有什么方法可以在我的电脑上的所有8个i7内核之间进行分割吗 唯一的问题是任务依赖于前面的计算,例如,下面是我的代码的简化版本: def code(nums): num = 1 for loop in range(nums): num += num * loop return num 然后使用 我可以在TaskManager上观察CPU的使用量(大约12%),这表明它只使用了一个内核
def code(nums):
num = 1
for loop in range(nums):
num += num * loop
return num
然后使用
我可以在TaskManager上观察CPU的使用量(大约12%),这表明它只使用了一个内核
有没有办法让这段代码在多个核上运行
注意:我遇到的主要困难是它依赖于前面的结果,因此我无法将代码拆分为多个部分
编辑:
我正在Windows 10上使用Python3
编辑2:
如果可能的话,你能写出上面的代码是否是我的完整代码的解决方案吗?首先,拿一支笔和一张纸,把计算过程记在心里。是否有任何步骤可以并行 否则,就不可能使用多核 如果是,请仔细检查并行步骤需要什么,是否所有步骤都可以并行取决于同一个步骤?还是取决于不同的步骤 如果是。。。如果不是 总之,在并行计算之前,首先需要为计算构建一个拓扑图,以便找到可以在哪里进行计算、需要什么以及如何进行计算。Python中的多处理 CPython是Python解释器最常见的实现,如果不使用Python的
multiprocessing
模块,它就不支持多处理。这是由于全局解释器锁(GIL)的引入,因为python内存不是线程安全的,因此即使是线程化
模块也不能真正实现并行代码。另一方面,多处理
模块启动了Python解释器的全新实例,由于它们不再共享GIL,因此可以真正跨多个核并行运行
因此,如果您希望运行一个利用多核的python程序,您必须手动将程序分解为子进程,每个子进程都可以在解释器的单独实例上运行。不过,一定要小心,因为以这种方式利用多个核心的好处可能会比在多个核心之间运行所带来的开销更高,但是这非常依赖于项目,所以您应该自己检查一下
资料来源:
你问题的可能解决方案
现在请耐心听我说,这里有几个数学步骤,但我相信有一种方法可以使代码并行化
首先以nums
的不同值的输出为例,看看代码的输出是什么:
nums | 1 | 2 | 3 | 4 | 5 | 6 |
-----------------------------------
out | 1 | 2 | 6 | 24 | 120 | 720 |
现在由于您的代码已经设置好,您可以看到code(nums)=code(nums-1)+code(nums-1)*(nums-1)
,因此如果我们可以找到一种从code(nums-1)
到code(nums)
的方法,而不需要知道code(nums-1)
的值,那么我们就可以并行化代码
如果我们考虑从代码>代码(NUS- 1)< /代码>到<代码>代码(NUMS)<代码>的差异,我们在上面的表中得到它们的不同的表:
nums | 1 | 2 | 3 | 4 | 5 | 6 |
-----------------------------------
diff | | 1 | 4 | 18 | 96 | 600 |
现在这些差异似乎并没有形成一种模式,但实际上有一点逻辑上的飞跃,您可以看到code(nums)
和code(nums-1)
之间的差异是(nums-1)*(nums-1)
(其中!
是数学阶乘函数)。因此,我们看到您的code
方法可以等价地写成:
from math import factorial
def code(nums):
num = 1
for i in range(1, nums):
num += i * factorial(i)
return num
现在,我们可以从中并行化您的代码。我们将使用带有8个进程池的多处理
模块(以匹配您的8个内核),并将所需工作的一部分映射到每个内核上,允许它们计算所需的值,然后将结果相加,然后只需在结果中加1,即可算出num
的初始值
from math import factorial
from multiprocessing import Pool, freeze_support
NUM_CORES = 8
def foo(lower, upper):
sum = 0
for i in range(lower, upper):
sum += i * factorial(i)
return sum
def code(nums):
# Build the list of arguments for the workers so that each gets 1/NUM_CORES of the work.
a, b = divmod(nums, NUM_CORES)
arguments = [(1,a)]
for c in range(2, NUM_CORES):
arguments.append(((c-1)*a, c*a))
arguments.append(((NUM_CORES - 1)*a, NUM_CORES*a + b))
print(arguments)
with Pool(processes=8) as pool:
results = pool.starmap(foo, arguments)
print(1 + sum(results))
if __name__ == '__main__':
freeze_support()
code(100)
需要底部
\uuuu main\uuuuu
块中的freeze\u support
调用,以便在code
方法中正确执行多处理。根据您拥有的示例函数,您可以将计算从0拆分为N/2,从N/2+1拆分为N(如果您想使用2个处理器)。最后总结一下。Python中有一个多处理包,可以让它在两个内核上运行。对于8个核,只需将计算分为整个数据块的1/8即可。@Spinor8这样将其分离是使其在多个核上运行的唯一方法吗?我这么问是因为我的计划很难分割。这非常复杂,幸运的是,您要求为特定程序提供特定的多处理解决方案,但只提供了一个抽象的通用示例。重写完全有可能消除程序中的一些相互依赖关系,但如果不更详细地查看代码,我们就没有什么可以帮助的了。@JakeConkerton Darby如果我这样说,怎么样:有没有办法让任何程序使用相同的方法在多个核上运行?e、 g.如果我在IPython中运行它,它将使用所有8个核(类似的东西,我不认为这是可行的哈哈)默认情况下不是。让python跨多个核运行的唯一方法(据我所知)是使用python中的多进程
模块将程序分解为子进程。这将允许您将程序分割成的各个部分独立运行,并利用多核。回答得很好。您是否能够提供这些步骤,以便使用多个进程运行我的示例代码?然后我可以把它标记为答案:)喂?有可能吗?喂?请回答:哦,令人惊讶的答案。非常
from math import factorial
from multiprocessing import Pool, freeze_support
NUM_CORES = 8
def foo(lower, upper):
sum = 0
for i in range(lower, upper):
sum += i * factorial(i)
return sum
def code(nums):
# Build the list of arguments for the workers so that each gets 1/NUM_CORES of the work.
a, b = divmod(nums, NUM_CORES)
arguments = [(1,a)]
for c in range(2, NUM_CORES):
arguments.append(((c-1)*a, c*a))
arguments.append(((NUM_CORES - 1)*a, NUM_CORES*a + b))
print(arguments)
with Pool(processes=8) as pool:
results = pool.starmap(foo, arguments)
print(1 + sum(results))
if __name__ == '__main__':
freeze_support()
code(100)