使用Matlab和Java混合編程實(shí)現(xiàn)并行的任務(wù)提交

項(xiàng)目地址:https://github.com/CHanzyLazer/Matlab-JavaThreadPool
問題描述
最近做課題越來越接觸到一些重復(fù)的任務(wù)需要并行執(zhí)行可以大大提高效率,例如機(jī)器學(xué)習(xí)需要的訓(xùn)練數(shù)據(jù),或者繪制一條曲線上需要很多個(gè)點(diǎn),每個(gè)點(diǎn)都是獨(dú)立的數(shù)據(jù),甚至是重復(fù)計(jì)算一個(gè)結(jié)果來驗(yàn)證正確性等等。并且現(xiàn)在也需要更多的使用超算,原本手動(dòng)管理任務(wù)的提交效率也很低,因此就在嘗試使用軟件來自動(dòng)并行提交任務(wù)。
首先在我的使用習(xí)慣中,主導(dǎo)的軟件一般是 Matlab,因?yàn)?Matlab 擁有比較完整的庫,可以在一個(gè)軟件中完成任務(wù)的提交,文本讀取獲得數(shù)據(jù),數(shù)據(jù)處理,以及數(shù)據(jù)的繪制(另一個(gè)替代品是則是 Python,不過在我看來只能處于替代品的位置)。在之前我一般會(huì)借助?Parallel Computing Toolbox,使用 parfor 和 system() 來并行提交任務(wù),但是這會(huì)遇到一些問題:
Matlab 的線程池有兩種模式,在 Process 模式中,每個(gè)線程都會(huì)創(chuàng)建一個(gè)相對(duì)獨(dú)立的 Matlab 進(jìn)程(每個(gè)會(huì)占用大概 500MB 的內(nèi)存),線程池初始化慢不說,當(dāng)線程數(shù)多了后占用的內(nèi)存也是非常的高。
在 Thread 模式中,無法設(shè)置超過 cpu 核心數(shù)目的線程數(shù),會(huì)浪費(fèi)掉一半的超線程不說,如果是向超算提交遠(yuǎn)程任務(wù)這個(gè)限制也非常不合理。并且 Thread 模式會(huì)有很多限制,比如目前的 Matlab 版本中(R2022b),不能設(shè)置 parfor 的最大并行數(shù)目,因此這個(gè)模式在這里還是基本不可用的狀態(tài)。
不能創(chuàng)建多個(gè)線程池,不能異步編程等等。
因?yàn)槲易罱凶鲆恍?Java 的并行編程,因此這些也都是相比 Java 的到的一些缺點(diǎn)(畢竟Python的并行甚至?xí)?nèi)存泄漏),好在我在搜索 Matlab 相關(guān)部分的時(shí)候,發(fā)現(xiàn)了 Matlab 對(duì) Java 的混合編程支持程度非常好,因此萌生了在 Matlab 中直接使用 Java 的線程池的想法。
原理介紹
具體可以參考官方對(duì)于 Matlab 和 Java 混合編程的文檔:https://ww2.mathworks.cn/help/matlab/java-language.html?s_tid=CRUX_lftnav
(或者直接問ChatGPT)
首先這里選用的是 Java 中的 FixedThreadPool 來獲取固定并行數(shù)目的線程池,不過還需要實(shí)時(shí)檢測(cè)線程池中任務(wù)的數(shù)目來實(shí)現(xiàn)進(jìn)度條,或者等待線程池完成等操作,因此實(shí)際使用的是和?FixedThreadPool 相同參數(shù)設(shè)置的?ThreadPoolExecutor。
為了保持代碼簡潔,這個(gè)線程池只需要負(fù)責(zé)并行執(zhí)行系統(tǒng)的指令(具體使用類似 Matlab 的 system 函數(shù),但是并行執(zhí)行),因此需要額外提供一個(gè)?SystemTask,繼承 Runnable,在執(zhí)行 run() 的時(shí)候使用 Runtime.exec() 來執(zhí)行具體的系統(tǒng)指令,而線程池只需要根據(jù)輸入的指令(String)來創(chuàng)建對(duì)應(yīng)的?SystemTask 并加入內(nèi)部的線程池中。
具體的使用細(xì)節(jié)和例子可以在 github 項(xiàng)目中查看:https://github.com/CHanzyLazer/Matlab-JavaThreadPool
下載
從 github?項(xiàng)目中下載:https://github.com/CHanzyLazer/Matlab-JavaThreadPool
或者直接下載:https://github.com/CHanzyLazer/Matlab-JavaThreadPool/releases/download/v1.0/Matlab-JavaThreadPool.zip