Início > linux, notícias, testes > Paralelização de processos

Paralelização de processos

Hoje em dia os computadores estão cada vez mais rápidos e via de regra, nossos processsadores tem mais de um núcleo de processamento. Isso é um “horizonte” grande que nos permite avançar num campo “baixo nível” da informática de gerenciar nossos processos para que eles sejam feitos em paralelo entre os vários núcleos do processador. Esse procedimento tem recomendações bem específicas e portanto não tem reflexos gerais em qualquer aplicação.

Estou tentando aprender sobre isso e ultimamente andei lendo e brincando com esses procedimentos que estão disponíveis no R. Basicamente existem três tipos de paralilazação. As de baixo nível, que envolvem um profundo conhecimento do hardware e assim como li, não são tão recomendadas para usuários finais. Outras são as paralizações explícitas em que o usuário é quem “manda” e por fim, já está disponível no R (exceto plataforma Windows) pacotes em que é possível implementar o processo de paralelização implícita, em que o usuário interage com ferramentas internas de “baixo nível” e o computador faz o resto… (brincadeira).

No primeiro tipo, se esse for seu propósito veja a documentação dos pacotes multicore (funções fork() e children()). No segundo caso procure sobre o pacote snow. E no último caso, ao qual vou dar mais atenção, veja sobre os pacotes doMC e multiocore especificamente nas funções mclapply(), parallel() e collect().

Como exemplo vou apresentar um caso bem tosco por sinal, mas acho que bastante ilustrativo. A primeira parte do código é uma implementação bem naive de uma simulação em que sobre uma população são retiradas dois tipos de amostra, para esses dois casos são em sequencia em um certo número de ciclos retiradas amostras. Esse processo por sua vez é repetido nsmc vezes (abreviatura de numero de simulações de Monte Carlo). Para as duas implementações (a naive e a paralela) é armazenado o tempo de processamento. Veja a diferença… Se você quiser ver a coisa acontecendo, abra o capô do seu computador, no terminal digite top, vai abrir o gerenciador de processos, e você vai conseguir ver no caso da implementação em paralelo, as várias cópias do seu processo correndo, diferentemente da implementação naive em que cada simulação só começa quando a anterios acaba.

Segue o código

#-----------------------------------------------------------------------------
## 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

## PRIMEIRO CASO -- "naive"
#-----------------------------------------------------------------------------
saida1 <- vector('list', length = nsmc) # saida da implementacao SIMPLES
tempoA <- system.time({ # armazena o tempo de processamento
   for(i in 1:nsmc) { # laço -- para cada simulacao
   resultados <- matrix(NA, ciclos, 4) # matriz dos resultados individuais
   # populacao inicial
   p0 <- sample(c(0, 1, 2), n, replace = TRUE, prob = c(.25, .5, .25))
   resultados[1, ] <- rep(c(mean(p0), var(p0)), times = 2) # resultado ciclo 0
   estrA <- sample(p0, n/5, replace = FALSE) # estrategia A
   estrB <- p0[seq(1, n, 5)] # estrategia B
   # resultados ciclo 1
   resultados[2, ] <- c(mean(estrA), var(estrA), mean(estrB), var(estrB))
   for(k in 3:ciclos) { # laço -- ciclos subsequentes
      ## populacao estrategia A ciclo n
      pA <- sample(estrA, n, replace = TRUE)
      estrA <- sample(p0, n/5, replace = FALSE)
      ## populacao estrategia B ciclo n
      pB <- sample(estrB, n, replace = TRUE)
      estrB <- pB[seq(1, n, 5)]
      # resultados ciclo n
      resultados[k, ] <- c(mean(estrA), var(estrA), mean(estrB), var(estrB))
   }
   saida1[[i]] <- resultados # armazena na saida
}
})

## SEGUNDO CASO -- paralelizada
#-----------------------------------------------------------------------------
## IDEM (realiza um simulacao de 'nsmc')
simula.i <- 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, n, 5)]
   resultados[2, ] <- c(mean(estrA), var(estrA), mean(estrB), var(estrB))
   for(k in 3:ciclos) {
      pA <- sample(estrA, n, replace = TRUE)
      estrA <- sample(p0, n/5, replace = FALSE)
      pB <- sample(estrB, n, replace = TRUE)
      estrB <- pB[seq(1, n, 5)]
      resultados[k, ] <- c(mean(estrA), var(estrA), mean(estrB), var(estrB))
   }
   return(resultados) # retorna uma simulacao
}

tempoB <- system.time({ # armazena o tempo de processamento
saida2 <- mclapply(1:nsmc, # numero de nsmc
# aplica a funcao -- faz a simulacao
                   simula.i,
                   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
})

## TEMPOS
tempoA[3]
tempoB[3]

Vale lembrar que é preciso estar usando ou Linux, ou Mac e é preciso antes fazer o download e chamar o pacote “multicore”. Espero que tenham gostado e que com esse exemplo consigam realizar suas próprias paraleilazações.

About these ads
Categoriaslinux, notícias, testes
  1. Franky
    27/11/2011 às 22:13

    Oi, fernandohtoledo…
    Gostei do exemplo, mas gostaria saber a fonte que você esta lindo.
    Abs

    J. Franky.

    • fernandohtoledo
      28/11/2011 às 07:13

      Franky, fico feliz que tenha gostado do, estou preparando uma reformulação no post para incluir o emprego dos threads pelas funções parallel() e collect(). Mas, respondendo a sua pergunta, os materiais que consultei foram as próprias documentações dos pacotes multicore e doMC e os tutoriais “Getting Started with doMC and foreach” do Steve Weston e a documentação do “novo” pacote parallel. Uma ótima pedida e ir pesquisando a diversidade de coisas no Task View do CRAN para High-Performance and Parallel Computing with R, em: http://cran.r-project.org/web/views/HighPerformanceComputing.html. Fico a disposição para qualquer outra dúvida.

  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

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.

Junte-se a 51 outros seguidores

%d blogueiros gostam disto: