【问题标题】:Pass in array to GNU Parallel to replace for loop将数组传递给 GNU Parallel 以替换 for 循环
【发布时间】:2018-11-28 15:34:05
【问题描述】:

 a) 我想并行运行 2 个脚本

b) 我想在这些脚本中并行执行 for 循环。

在我有这个代码之前:

for year in 2000 2001 2002 2003; do

  echo $year" LST data being merged"

  cd $base_data_dir/$year

  # this is the part that takes a long time
  cdo -f nc2 mergetime *.nc $output_dir/LST_$year.nc

done

我想使用 GNU Parallel 来尝试并行运行它。

我尝试了以下方法:

a) 创建一个调用其他脚本的“控制器”脚本

b) 将数组作为参数传递给 GNU 并行

控制器脚本

# 1. Create monthly LST for each year

cd $working_dir
seq 2000 2003 | parallel 'bash create_yearly_LST_files.sh {}'

# 2. Create monthly NDVI for each year

cd $working_dir
seq 2000 2003 | parallel 'bash create_yearly_NDVI_files.sh {}'

这应该并行运行以下:

bash create_yearly_LST_files.sh 2000
bash create_yearly_LST_files.sh 2001
...

bash create_yearly_NDVI_files.sh 2000
bash create_yearly_NDVI_files.sh 2001
...

处理脚本(NDVI同)

year="$1"
echo $year" LST data being merged"
cd $base_data_dir/$year

cdo -f nc2 mergetime *.nc $output_dir/LST_$year.nc

所以命令应该是:

cd $base_data_dir/2000
cdo -f nc2 mergetime *.nc $output_dir/LST_2000.nc

cd $base_data_dir/2001
cdo -f nc2 mergetime *.nc $output_dir/LST_2001.nc
...

cd $base_data_dir/2000
cdo -f nc2 mergetime *.nc $output_dir/NDVI_2000.nc

cd $base_data_dir/2001
cdo -f nc2 mergetime *.nc $output_dir/NDVI_2001.nc
...

我的问题:

这些进程在我的新代码中仍然有效,但没有提高性能。

谁能帮我了解如何通过每年并行运行?

同时运行这两个脚本(create_yearly_LST_files.shcreate_yearly_NDVI_files.sh

【问题讨论】:

    标签: bash parallel-processing netcdf gnu-parallel


    【解决方案1】:

    使用 GNU 并行

    cd $working_dir
    parallel 'cd {}; cdo -f nc2 mergetime *.nc xxx/LST_{}.nc' ::: {2000..2003}
    

    【讨论】:

    • 嗨@Mark cd {} 中的空大括号必须用cd{$base_data_dir/$year} 填充吗?道歉 bash 对我来说有点新鲜!
    • 没有。随着每个并行作业的启动,{} 将被填充(由 GNU Parallel)当前参数,因此它将用 2000 填充第一个作业,2001 用于第一个作业第二个等等。
    • 你可以使用parallel --dry-run ...,如果你想看看它会执行什么而不实际执行任何东西。
    • 可以使用man parallel查看内置帮助,按空格键前进一页,q退出。
    【解决方案2】:

    是什么阻止了你做事

    for year in 2000 2001 2002 2003; do
    
      echo $year" LST data being merged"
    
      cd $base_data_dir/$year
    
      # this is the part that takes a long time
      cdo -f nc2 mergetime *.nc $output_dir/LST_$year.nc &
    
    done
    wait
    

    【讨论】:

    • & 是否意味着循环中后面的$year 也将在不同的内核上运行?
    • & 将任务置于后台;这意味着它在继续之前不会等待命令完成。底部的wait 等待所有后台任务完成,然后再继续执行您的脚本。 Linux 很智能,并且会使用不同的内核,是的。
    • 其他echo 语句写入何处?假设我有一行 echo $year " LST data merged" 会写在哪里?
    • 所有的 echo 语句都写到同一个地方,stdout。
    • 是的,我介意。我回答了你最初的问题,你既不赞成也不接受我的回答。
    【解决方案3】:

    也许这会起作用:

    doit() {
      cd "$base_data_dir"/"$1"
      cdo -f nc2 mergetime *.nc "$output_dir"/${2}_${1}.nc"
    }
    export -f doit
    export base_data_dir
    export output_dir
    parallel doit ::: {2000..2018} ::: LST NDVI
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-16
      • 1970-01-01
      • 2017-10-12
      相关资源
      最近更新 更多