首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Sys.setenv()在R中不能立即生效?

为什么Sys.setenv()在R中不能立即生效?
EN

Stack Overflow用户
提问于 2022-10-22 18:46:06
回答 1查看 88关注 0票数 2

我试图理解与在R会话中设置环境变量有关的一些行为。

Context:在具有多核的计算机上,Intel可以在(足够大的)矩阵乘法过程中诱导数据竞争。这些数据竞争取决于线程模型。特别是在Ubuntu上,如果您没有设置MKL_THREADING_LAYER = "GNU" (不是默认的!)你可能会得到数据竞赛。

代码语言:javascript
复制
can_induce_data_race <- function() {
  X <- matrix(1:500 / 500, 50, 10)
  Y <- matrix(1:1000 / 1000, 10, 100)
  
  norm(X %*% Y)
}

Sys.getenv("MKL_THREADING_LAYER")
#> [1] ""

can_induce_data_race()
#> [1] 2997.423
can_induce_data_race()
#> [1] 2986.476
can_induce_data_race()
#> [1] 2757.553

现在,如果我使用callr::r()启动一个新的R会话,我既可以复制这个问题,也可以通过传递MKL_THREADING_LAYER = "GNU"来解决它。

代码语言:javascript
复制
callr::r(can_induce_data_race)
#> [1] 2997.423
callr::r(can_induce_data_race, env = c(MKL_THREADING_LAYER = "GNU"))
#> [1] 249.7852

我希望我能从我的R会话中解决这个问题,如下所示,但它似乎行不通。

代码语言:javascript
复制
callr::r(can_induce_data_race)
#> [1] 2967.369

Sys.setenv(MKL_THREADING_LAYER = "GNU")
Sys.getenv("MKL_THREADING_LAYER")
#> [1] "GNU"

can_induce_data_race()
#> [1] 2997.423

但是,此时使用callr::r(),就可以消除数据竞争。此外,如果我在我的MKL_THREADING_LAYER = "GNU"文件中指定了.Renviron,数据竞争就会被消除。

代码语言:javascript
复制
callr::r(can_induce_data_race)
#> [1] 249.7852
callr::r(can_induce_data_race, env = c(MKL_THREADING_LAYER = "GNU"))
#> [1] 249.7852

为什么当我在env参数中将它指定给callr::r()或通过.Renviron,而不是当我通过Sys.setenv()显式地设置它时,为什么会尊重它?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-26 18:30:38

由于许多原因,程序和库通常在启动时只读取一次环境变量。如果在加载库后更改了该值,则为时已晚:环境变量设置已被读取和应用,并且将不再查询该变量。您只能依赖您生成的子进程正在使用的新值。

所有这些都不是专门针对MKL或R的;实际上,这是非常普遍的做法。查找环境变量是相对昂贵的,也不是线程安全的,而且在运行时更改受变量影响的设置常常是不实际的。选择线程后端当然听起来像这样的情况。

如果希望将环境变量应用于启动的每个R会话,请在.bashrc.xsessionrc.desktop文件或其他等效位置(取决于使用何种类型的shell )中的某个位置定义导出的环境变量.xsessionrc

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74166247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档