我有一个 Python 程序,它基本上执行以下操作:
for j in xrange(200):
# 1) Compute a bunch of data
# 2) Write data to disk
1) 大约需要 2-5 分钟
2) 大约需要 ~1 分钟
请注意,要保存在内存中的数据太多。
理想情况下,我想做的是以避免 CPU 空闲的方式将数据写入磁盘。这在 Python 中可能吗?谢谢!
我有一个 Python 程序,它基本上执行以下操作:
for j in xrange(200):
# 1) Compute a bunch of data
# 2) Write data to disk
1) 大约需要 2-5 分钟
2) 大约需要 ~1 分钟
请注意,要保存在内存中的数据太多。
理想情况下,我想做的是以避免 CPU 空闲的方式将数据写入磁盘。这在 Python 中可能吗?谢谢!
您可以尝试使用这样的多个进程:
import multiprocessing as mp
def compute(j):
# compute a bunch of data
return data
def write(data):
# write data to disk
if __name__ == '__main__':
pool = mp.Pool()
for j in xrange(200):
pool.apply_async(compute, args=(j, ), callback=write)
pool.close()
pool.join()
pool = mp.Pool()
将创建一个工作进程池。默认情况下,worker 的数量等于您的机器拥有的 CPU 内核的数量。
每个pool.apply_async调用排队一个任务,由工作进程池中的工作人员运行。当工作人员可用时,它会运行compute(j)
. 当worker返回一个值时,data
主进程中的一个线程运行回调函数write(data)
,data
作为worker返回的数据。
一些警告:
j
从 0 到 199 的范围。解决此问题的一种方法是将数据写入 sqlite(或其他类型的)数据库,并将其j
作为数据字段之一. 然后,当您希望按顺序读取数据时,您可以SELECT * FROM table ORDER BY j
.使用多个进程将增加所需的内存量,因为工作进程生成数据并且等待写入磁盘的数据会累积在队列中。您也许可以通过使用 NumPy 数组来减少所需的内存量。如果这不可能,那么您可能必须减少进程数:
pool = mp.Pool(processes=1)
这将创建一个工作进程(运行compute
),让主进程运行write
。由于compute
需要比 更长
write
的时间,因此队列不会备份超过一大块要写入磁盘的数据。但是,您仍然需要足够的内存来计算一个数据块,同时将另一块数据写入磁盘。
如果您没有足够的内存来同时执行这两项操作,那么您别无选择——您的原始代码按顺序运行是唯一的方法compute
。write
简单的方法是只使用线程和队列。另一方面,如果计算部分不依赖于全局状态,并且您的机器具有多个 CPU 核心,则更有效的方法是使用进程池
from multiprocessing import Pool
def compute_data(x):
return some_calculation_with(x)
if __name__ == '__main__':
pool = Pool(processes=4) # let's say you have quad-core, so start 4 workers
with open("output_file","w") as outfile:
for calculation_result in pool.imap(compute_data, range(200)):
# pool.imap returns results as they come from process pool
outfile.write(calculation_result)