首页 文章

防止R中的堆栈溢出,有大量的空闲RAM

提问于
浏览
1

我提前道歉,因为这篇文章没有任何可重复的例子 .

我使用R x64 3.4.2在相当大的矩阵上运行一些交叉验证的分析(列数~80000,行数在40和180之间) . 分析涉及多个功能选择步骤(使用内部函数或使用 CORElearn 包中的函数执行,使用C编写),以及功能的一些聚类和SVM模型的拟合(通过包 RWeka ,用Java编写) .

我正在使用 DELL Precision T7910 机器,有2个处理器 Intel Xeon E5-2695 v3 2.30 GHz ,192 Gb RAM和Windows 7 x64操作系统 .

为了加快分析的运行时间,我想将 doParallel 包与 foreach 结合使用 . 我将按如下方式设置群集

cl <- makeCluster(number_of_cores, type='PSOCK')
registerDoParallel(cl)

number_of_cluster 设置为2到10之间的各种数字( detectCore() 告诉我,我总共有56个核心) .

我的问题是,即使只将 number_of_cluster 设置为2,我收到了 protection from stack overflow 错误消息 . 问题是我在脚本运行时监视RAM使用情况,甚至没有使用20 Gb的192 Gb RAM .

如果我以顺序方式运行脚本,它会花费很多时间(大约需要42个行和大约80000列的3个小时),但它会一直运行到最后 .

我已经尝试过(差不多)书中的每一个技巧,以便在R中实现良好的内存管理:

  • 我正在根据需要加载和删除大变量,以减少内存使用量

  • 我正在使用函数分解步骤而不是直接编写脚本,以利用作用域

  • 我每次删除一个大对象时都会调用 gc() 以提示R将内存返回给操作系统

但我仍然无法并行运行脚本 .

有人对此有任何建议吗?每次运行分析时,我应该放弃并等待> 3小时吗?更一般地说:当拥有大量空闲RAM时,如何可能出现堆栈溢出问题?

UPDATE

我现在尝试使用相同的机器“伪并行化”工作:因为我正在运行10倍交叉验证方案,所以我打开5个不同的Rgui实例并在每个实例中运行2次 . 以这种方式进行,一切运行顺利,并且该过程确实比在单个R实例中运行少了10倍 . 令我惊讶的是,如果Rgui的10个实例可以同时运行并完成工作,这意味着机器具有所需的计算资源 . 因此,我无法真正了解具有10个簇的%dopar%不起作用的事实 .

1 回答

  • 1

    "protection stack overflow"意味着你已经用完了"protection stack",那太多的指针已被 PROTECT 编辑但尚未 UNPROTECT 编辑 . 这可能是因为您运行的代码中存在错误或效率低下(在包的本机代码中或在R的本机代码中,但不是R源代码中的错误) .

    此问题与堆上的可用内存量无关,因此调用 gc() 将不会产生任何影响,并且机器具有多少物理内存并不重要 . 请不要显式调用 gc() ,即使堆使用有问题,它只会使程序运行速度变慢但无效:如果没有足够的堆空间但可以通过垃圾回收获得,垃圾收集器将自动运行 . 由于问题是保护堆栈,既不重组R代码也不明确删除死变量将有所帮助 . 原则上,将代码结构化为(相对较小的)函数对于可维护性/可读性是一件好事,并且它还间接地减少了变量的范围,因此显式删除变量应该变得不必要 .

    增加指针保护堆栈大小可能会有所帮助,这可以在R启动时使用 --max-ppsize 从命令行完成 .

相关问题