我试图理解与在R会话中设置环境变量有关的一些行为。
Context:在具有多核的计算机上,Intel可以在(足够大的)矩阵乘法过程中诱导数据竞争。这些数据竞争取决于线程模型。特别是在Ubuntu上,如果您没有设置MKL_THREADING_LAYER = "GNU" (不是默认的!)你可能会得到数据竞赛。
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"来解决它。
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会话中解决这个问题,如下所示,但它似乎行不通。
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,数据竞争就会被消除。
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()显式地设置它时,为什么会尊重它?
发布于 2022-10-26 18:30:38
由于许多原因,程序和库通常在启动时只读取一次环境变量。如果在加载库后更改了该值,则为时已晚:环境变量设置已被读取和应用,并且将不再查询该变量。您只能依赖您生成的子进程正在使用的新值。
所有这些都不是专门针对MKL或R的;实际上,这是非常普遍的做法。查找环境变量是相对昂贵的,也不是线程安全的,而且在运行时更改受变量影响的设置常常是不实际的。选择线程后端当然听起来像这样的情况。
如果希望将环境变量应用于启动的每个R会话,请在.bashrc、.xsessionrc、.desktop文件或其他等效位置(取决于使用何种类型的shell )中的某个位置定义导出的环境变量.xsessionrc。
https://stackoverflow.com/questions/74166247
复制相似问题