スーパーコンピュータには30時間かかるコードがあり、管理者は一度に1つのコアしか使用できないと言います。 60 x 60マトリックスを介してイメージングコードを実行し、zdichi_epsイメージングプログラムを実行し、繰り返し(3600回)ごとにファイルにデータを書き込みます。私の考えでは、GNU PARALLELコマンドを使用し、2つのwhileループの代わりにforループを使用して以下のスクリプトを書き換えることができます。最大64コアまで使用できるので時間が大幅に短縮されると思います。一度見てどう思うか教えてください。どのように変わりますか?可能ですか?ありがとうございます!データセンターとの戦いで私を救ってくれる仕事のバージョンを手に入れるのを手伝うことができるすべての人に喜んで寄付します!
set tb = gau_9.tab # tab file
set target = reformat # target name (from the command line)
set dte = May2010v1 # date of the run.
set mult1 = 0.7958 # multiplication factor
set mult2 = `echo $mult1 | awk '{printf("%.6f",$1/2)}'`
set inclin = 40 # inclination angle
set vsin = 113.3 # vsini
set aim = 0.03221 # <chisq aim>
set tphot = 5600 # photosphere temperature
set tspot = 4100 # spot temperature
set omega0 = 11.0038 # omega_0; matched to the period
set startx = 10.8 # starting omega_eq
set stepx = 0.01 # step in omega_eq
set nx = 60 # number of datapoint for omega_eq
set starty = 0.0 # starting domega
set stepy = 0.01 # step in domega
set ny = 60 # number of datapoints for domega.
set npts = 30 # number of points used in zdichi_ep set spec =
$target.rs
set tab = $tb
set b1 = $target.b1
set s1 = $target.s1
set out = $target$aim$dte.out
set map = $target$aim$dte.m
set junk = $target.dr_junk
set screen = $target.screen.dat
set zdi = $target.zdi.in
set om
set do
set ntot = 0
echo " " > $out
echo " " > $junk
echo " " > $screen
echo "starting diffrot" > $target.afile
set i = 0
while ($i < $nx)
set omega = `echo $startx $stepx $i | awk '{printf("%.5f",$1+$2*$3)}'`
echo "Count i, Count ny " $i $ny
echo "omega : " $omega
set line
set j = 0
while ($j < $ny)
echo "Count J Count ny " $j $ny
set domeg = `echo $starty $stepy $j | awk '{printf("%.5f",$1+$2*$3)}'`
echo "1 delta omega : " $domeg
set test = `echo $omega $domeg | awk '{tmp = $1-0.361387*$2-4.461019;
tmp = sqrt(tmp*tmp); if (tmp < 0.02) print 1; else print 0; }'`
echo "test value : " $test
set test = 1
if ($test == 0) then
set spot = 9.000000
set chi2 = 9.000000
set testzdi = 9.00000
else
set beta = `echo $omega $omega0 | awk '{printf("%e",1.0-$1/$2)}'`
set gamma = `echo $domeg $omega0 | awk '{printf("%e",$1/$2)}'`
echo "test, beta and gamma : " $test $beta $gamma
echo "22 sending data to zdichi via diffrot2"
echo "33 The data sent :" $vsin $spec $tab $mult1 $beta $aim $gamma $mult2 >> $screen
# setting up the input file for zdichi_eps
echo n > $zdi
echo n >> $zdi
echo 5000 $inclin $vsin >> $zdi
echo n >> $zdi
echo 1 >> $zdi
echo $tphot $tspot >> $zdi
echo $beta $gamma >> $zdi
echo $spec >> $zdi
echo $tab >> $zdi
echo $mult1 $mult2 >> $zdi
echo y >> $zdi
echo 1.0 >> $zdi
echo 1 >> $zdi
echo y >> $zdi
echo 1 >> $zdi
echo $aim $npts >> $zdi
echo $b1 >> $zdi
echo y >> $zdi
echo $s1 >> $zdi
# finished setting up the input file for zdichi_eps
/home/zdichi_eps < $zdi >> $out
echo "44 finished with zdichi"
@ ntot++
set chi2 = `tail -20 $out | grep '<29>' | awk '{printf("%.6f", $3)}'`
set spot = `tail -20 $out | grep '<29>' | awk '{printf("%.6f", $5)}'`
set testzdi = `tail -20 $out | grep '<29>' | awk '{printf("%.6f", $6)}'`
echo "55 The returned values were: " $omega $domeg $test $chi2 $spot $testzdi >> $screen
endif
if ($i == 0) then
set do = `echo $do $domeg`
endif
set line = `echo $line $chi2`
@ j++
end
set om = `echo $om $omega`
echo $line >> $junk
@ i++
end
答え1
次のようなものを並列化する最速の方法は次のとおりです。
- すべてのパラメータファイルの書き込み
reformat.zdi.${i}_${j}.in
- 各ファイルに対してプログラムを並列に呼び出す
たとえば、次のようになります。
#!/bin/bash
for f in ./reformat.zdi.*.in ;do
echo "/home/zdichi_eps < $f > ${f%.in}.out"
done | parallel -j64
答え2
$i
Bashで好ましいアプローチは、引数を受け入れる関数を作成することです$j
。
do_zdichi() {
i="$1"
j="$2"
[set all variables here]
/home/zdichi_eps < $zdi >> $out
[postprocess output]
}
export -f do_zdichi
eval parallel do_zdichi ::: {0..$nx} ::: {0..$ny}
output.$i.$j
関数によって作成されたすべてのファイル名が一意の名前(可能ですがそうではありません)を持っていることを確認しても、並行して実行されるmyoutput
他のプロセスはそのファイルを上書きしません。