Como posso executar este script bash em paralelo?

2

Eu preciso que isso seja mais eficiente

Neste momento, demora até 20 horas, dependendo da linha (estes são conjuntos de dados MCS razoavelmente grandes).

  • Divida arquivos grandes de dados em suas "fotos"
  • Cria uma lista de cada nome de captura a ser usado no loop
  • Faz um loop em cada disparo e executa os mesmos processos
  • Acrescenta cada foto a um novo arquivo de dados, para que você tenha a mesma linha aa antes, mas processada. Neste caso, estou filtrando os dados repetidamente, e é por isso que acho que isso pode ser executado em paralelo.

Você pode ignorar todos os comandos SU e, assim como tudo no loop for, eu só preciso saber como executar isso em paralelo (digamos 32 nós). Este é um tópico relativamente novo para mim, então uma explicação detalhada seria apreciada!

script:

#! /bin/bash    
# Split the input file into one file for each shot. NB mustclose each o/p file at the earliest opportunity otherwise it will crash!
susplit <$1 key=fldr stem=fldr_ verbose=1 close=1

# Create a list of shot files
ls fldr* > LIST

# Loop over each shot file; suppress direct wave; write to new concatenated output file
for i in 'cat LIST'; do
    echo $i
    suchw key1=tstat key2=tstat a=200 < $i | suwind key=tracf min=10 max=400 tmin=0 tmax=6 | suweight a=0 | suresamp rf=4 | sustatic hdrs=1 sign=-1 | sureduce rv=1.52 | sumedian median=1 xshift=0 tshift=0 nmed=41 | suflip flip=3 | sureduce rv=1.52 | suflip flip=3 | suresamp rf=0.25 | suweight inv=1 a=0 | sustatic hdrs=1 sign=1 >> $2
done

# Tidy up files by removing single shot gathers and LIST
rm -f fldr* LIST &
    
por acquisto2 23.03.2017 / 18:26

1 resposta

4

Suponho que é o loop for que você deseja paralelizar:

#! /bin/bash    
# Split the input file into one file for each shot. NB mustclose each o/p file at the earliest opportunity otherwise it will crash!
susplit <$1 key=fldr stem=fldr_ verbose=1 close=1

sucit() {
    i=$1
    echo $i
    suchw key1=tstat key2=tstat a=200 < $i | suwind key=tracf min=10 max=400 tmin=0 tmax=6 | suweight a=0 | suresamp rf=4 | sustatic hdrs=1 sign=-1 | sureduce rv=1.52 | sumedian median=1 xshift=0 tshift=0 nmed=41 | suflip flip=3 | sureduce rv=1.52 | suflip flip=3 | suresamp rf=0.25 | suweight inv=1 a=0 | sustatic hdrs=1 sign=1
}
export -f sucit

parallel sucit ::: fldr* > $2

# Tidy up files by removing single shot gathers and LIST
rm -f fldr* LIST &

Dependendo do susplit , você pode torná-lo ainda mais rápido. Se um tiro em "large_data_file" começar com <shot>\n e terminar com </shot>\n , algo como isto pode funcionar:

sucpipe() {
    suchw key1=tstat key2=tstat a=200 | suwind key=tracf min=10 max=400 tmin=0 tmax=6 | suweight a=0 | suresamp rf=4 | sustatic hdrs=1 sign=-1 | sureduce rv=1.52 | sumedian median=1 xshift=0 tshift=0 nmed=41 | suflip flip=3 | sureduce rv=1.52 | suflip flip=3 | suresamp rf=0.25 | suweight inv=1 a=0 | sustatic hdrs=1 sign=1
}
export -f sucpipe

parallel --block -1 --recstart '<shot>\n' --recend '</shot>\n' --pipepart -a $1 sucpipe > $2

Ele tentará dividir o bigfile em n blocos, onde n = número de núcleos. A divisão é feita em tempo real para que não grave arquivos temporários primeiro. Então, o GNU Parallel passará cada bloco para um sucflo.

Se bigfile for binário (ou seja, não texto) com um cabeçalho de 3200 bytes e um comprimento de registro de 1000 bytes, isso pode funcionar:

parallel -a bigfile  --pipepart --recend '' --block 1000 --header '.{3200}' ...

Para mais detalhes, siga o tutorial: man parallel_tutorial Sua linha de comando vai adorar você por isso.

    
por 24.03.2017 / 00:03