项目地址:https://github.com/CHanzyLazer/Matlab-JavaThreadPool
问题描述
最近做课题越来越接触到一些重复的任务需要并行执行可以大大提高效率,例如机器学习需要的训练数据,或者绘制一条曲线上需要很多个点,每个点都是独立的数据,甚至是重复计算一个结果来验证正确性等等。并且现在也需要更多的使用超算,原本手动管理任务的提交效率也很低,因此就在尝试使用软件来自动并行提交任务。
首先在我的使用习惯中,主导的软件一般是 Matlab,因为 Matlab 拥有比较完整的库,可以在一个软件中完成任务的提交,文本读取获得数据,数据处理,以及数据的绘制(另一个替代品是则是 Python,不过在我看来只能处于替代品的位置)。在之前我一般会借助 Parallel Computing Toolbox,使用 parfor 和 system() 来并行提交任务,但是这会遇到一些问题:
因为我最近有做一些 Java 的并行编程,因此这些也都是相比 Java 的到的一些缺点(毕竟Python的并行甚至会内存泄漏),好在我在搜索 Matlab 相关部分的时候,发现了 Matlab 对 Java 的混合编程支持程度非常好,因此萌生了在 Matlab 中直接使用 Java 的线程池的想法。
原理介绍
具体可以参考官方对于 Matlab 和 Java 混合编程的文档:https://ww2.mathworks.cn/help/matlab/java-language.html?s_tid=CRUX_lftnav
(或者直接问ChatGPT)
首先这里选用的是 Java 中的 FixedThreadPool 来获取固定并行数目的线程池,不过还需要实时检测线程池中任务的数目来实现进度条,或者等待线程池完成等操作,因此实际使用的是和 FixedThreadPool 相同参数设置的 ThreadPoolExecutor。
为了保持代码简洁,这个线程池只需要负责并行执行系统的指令(具体使用类似 Matlab 的 system 函数,但是并行执行),因此需要额外提供一个 SystemTask,继承 Runnable,在执行 run() 的时候使用 Runtime.exec() 来执行具体的系统指令,而线程池只需要根据输入的指令(String)来创建对应的 SystemTask 并加入内部的线程池中。
具体的使用细节和例子可以在 github 项目中查看:https://github.com/CHanzyLazer/Matlab-JavaThreadPool
下载
从 github 项目中下载:https://github.com/CHanzyLazer/Matlab-JavaThreadPool
或者直接下载:https://github.com/CHanzyLazer/Matlab-JavaThreadPool/releases/download/v1.0/Matlab-JavaThreadPool.zip