我想加快我在linux中的计算速度?作为示例,我有以下脚本:example.sh
#!/bin/bash
n1=1; n2=1000
while [ $n1 -le $n2 ]
do
cat << EOF > test.f
open (1,file='$n1.txt',form='formatted', status='unknown')
write (1, *) "Hello World!"
stop;end
EOF
gfortran test.f
./a.out
(( n1++ ))
done
如果我执行上面的example.sh,那么它将执行1000次。我原来的fortran程序有点大,需要大约3分钟才能完成。所以完成我的脚本需要大约2天。那么如何使用多CPU来加快速度呢?我的系统显示CPU:8。
答案 0 :(得分:3)
GNU Parallel做得很好。
GNU Parallel可用于使用一台或多台计算机并行执行作业。这消除了管理进程的需要,并为我们提供了一种并行执行二进制文件的方法。
因此,您的脚本(让我们称之为test.sh)变为
#!/bin/bash
n1=$1
cat << EOF > test.f
open (1,file='$n1.txt',form='formatted', status='unknown')
write (1, *) "Hello World!"
stop;end
EOF
gfortran test.f
./a.out
现在可以使用'parallel'调用脚本test.sh,如下所示。
seq 1000 | parallel -j 8 --workdir $PWD ./test.sh {}
-j 8
指定要运行的作业数。这将启动./test.sh 1, ./test.sh 2, ./test.sh 3 ... ./test.sh 1000
并确保其中8个并行运行。
答案 1 :(得分:2)
此代码将自行执行八次(每次在后台执行),然后等待所有八个代码退出:
#!/bin/bash
if [ "$#" = 0 ]; then
trap 'kill -9 $job_list' 0 # clean up if given CTRL+C
i=0; CPUs=8; total=1000
while [ $i -lt $CPUs ]; do
from=$((i*total/CPUs+1))
i=$((i+1))
to=$((i*total/CPUs))
bash $0 $from $to &
job_list="$job_list $!"
done
wait
trap - 0 # done, remove cleanup code
exit
fi
n1=$1; n2=$2
while [ $n1 -le $n2 ]; do
cat << EOF > test$n1.f
open (1,file='$n1.txt',form='formatted', status='unknown')
write (1, *) "Hello World!"
stop;end
EOF
trap "rm -f test$n1.f a$n1.out" 0
gfortran test$n1.f -o a$n1.out
./a$n1.out
rm test$n1.f a$n1.out
(( n1++ ))
done
这将运行给定Fortran代码的125次运行的八个循环。所有八个循环同时运行。
这使用wait
和job control:在命令末尾使用&
将其作为后台作业运行(并继续运行而不等待它完成),{{1是最近的后台作业的作业规范(我们保存在$!
中,因此我们可以在需要时将其删除),$job_list
,如果没有参数,将等待 all 继续工作。
答案 2 :(得分:2)
正如其他人所提到的,重写程序以接受命令行参数是值得的。我在下面的示例中扩展了代码:
runfile.f90
program runfile
character(len=128) :: arg
integer :: i
do i = 1,command_argument_count()
call get_command_argument(i, arg)
open (1, file=trim(arg) // ".txt", form='formatted', status='unknown')
write (1, *) "Hello world!"
end do
end program runfile
然后你可以编译一次这个程序(可能还有一些更积极的编译标志,如果你对速度感兴趣)并与另一个答案中提到的GNU parallel并行化:
seq -w 1000 | parallel -j 8 ./runfile {}
我完成命令行处理的方式就像许多Unix工具一样,所以即使你不进行并行化,你现在也可以像./runfile {01..10}
一样调用你的程序进行10次运行。此外,如果文本文件实际上是要处理的内容,您可以稍微修改程序以允许调用./runfile *.txt
。