Python和R的并行处理

文章探讨了Python中的多线程、多进程以及线程池实现并行处理,通过示例展示了`threading`,`multiprocessing`和`concurrent.futures`库的使用。同时,提到了R语言的`parallel`包,利用`parLapply`和`mclapply`进行并行计算,并强调了全局变量的处理和不同操作系统下的注意事项。
摘要由CSDN通过智能技术生成

Python的并行处理

python进行并行处理的分为多线程和多进程,多线程使用thread,多进程使用multiprocessing,还有线程池future。
假设要运行linux下的命令:
首先是普通的运行:

def Reconall(sub):
    subanat = filedir + "/" + sub + "/anat/" + sub + "_T1w.nii"
    Command_recon = "recon-all -s sub-101 -i sub-101_T1w.nii.gz -all"
    os.system(Command)

import os, sys
workpath = '/home/clancy/Document'
filedir = os.path.join(workpath, 'test')
subs = os.listdir(filedir)

## run per sub
sub = subs[0]
Recon(sub)

cpu占用率瞬间就100%,到AntsN4BiasFiledCorrectionFs函数。不过是单cpu。

其次试试pool,线程池:

import re
from pathlib import Path
subs = list(set([Path(f).stem for f in Path(fmriprep_dir).glob(f"sub-*") if Path(f).is_dir()]))
subs.sort(key=lambda x: int("".join(re.findall("\d+",x))))

from concurrent.futures import ThreadPoolExecutor
pool = ThreadPoolExecutor(max_works=3)
for sub in subs:
    pool.submit(Reconall, sub)
pool.shutdown

有2个cpu瞬间达到100%,到AntsN4BiasFiledCorrectionFs函数,第3个cpu落后了一些时间,但是后面也达到了100%。

然后试试多进程:

from multiprocessing import Pool
pool = Pool(processes=3)
for sub in subs:
    pool.apply(Reconall, args=(sub, ))
pool.close()
pool.join()

只有1个cpu达到100%,到AntsN4BiasFiledCorrectionFs函数。
所以其实linux命令算是多线程了。
但是当我连接远程hpc,跑单核可以到100%,跑多线程时,hpc每个线程最大只能到10%的cpu负载,可能是hpc进行了某种限制。
至于更复杂的python多进程,全局变量锁,这些在需要的时候再看看。目前这个已经能满足日常使用了。

R的并行处理

使用自带的基础parallel包,用到的函数有

parLapply(cl, x, FUN, ...)
mclapply(X, FUN, ..., mc.cores)

parLapply版本如下:

library(parallel)
#指定线程数
clus <- makeCluster(3)
#可以确定当前可用CPU数目
detectCores()
#编写函数用于测试
Run <- function(x){
  a <- sample(1:(10000*x), 1000)
  sd(a)
}
nums <- 1:1000
# 单线程版
lapply(nums, FUN = Run)
# 多线程版
parLapply(clus, nums ,fun = Run)

也就是在apply家族的函数,加一个par前缀就行。

parLapply无法使用全局变量,应传入后再使用,如下:

st = 10
clus <- makeCluster(3)
# 使用clusterExport传入全局变量
clusterExport(clus,"st",envir = environment())
Run <- function(x){
  a <- sample(st:(10000*x), 1000)
  sd(a)
}
nums <- 1:1000
system.time(parLapply(clus, nums ,fun = Run))
## 假如要使用全部的cores
clnum<-detectCores() 
cl <- makeCluster(getOption("cl.cores", clnum));
# 关闭并行处理
stopCluster(cl)
stopCluster(clus)

mcapply一般仅在linux下使用,window会有一些想不到的bug。mcapply版本如下:

mclapply(mc.preschedule = F, mc.cores = 4, nums, Run)

mc.cores就是要调用的cores数量,mc.preschedule就是保证一组数据出错不会影响另一组数据的计算(lapply如果遇到错误,会直接中止计算)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

clancy_wu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值