當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


R mgcv.parallel mgcv 中的並行計算。


R語言 mgcv.parallel 位於 mgcv 包(package)。

說明

mgcv 可以利用多核或集群。

bam 可以使用基於 openMP 的並行化方法以及協變量的離散化來實現顯著的加速。這是使用 bamdiscrete=TRUE 選項來選擇的,線程數通過 nthreads 參數控製。這是擴展性最好的方法。請參閱下麵的示例。

或者,函數 bam 可以使用 parallel 包中提供的函數。請參閱下麵的示例。請注意,大多數多核機器的內存帶寬有限,因此並行速度往往相當不穩定。

函數 gam 可以通過 openMP 在(共享內存)多核機器上使用並行線程(如果支持)。為此,請通過在 gamcontrol 參數中將 nthreads 設置為要使用的核心數來設置所需的線程數。請注意,在大多數情況下,隻有主要的 步驟是並行的(n 是數據數量,p 是參數數量)。對於 GCV 估計的加性高斯模型,速度可能會令人失望,因為這些模型采用 SVD 步驟,這在實踐中也可能產生大量成本。 magic 也可以使用多個核心,但相同的注釋適用於 GCV 高斯加性模型。

NCVgam 一起使用時,通過在 gam.control 中設置 ncv.threads 可以獲得值得的性能改進。

如果control$nthreads 設置為大於檢測到的核心數,則僅使用檢測到的核心數。請注意,使用虛擬核心通常隻會帶來很小的加速,甚至可能會稍微減慢計算速度。例如,許多報告有 4 個核心的英特爾處理器實際上有 2 個物理核心,每個核心有 2 個虛擬核心,因此使用 2 個線程可以顯著提高速度,而使用 4 個線程幾乎沒有什麽額外的區別。

請注意,在 Intel 和類似處理器上,通常通過在 BIOS 中禁用 Hyper-Threading,然後將線程數設置為所使用的物理核心數來實現最大性能。這可以防止操作係統調度程序將 2 個浮點密集型線程發送到同一物理核心,它們必須共享浮點單元(和緩存),從而相互減慢速度。調度程序傾向於在 mgcv 中使用的管理器-工作程序多線程方法下執行此操作,因為管理器線程在工作程序設置為工作的點之前看起來非常繁忙,並且在調度程序時,調度程序沒有辦法知道管理器線程實際上沒有什麽可做的,直到工作人員完成為止。如果您在無法禁用hyper-threading的多核平台上工作,那麽可能值得將線程數設置為比物理核心數少一,以減少此類調度問題的頻率。

mgcv 的工作分割始終做出簡單的假設,即所有內核都是平等的,並且您不與其他浮點密集型線程共享它們。

除了 hyper-threading 之外,還有幾個函數可能會導致縮放效果明顯不佳。首先,許多CPU都有Turbo模式,隻要CPU使用的總功率不超過設計限製,少數核心就可以以更高的頻率運行,但是CPU上的所有核心都不可能以更高的頻率運行。這個頻率。因此,當您最終添加線程時,CPU 頻率必須降低到 Turbo 頻率以下,結果是您無法通過添加內核獲得預期的速度。其次,大多數現代 CPU 都會根據負載動態設置頻率。您可能需要設置係統電源管理策略以支持高性能,以便最大限度地提高所有線程以您希望的速度運行的機會(您可以在 BIOS 中關閉動態電源控製,但隨後您也可以關閉渦輪也)。

由於 mgcv 中的計算負擔全部在線性代數中,因此並行計算可能會通過調整的 BLAS 提供減少的好處或沒有好處。如果您使用多線程 BLAS,情況尤其如此,但如果線程必須共享緩存,則經過調整以有效利用特定緩存大小的 BLAS 也可能會遇到性能損失。

例子

## illustration of multi-threading with gam...

require(mgcv);set.seed(9)
dat <- gamSim(1,n=2000,dist="poisson",scale=.1)
k <- 12;bs <- "cr";ctrl <- list(nthreads=2)

system.time(b1<-gam(y~s(x0,bs=bs)+s(x1,bs=bs)+s(x2,bs=bs,k=k)
            ,family=poisson,data=dat,method="REML"))[3]

system.time(b2<-gam(y~s(x0,bs=bs)+s(x1,bs=bs)+s(x2,bs=bs,k=k),
            family=poisson,data=dat,method="REML",control=ctrl))[3]

## Poisson example on a cluster with 'bam'. 
## Note that there is some overhead in initializing the 
## computation on the cluster, associated with loading 
## the Matrix package on each node. Sample sizes are low
## here to keep example quick -- for such a small model
## little or no advantage is likely to be seen.
k <- 13;set.seed(9)
dat <- gamSim(1,n=6000,dist="poisson",scale=.1)

require(parallel)  
nc <- 2   ## cluster size, set for example portability
if (detectCores()>1) { ## no point otherwise
  cl <- makeCluster(nc) 
  ## could also use makeForkCluster, but read warnings first!
} else cl <- NULL
  
system.time(b3 <- bam(y ~ s(x0,bs=bs,k=7)+s(x1,bs=bs,k=7)+s(x2,bs=bs,k=k)
            ,data=dat,family=poisson(),chunk.size=5000,cluster=cl))

fv <- predict(b3,cluster=cl) ## parallel prediction

if (!is.null(cl)) stopCluster(cl)
b3

## Alternative, better scaling example, using the discrete option with bam...

system.time(b4 <- bam(y ~ s(x0,bs=bs,k=7)+s(x1,bs=bs,k=7)+s(x2,bs=bs,k=k)
            ,data=dat,family=poisson(),discrete=TRUE,nthreads=2))

作者

Simon Wood <simon.wood@r-project.org>

參考

https://hpc-tutorials.llnl.gov/openmp/

相關用法


注:本文由純淨天空篩選整理自R-devel大神的英文原創作品 Parallel computation in mgcv.。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。