如何通过SBT让多个Scala程序利用多CPU核心运行?
问题描述
我编写了一个带输入参数的Scala程序,通过bash脚本启动多个不同参数的实例,启动命令如下:
sbt "runMain Experiment --profix data --binFile bin/000000.bin --bucketNum 8" & sbt "runMain Experiment --profix data --binFile bin/000000.bin --bucketNum 16" & sbt "runMain Experiment --profix data --binFile bin/000000.bin --bucketNum 32" & sbt "runMain Experiment --profix data --binFile bin/000000.bin --bucketNum 64" & sbt "runMain Experiment --profix data --binFile bin/000000.bin --bucketNum 128" &
启动后发现这五个程序仅共享单个CPU核心,而服务器具备28个CPU核心,其余27个核心处于闲置状态(截图显示三个程序各占用1/3的CPU资源)。请问如何让多个Scala程序利用多CPU核心运行?
解决方法
1. 让每个Scala实例运行在独立JVM进程中
默认情况下,sbt的runMain会在sbt自身的JVM进程内执行程序,多个runMain实例会被限制在同一个进程的线程池中,无法充分利用多核。开启fork模式可让每个程序启动独立的JVM:
方式一:全局配置(修改build.sbt)
在项目的build.sbt文件中添加以下配置:
fork := true
之后执行启动命令,每个runMain都会启动单独的JVM进程,系统会自动调度到不同CPU核心。
方式二:命令行临时指定
若不想修改全局配置,可在启动命令中直接指定fork参数:
sbt -J-Dsbt.run.fork=true "runMain Experiment --profix data --binFile bin/000000.bin --bucketNum 8" &
2. 手动绑定CPU核心(可选)
如果希望强制每个实例绑定到特定核心,避免系统调度的不确定性,可使用taskset命令指定CPU亲和性。例如将五个实例分别绑定到核心0-4:
taskset -c 0 sbt -J-Dsbt.run.fork=true "runMain Experiment --profix data --binFile bin/000000.bin --bucketNum 8" & taskset -c 1 sbt -J-Dsbt.run.fork=true "runMain Experiment --profix data --binFile bin/000000.bin --bucketNum 16" & taskset -c 2 sbt -J-Dsbt.run.fork=true "runMain Experiment --profix data --binFile bin/000000.bin --bucketNum 32" & taskset -c 3 sbt -J-Dsbt.run.fork=true "runMain Experiment --profix data --binFile bin/000000.bin --bucketNum 64" & taskset -c 4 sbt -J-Dsbt.run.fork=true "runMain Experiment --profix data --binFile bin/000000.bin --bucketNum 128" &
注意:CPU核心编号从0开始,28核服务器的核心编号范围为0-27。
3. 确保Scala程序本身支持多线程(按需调整)
如果你的Scala程序是单线程逻辑,每个实例最多只能占用一个核心,但多个独立实例可分别利用不同核心。若希望单个程序实例利用多核,需在代码中引入多线程逻辑,比如使用Scala的Future、线程池或并行集合等。
内容的提问来源于stack exchange,提问作者meng han
相关产品推荐
相关产品推荐

