Início > dados, linux, testes > Paralelização de Processos II

Paralelização de Processos II

Dando continuidade ao que foi apresentado no post sobre paralelização de processos e motivado pelo comentário do colega J. Franky e fundamentalmente com a ajuda de Benilton Carvalho (aos quais deixo meu agradecimento), nesse “fast-post” vou mostrar uma outra implementação em paralelo.

O cenário é exatamente o mesmo do apresentado no post anterior (veja para entender). Agora, entretanto o processamento paralelo se dará em dois “níveis”, a saber: As nsmc simulações correm como um fork, ou seja, cópias do mesmo processo. Elas são implementadas como uma função e “correm” com a função mclapply(), o argumento mc.set.seed = TRUE garante que cada uma das nsmc terá uma semente geradora de números diferente.

Dentro de cada simualação temos ainda dois processos independentes dentro de cada ciclo (as duas estratégias de amostragem). Para um caso em que cada uma dessas estratégias demore um tempo grande, ao invés de esperar que a primeira termine para então começar a segunda, usamos uma versão de thread, com as funções parallel() e collect() e paralelizamos as duas estratégias.

O argumento mc.set.seed = TRUE tem o mesmo propósito que anteriormente, o argmento name = ‘foo’ é um grande facilitador… Vocês vão entender! Ao passar uma tarefa (a estratégia de amostragem) pela função parallel() é mesmo que dar um comando no terminal com um ‘nohup &’, ou seja, o computador executa a tarefa mas não “bloqueia” tal terminal para outro comando.

Depois de paralelizados, os processos são coletados pela função collect() na estrutura de uma lista, temos como argumentos da função (que não estão sendo usados, veja a documentação) o wait, ele é muito útil quando queremos que se espera ‘X’ tempo pelo fim das tarefas, após esse tempo, o processo continua.

A vantagem do uso do argumento name = ‘foo’ é que por default os nomes na estrutura da lista do collect recebem o número PID do processo, ao atribuir um nome fica muito mais fácil distribuir o que foi paralelizado.

Espero que tenham gostado… Lembrando que este é um exemplo puramente didático, que provavelmente não se aplica ao uso desses procedimentos. Segue portando código da terceira implementação, agora com o uso de paralelização em dois níveis.

#-----------------------------------------------------------------------------
## PARAMETROS DA SIMULAÇÃO -- usar os mesmo para as duas situações
n <- 5000 # numero de individuos
ciclos <- 30 # numero de ciclos
nsmc <- 100 # numero de simulacoes

## SEGUNDO CASO -- paralelizada
#-----------------------------------------------------------------------------
## IDEM (realiza um simulacao de 'nsmc')
simula.ii <- function(x) { # inicio da funcao -- sem argumentos
  ## mesmos comentarios do caso acima
  resultados <- matrix(NA, ciclos, 4) 
  p0 <- sample(c(0, 1, 2), n, replace = TRUE, prob = c(.25, .5, .25))
  resultados[1, ] <- rep(c(mean(p0), var(p0)), times = 2)
  estrA <- sample(p0, n/5, replace = FALSE)
  estrB <- p0[seq(1, 5000, 5)]
  resultados[2, ] <- c(mean(estrA), var(estrA), mean(estrB), var(estrB))
  for(k in 3:ciclos) {
    ## pA e pB paralelizados em 'thread'
    pA <- parallel(tipoA(estrA), name = 'A', mc.set.seed = TRUE)
    pB <- parallel(tipoB(estrB), name = 'B', mc.set.seed = TRUE)
    estrG <- collect(list(pA, pB)) # coleta dos processos paralelizados
    estrA <- estrG$A; estrB <- estrG$B # redistribui os processos
    resultados[k, ] <- c(mean(estrA), var(estrA), mean(estrB), var(estrB))
  }
  return(resultados) # retorna uma simulacao
}

tempoC <- system.time({ # armazena o tempo de processamento
saida3 <- mclapply(1:nsmc, # numero de nsmc
# aplica a funcao -- faz a simulacao
                   simula.ii,
                   mc.preschedule = FALSE,
                   # 'expande' quantos processos forem possiveis
                   mc.set.seed = TRUE,
                   # uma semente para cada processo
                   mc.cores = getOption('cores'))
                   # usa quantos processadores forem possiveis
})

## TEMPO
tempoC[3]

Até a próxima!

Anúncios
  1. Benilton
    10/03/2012 às 19:46

    Muito legal o post, FH! Prox. capitulo foreach()? 😉

    • fernandohtoledo
      11/03/2012 às 11:43

      Benilton, obrigado pelo retorno… você justamente tocou no ponto nevrálgico! Estou mesmo inclinado e fazer alguma implementação para reamostragem com o foreach(), Publico em tempo!
      abraço,
      FH

  1. No trackbacks yet.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: