我有 bash 脚本,它创建高能碰撞事件,如果一个事件需要大约 2 分钟,那么对于 100000 个事件则需要 200000 分钟,这太多了。所以如果我在一个节点中有50个核心,我希望每个核心上都有一个事件,这样在2分钟内就会生成50个事件,这样就节省了时间。我认为这可以通过多线程或任何其他方式来完成,那么有人可以帮助我吗?
答案1
GNU Parallel 就是为此类任务而设计的。
seq 100000 | parallel do_experiment
如果您的实验采用不同类型的值(例如模型),那么您可以通过以下方式运行所有模型的所有实验:
seq 100000 | parallel do_experiment --iteration {1} --model {2} :::: - ::: model1 model2
默认情况下,每个 CPU 核心有 1 个进程,并确保两个并行作业的输出不会混合。如果您的实验室中有多台未使用的计算机,您也可以让它们参与计算。
GNU Parallel 是一个通用并行器,可以轻松地在同一台计算机或多台您可以通过 ssh 访问的计算机上并行运行作业。它通常可以代替for
循环。
如果您想要在 4 个 CPU 上运行 32 个不同的作业,则并行化的直接方法是在每个 CPU 上运行 8 个作业:
相反,GNU Parallel 在完成后会生成一个新进程 - 保持 CPU 处于活动状态,从而节省时间:
安装
如果您的发行版未打包 GNU Parallel,您可以进行个人安装,不需要 root 访问权限。这样做可以在 10 秒内完成:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
对于其他安装选项,请参阅http://git.savannah.gnu.org/cgit/parallel.git/tree/README
了解更多
查看更多示例:http://www.gnu.org/software/parallel/man.html
观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
浏览本教程:http://www.gnu.org/software/parallel/parallel_tutorial.html
注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel
答案2
您可以将作业作为后台进程启动,直到达到后台 50 个作业的限制,然后等待一项作业完成,然后再启动另一项作业。
LIMIT=50
while collision_event_to_run
do
run_new_collision_event&
while (( $(jobs | wc -l) >= LIMIT ))
do
sleep 1
done
done
或者更好地在平均负载较低时运行新事件。
LIMIT=49
while collision_event_to_run
do
run_new_collision_event&
sleep 2 # let time for the load average calculation
while (( $(cut -d " " -f1 < /proc/loadavg) >= LIMIT ))
do
sleep 1
done
done
另一种选择是使用该batch
命令将作业堆叠到atd
批处理队列中。
batch collision _event_1
batch collision _event_2
batch collision _event_3
...
atd
服务将并行启动作业,直到服务器负载达到限制。该限制是 的一个参数,例如,它必须在服务启动脚本 atd
中设置。atd
atd -l 50
编辑:
为操作系统保留一点空闲CPU
atd -l 49
。atd 每分钟都会启动一个新作业,这太慢了,无法让服务器达到最后 200 万个作业的负载。您可以通过该参数减少延迟
-b
。atd -b 2 -l 49
每 2 秒启动一项作业将允许在第一个作业完成之前达到限制。