python - 关于 Python 中的多处理速度提升的问题
问题描述
我在处理多个视频的项目中工作,每个视频时长 1-2 小时,并且我可以使用 SLURM Worload Manager 访问高性能集群。程序的主要任务是跟踪对象并评估跟踪器的一些性能指标,这一切都使用 numpy 和 opencv 命令完成,并且仅在一个视频上运行时运行良好,大约 30 FPS。但是,我想在某种程度上并行运行评估以节省时间。我的代码的简化版本可能如下所示:
class Task:
def __init__(videos):
self.videos = videos
self.object_tracker = ObjectTracker()
def execute(self):
jobs = []
for video in self.videos:
worker = VideoWorker(video=video, self.object_tracker)
jobs.append(worker)
worker.start()
for j in jobs:
j.join()
class VideoWorker(multiprocessing.Process):
def __init__(self, video, object_tracker):
self.video = video
self.object_tracker = object_tracker
def run(self):
cap = cv2.VideoCapture(video.path_to_video)
while cap.isOpened():
frame = cap.read()
objects, tracks = self.object_tracker.process_frame(frame)
"""
... Further processing involving numpy and cv2 methods
"""
logging.info("Accuracy: %.2f" % accuracy")
我没有包括在并行/串行处理之间切换的行,但这只是一些 if/else 语句。
我可以运行我的代码的方式:
- 未并行化,一次一个视频,在最多 48 个内核的节点上运行 -> ~30 FPS
- 在具有 48 个内核的一个节点上并行化(我尝试了进程和池)-> 每个进程/vid 中约 5 FPS,我有 20 个视频,所以内核数量不应该是问题
- 通过在 20 个节点上部署我的代码进行并行化(每个视频一个,每个进程只打开/评估一个视频),每个视频/任务限制为 1 个核心和 4GB 内存,实际代码中没有多处理 -> 每个任务中约 30 FPS
当仅在一个节点上使用多处理时,我期待或希望获得类似的性能,因为这会为我简化一些事情(例如,我可以直接收集所有结果)。我的理解是,多处理会产生一个新的 python 进程并将其分配给一个空闲核心,并将必要的数据复制到为该新产生的进程保留的内存空间中。当处理能力似乎不是极限时,为什么这会慢得多?使用多处理时阻止我的评估循环运行得更快的时间在哪里?我很高兴得到一些澄清!
解决方案
推荐阅读
- javascript - 指数据的firestore安全
- xamarin.forms - Android 相机照片不应存储在设备和 SD 卡中
- python - re.sub 带括号,删除日文红宝石字符
- c# - C# 每 5 秒读取一次 SQLite 数据库 (WPF)
- c# - 如何在 C# 中使用 SHA2 正确签署 SOAP 消息?
- java - 导出到 jar 时缺少 Eclipse 中可用的库
- python - 如何使用 Python 高效地将大型 CZI 图像(+50GB)转换为 JP2?
- python - 在序列化程序中过滤嵌套查询集
- r - ggplotting 列表或列表到数据框
- gams-math - GAMS 建模:如何将标识符设置为方程组的最后一个值(index.last)