You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

并行场景下是否需根据工作进程数调整terra的memfrac参数?

问题描述

使用future/future.apply包运行terra代码时遭遇内存错误:Error in eval(expr, p) : std::bad_alloc。当前配置为:

  • 并行计划采用future包的"multisession"策略,工作进程数为4
  • terra的memfrac参数保留默认值0.6

疑问:

  1. 是否需要根据工作进程数调整memfrac参数?
  2. future.callr::callr并行计划是否适用于该场景?该计划下memfrac参数如何处理?

示例代码:

library(terra)
#> terra 1.7.78
library(future.apply)
#> Loading required package: future
library(stringr)

# 坡度计算函数
slopefun<- function(x){
  fn<- paste0(str_remove(x, "\\.tif$"),"_slope.tif")
  terrain(rast(x), v="slope", filename=fn, overwrite=TRUE)
  return(fn)
}

# 创建数据集
r<- rast(volcano, 
         extent= ext(2667400, 2667400 + ncol(volcano)*10, 
                     6478700, 6478700 + nrow(volcano)*10), 
         crs = "EPSG:27200")

# 文件名列表
r_list<- list("test1.tif", "test2.tif", "test3.tif", "test4.tif")

# 将数据写入对应文件
writeRaster(r, filename = r_list[[1]], overwrite=TRUE)
writeRaster(r*2, filename = r_list[[2]], overwrite=TRUE)
writeRaster(r*3, filename = r_list[[3]], overwrite=TRUE)
writeRaster(r*4, filename = r_list[[4]], overwrite=TRUE)

nworkers<- 4

plan(strategy = "multisession", workers= nworkers) # 配置并行环境
res_list<- future_lapply(r_list, FUN = slopefun)
plan(strategy = "sequential")

# 结果大于1,是否需要除以工作进程数?
# 例如在本场景中,因有4个工作进程,是否需将memfrac降至0.25或更低?
terraOptions()$memfrac*nworkers
#> memfrac   : 0.6
#> tolerance : 0.1
#> verbose   : FALSE
#> todisk    : FALSE
#> tempdir   : C:/Users/socce/AppData/Local/Temp/Rtmp2puqqO
#> datatype  : FLT4S
#> memmin    : 1
#> progress  : 3
#> [1] 2.4
解答

1. 必须根据工作进程数调整memfrac参数

terra的memfrac参数定义的是单个R进程可使用的系统内存比例,而非总内存的比例。在multisession并行模式下,每个工作进程都是独立的R实例,会各自按照memfrac设定的比例占用内存。

以你的场景为例,4个工作进程×0.6的内存比例=2.4,意味着所有进程尝试占用的内存总量是系统总内存的2.4倍,远超实际可用内存,这正是触发std::bad_alloc内存错误的核心原因。

调整建议:

  • 直接将memfrac设置为1/工作进程数左右,比如4个进程时设为0.2(比0.25略低,预留缓冲空间)
  • 执行调整代码:terraOptions(memfrac = 0.2)
  • 如果仍出现内存问题,可进一步降低该值,或减少工作进程数

2. future.callr::callr计划的适用性及memfrac处理

适用性

callr并行计划会为每个任务启动一个独立的、完全隔离的R进程,与multisession类似,但进程管理更严谨,能避免部分进程间的资源冲突或内存泄漏问题。如果multisession模式下的内存问题伴随进程间干扰,callr计划会是更稳定的替代方案,完全适用于你的坡度计算场景。

memfrac处理逻辑

callr计划下,每个独立R进程仍会遵循terra的memfrac参数设置,因此同样需要根据工作进程数调整memfrac值,原理和multisession一致,避免总内存占用过载。

额外优化:
callr支持通过rlimits参数直接限制每个进程的内存上限,比memfrac更直观。例如,限制每个进程最多使用2GB内存:

library(future.callr)
plan(callr, workers = 4, rlimits = list(asize = 2e9)) # asize单位为字节
terraOptions(memfrac = 0.8) # 此时memfrac基于每个进程的内存上限计算,而非系统总内存

内容的提问来源于stack exchange,提问作者ailich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:27:04