DEA参数校准并行运行咨询:多线程/多进程与文件访问问题
DEA参数校准并行化问题解决方案
问题1:能否通过多线程同时运行250次solver.out?
首先明确:solver.out作为数值求解器,通常属于CPU密集型程序。Python的多线程受GIL限制,无法真正实现多核并行,因此多线程方案不适用于这类场景,优先用多进程更高效。你当前用Pool.starmap时CPU上限为8,大概率是因为默认进程数等于CPU核心数(os.cpu_count())。
- 理论上可以手动设置进程池大小(比如
Pool(processes=250))来启动250个solver.out实例,但实际要评估系统资源承载能力:- CPU:250个CPU密集型进程会让CPU完全饱和,上下文切换开销剧增,整体运行效率反而下降,甚至导致系统卡顿。
- 内存:若每个
solver.out实例占用较多内存,250个实例可能直接耗尽内存引发OOM错误。 - 磁盘IO:大量实例同时读写磁盘,会触发IO带宽瓶颈,拖慢所有任务的执行速度。
- 更合理的做法是动态控制并发数:基于系统当前负载(CPU使用率、内存占用)调整进程池大小,比如用
concurrent.futures.ProcessPoolExecutor将max_workers设置为CPU核心数的2-4倍(若solver存在IO等待环节),或保持核心数水平(纯CPU密集场景)。 - 额外建议:若
solver.out本身支持多线程/多进程加速,优先调整solver的内部参数,比启动多个独立实例的资源利用率更高。
问题2:并行运行时文件读写与solver.out执行是否会引发冲突?
会,直接共享输入输出文件必然导致数据覆盖、读写错误或程序崩溃,必须做隔离处理:
- 为每个候选解(甚至每个
solver.out运行实例)创建独立的临时目录:- 用Python的
tempfile.TemporaryDirectory自动生成唯一临时目录,或结合候选解ID、UUID生成自定义目录名(比如f"solution_{sol_id}_run_{run_idx}")。 - 将当前任务所需的6-10个
.txt输入文件写入专属目录,调用solver.out时明确指定输入文件路径为该目录下的文件,输出文件也定向到该目录。
- 用Python的
- 任务完成后,可选择保留目录用于结果校验,或自动删除临时文件释放磁盘空间。
- 调用
subprocess.call时,建议通过cwd参数指定工作目录为临时目录,避免solver默认读写当前目录的同名文件。
优化建议
针对你当前每个候选解需串行运行6-10次solver.out的情况,可采用嵌套并行方案:
- 外层用进程池处理不同候选解(充分利用多核CPU)。
- 每个候选解内部用线程池并行处理自身的6-10次
solver.out运行(因为solver执行是独立子进程,线程池可避免进程切换开销)。
这种方式既能提升整体并行度,又能有效控制单任务的资源占用。
内容的提问来源于stack exchange,提问作者Gungor SAHİN
相关产品推荐
相关产品推荐

