AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 458212
Accepted
user3647558
user3647558
Asked: 2018-07-25 10:53:29 +0800 CST2018-07-25 10:53:29 +0800 CST 2018-07-25 10:53:29 +0800 CST

GNU paralelo com loop for?

  • 772

Encontrei respostas próximas a isso, mas não consigo entender como usá-las no meu caso (sou bastante novo no Bash) ... com Imagemagick e gostaria de usar GNU Parallel para acelerar as coisas.

Este é o código que eu uso (processando 100 quadros por vez para evitar ficar sem memória ram):

calcmethod1=mean;
allframes=(*.png)
cd out1

for (( i=0; i < "${#allframes[@]}" ; i+=100 )); do 
    convert "${allframes[@]:i:100}" -evaluate-sequence "$calcmethod1" \
        -channel RGB -normalize ../out2/"${allframes[i]}"
done

como eu 'paralelizar' isso? A maioria das soluções que encontrei funciona sem usar um loop, mas uma tubulação - mas, ao fazer isso, me deparei com o problema de que meu script quebraria por causa da minha lista de argumentos ficar muito longa ...

Eu acho que o que eu gostaria de fazer é paralleldividir a carga como entregar os primeiros 100 quadros ao núcleo 1, quadros 100-199 ao núcleo 2 etc.?

bash imagemagick
  • 3 3 respostas
  • 5134 Views

