GISProjekt R

Przyspieszanie skryptów – Wykorzystaj swój PROCESOR (future.apply)

Większość z nas posiada sprzęt komputerowy umożliwiający przyspieszenie naszych skyptów w R. W pierwszej kolejności powinniśmy przyjrzeć się naszym procesorom i wykorzystać je do zrównoleglenia wykonywanych operacji (przetwarzanie wielowątkowe). W dzisiejszym poście pokażemy Wam jak przyspieszyć nasze skrypty korzystając z biblioteki future.apply. Załadujemy bibliotekę:

library(future.apply)

Wbudowana w bibliotekę funkcja availableCores wyświetli nam ile rdzeni ma nasz procesor:

> availableCores()
system 
     8

Mój komputer ma 8 rdzeni, które mogę wykorzystać do równoległego przetwarzania danych.

Wczytajmy też dane, których używaliśmy już w poprzednim poście o przyspieszaniu skryptów:

r <- raster("d:/GIS_in_R/B08.tif")
grid <- readOGR(“d:/GIS_in_R/grid10x100.shp”)

Tym razem nasza siatka jest większa i ma 1000 poligonów.

Napiszmy funkcję, którą będziemy chcieli wykonać w pętli. Funkcja ta będzie:

  • wybierać konkretny poligon z warstwy grid, 
  • wycinać z rastra r fragment leżący w zakresie wybranego poligonu,
  • wyliczać średnią wartość pikseli z wyciętego kawałka zawierających się w poligonie.

Nasza funkcja wygląda tak:

nasza_funkcja <- function(x)
{
  g <- grid[x,]
  r_crop <- crop(r,g)
  v <- as.numeric(extract(r_crop,grid[x,],fun=mean))
  return(v)
}

Wykonajmy funkcję w pętli używając bazowej funkcji R sapply() i sprawdźmy ile nam to zajmie z użyciem system.time():

system.time(v <- sapply(seq_along(grid),FUN = nasza_funkcja))

Funkcja sapply wykonała działanie w 155,4 s.

użytkownik     system upłynęło 
    154.49       0.60 155.43

Teraz wykorzystamy możliwości naszego procesora do przyspieszenia naszych obliczeń. Najpierw musimy zdefiniować plan dla funkcji future:

plan(multiprocess,workers = 8)

I zastąpić sapply funkcją future_apply:

system.time(v <- future_sapply(seq_along(grid),FUN = nasza_funkcja))

Funkcja sapply_future wykonała działanie w 39,3 s. Prawie 4 x szybciej.

użytkownik     system upłynęło 
      0.37       0.28 39.31

Bibliotek future.apply ma wiele innych funkcji które możemy wykorzystać do przyspieszenia naszych skryptów. Polecamy zapoznać się z jej dokumentacją.