我们在需要处理的各种目录中有大约500 to的图像。每个图像的大小约为4MB,我们有一个python脚本来一次处理每个图像(它读取元数据并将其存储在数据库中)。每个目录可能需要1-4个小时来处理,具体取决于目录的大小。
我们在GNU/Linux操作系统上有一个2.2 GNU的四核处理器和16 GNU的RAM。当前脚本仅使用一个处理器。利用其他内核和RAM来更快地处理图像的最佳方法是什么?启动多个Python进程来运行脚本是否会利用其他内核?
另一种选择是使用Gearman或Beanstalk之类的工具将工作外包给其他机器。我看过多进程库,但不确定如何利用它。
发布于 2012-04-04 22:17:30
启动多个Python进程来运行脚本会不会利用其他内核?
是的,如果任务是受CPU限制的,它就会。这可能是最简单的选择。但是,不要为每个文件或每个目录派生单个进程;请考虑使用parallel(1)之类的工具,让它为每个内核派生两个进程。
另一种选择是使用诸如Gearman或Beanstalk之类的工具将工作外包给其他机器。
这可能行得通。另外,看看Python binding for ZeroMQ,它使分布式处理变得非常容易。
我已经看过多进程库了,但是我不确定如何利用它。
定义一个函数,比如process,该函数读取单个目录中的图像,连接到数据库并存储元数据。让它返回一个表示成功或失败布尔值。假设directories是要处理的目录列表。然后
import multiprocessing
pool = multiprocessing.Pool(multiprocessing.cpu_count())
success = all(pool.imap_unordered(process, directories))将并行处理所有目录。如果您愿意,您也可以在文件级进行并行;这只需要稍加修改即可。
请注意,这将在第一次失败时停止;使其具有容错能力需要更多的工作。
发布于 2012-04-04 22:18:53
启动独立的Python进程是理想的。进程之间不会有锁争用,操作系统将安排它们并发运行。
您可能想要进行实验,看看理想的实例数是多少-它可能比核心数多,也可能少。可能会争用磁盘和缓存,但另一方面,您可能会让一个进程运行,而另一个进程则在等待I/O。
发布于 2012-04-04 22:51:01
您可以使用多进程池来创建进程以提高性能。假设您有一个用于处理图像的函数handle_file。如果你使用迭代,它最多只能使用你的一个核心的100%。为了利用多核,Pool multiprocessing为您创建子进程,并将您的任务分配给它们。下面是一个示例:
import os
import multiprocessing
def handle_file(path):
print 'Do something to handle file ...', path
def run_multiprocess():
tasks = []
for filename in os.listdir('.'):
tasks.append(filename)
print 'Create task', filename
pool = multiprocessing.Pool(8)
result = all(list(pool.imap_unordered(handle_file, tasks)))
print 'Finished, result=', result
def run_one_process():
for filename in os.listdir('.'):
handle_file(filename)
if __name__ == '__main__':
run_one_process
run_multiprocess()run_one_process是处理数据的单核心方式,简单,但速度慢。另一方面,run_multiprocess创建了8个工作进程,并将任务分配给它们。如果你有8个内核,速度会快8倍左右。我建议您将worker数量设置为内核的两倍,或者恰好是内核的数量。您可以尝试一下,看看哪种配置更快。
对于高级分布式计算,您可以像前面提到的那样使用ZeroMQ。一开始很难理解。但是一旦你理解了它,你就可以设计一个非常高效的分布式系统来处理你的数据。在你的情况下,我认为一个REQ有多个代表就足够了。

希望这能对你有所帮助。
https://stackoverflow.com/questions/10012968
复制相似问题