3 respostas

  • Voted
  1. eschwartz
    2018-07-25T11:40:34+08:002018-07-25T11:40:34+08:00

    A solução correta é imprimir os nomes dos arquivos usando um shell embutido como printf '%s\0' *.pngo qual não é vulnerável à limitação ARG_MAX no comprimento do argumento da linha de comando e, em seguida, canalizá-lo para o parallel --nullqual lerá esses nomes de arquivos e agrupará os trabalhos da maneira que desejar.

    Algumas funcionalidades parallelque iremos utilizar:

    • --nullé necessário para dividir nomes de arquivos de forma sensata em caracteres nulos para evitar problemas estranhos com nomes de arquivos estranhos
    • -n 100irá, assim como xargs, lidar com 100 arquivos para cada chamada
    • {}contém esses 100 nomes de arquivos
    • ../out2/{1}contém apenas o primeiro

    Então, isso se tornaria:

    calcmethod1=mean
    printf '%s\0' *.png | parallel --null -n 100 convert {} -evaluate-sequence $calcmethod1 -channel RGB -normalize {} ../out2/{1}
    

    Por que você acha que a tubulação não funcionaria? A tubulação funciona bem, são apenas comandos bifurcados externamente que não são lidos de um tubo, que têm problemas com o comprimento do argumento . A tubulação é de fato todo o propósito do parallel.

    • 3
  2. Best Answer
    slm
    2018-07-25T23:23:29+08:002018-07-25T23:23:29+08:00

    Ordem

    Seu programa de exemplo não parecia se importar com a ordem do *.pngarray allframesque você estava construindo, mas seus comentários me levaram a acreditar que a ordem importaria.

    Eu acho que o que eu gostaria de fazer é ter uma divisão paralela da carga, como entregar os primeiros 100 quadros ao núcleo 1, quadros 100-199 ao núcleo 2, etc.?

    festança

    Portanto, eu começaria com uma modificação no seu script assim, alterando a construção do allframesarray para que os arquivos sejam armazenados em ordem numérica.

    allframes=($(printf "%s\n" *.png | sort -V | tr '\n' ' '))
    

    Isso pode ser simplificado ainda mais usando sort -zV:

    allframes=($(printf "%s\0" *.png | sort -zV | tr '\0' ' '))
    

    Isso tem o efeito de construir seus convert ...comandos para que fiquem assim agora:

    $ convert "0.png 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png \
              10.png 11.png 12.png 13.png 14.png 15.png 16.png 17.png 18.png \
              19.png 20.png 21.png 22.png 23.png 24.png 25.png 26.png 27.png \
              28.png 29.png 30.png 31.png 32.png 33.png 34.png 35.png 36.png \
              37.png 38.png 39.png 40.png 41.png 42.png 43.png 44.png 45.png \
              46.png 47.png 48.png 49.png 50.png 51.png 52.png 53.png 54.png \
              55.png 56.png 57.png 58.png 59.png 60.png 61.png 62.png 63.png \
              64.png 65.png 66.png 67.png 68.png 69.png 70.png 71.png 72.png \
              73.png 74.png 75.png 76.png 77.png 78.png 79.png 80.png 81.png \
              82.png 83.png 84.png 85.png 86.png 87.png 88.png 89.png 90.png \
              91.png 92.png 93.png 94.png 95.png 96.png 97.png 98.png 99.png" \
              -evaluate-sequence "mean" -channel RGB -normalize ../out2/0.png
    

    Paralelos

    Com base no exemplo de eschwartz, montei um parallelexemplo da seguinte forma:

    $ printf '%s\n' *.png | sort -V | parallel -n100 --dryrun convert {} \
       -evaluate-sequence 'mean' -channel RGB -normalize ../out2/{1}
    

    novamente, mais simplesmente usando sort -zV:

    $ printf '%s\0' *.png | sort -zV | parallel -0 -n100 --dryrun "convert {} \
       -evaluate-sequence 'mean' -channel RGB -normalize ../out2/{1}
    

    NOTA: O acima tem um eco "..." como a parallelação para iniciar. Fazer desta forma ajuda a visualizar o que está acontecendo:

    $ convert 0.png 1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10.png \
             11.png 12.png 13.png 14.png 15.png 16.png 17.png 18.png 19.png \
             20.png 21.png 22.png 23.png 24.png 25.png 26.png 27.png 28.png \
             29.png 30.png 31.png 32.png 33.png 34.png 35.png 36.png 37.png \
             38.png 39.png 40.png 41.png 42.png 43.png 44.png 45.png 46.png \
             47.png 48.png 49.png 50.png 51.png 52.png 53.png 54.png 55.png \ 
             56.png 57.png 58.png 59.png 60.png 61.png 62.png 63.png 64.png \ 
             65.png 66.png 67.png 68.png 69.png 70.png 71.png 72.png 73.png \ 
             74.png 75.png 76.png 77.png 78.png 79.png 80.png 81.png 82.png \
             83.png 84.png 85.png 86.png 87.png 88.png 89.png 90.png 91.png \
             92.png 93.png 94.png 95.png 96.png 97.png 98.png 99.png \
             -evaluate-sequence mean -channel RGB -normalize ../out2/0.png
    

    Se você estiver satisfeito com esta saída, simplesmente remova a --dryrunopção para parallele execute-a novamente.

    $ printf '%s\0' *.png | sort -zV | parallel -0 -n100 convert {} \ 
        -evaluate-sequence 'mean' -channel RGB -normalize
    

    Referências

    • [Publicado na revista Open Source For You (OSFY), edição de outubro de 2013.]
    • 3
  3. Bob
    2018-07-25T13:40:30+08:002018-07-25T13:40:30+08:00

    É possível executar cada convertprocesso em seu próprio subshell:

    #!/bin/bash
    
    for (( i=1; i<=1000; i++ )) do
    (
    command --options ) &
    disown
    done
    
    exit 0
    

    Para ver como funciona, tente este script:

    #!/bin/bash
    
    echo "Hi!"
    
    for (( i=1; i<=1000; i++ )) do
    (
    sleep 30
    echo "Bye, "$i"!" ) &
    disown
    done
    
    exit 0
    

    Atribua ao nome do script par.she verifique os processos posteriormente:

    ps aux | grep par.sh
    

    Podemos supor que o balanceador de carga de CPU Linux nativo deve distribuir os processos entre os núcleos de CPU uniformemente, pois cada subshell possui um pid separado. De qualquer forma, algo como cpusetestá sempre disponível para ser usado.

    • 2

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    ssh Não é possível negociar: "nenhuma cifra correspondente encontrada", está rejeitando o cbc

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    Como descarregar o módulo do kernel 'nvidia-drm'?

    • 13 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add retorna com: "Erro ao conectar ao agente: nenhum arquivo ou diretório" 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve