问题 尚未支持mclapply长向量


我正在尝试运行一些R代码,因为内存而崩溃了。我得到的错误是:

Error in sendMaster(try(lapply(X = S, FUN = FUN, ...), silent = TRUE)) : 
  long vectors not supported yet: memory.c:3100

产生麻烦的功能如下:

StationUserX <- function(userNDX){
  lat1 = deg2rad(geolocation$latitude[userNDX])
  long1 = deg2rad(geolocation$longitude[userNDX])
  session_user_id = as.character(geolocation$session_user_id[userNDX])
  #Find closest station
  Distance2Stations <- unlist(lapply(stationNDXs, Distance2StationX, lat1, long1))
  # Return index for closest station and distance to closest station
  stations_userX = data.frame(session_user_id = session_user_id, 
                              station = ghcndstations$ID[stationNDXs], 
                              Distance2Station = Distance2Stations)    
  stations_userX = stations_userX[with(stations_userX, order(Distance2Station)), ]
  stations_userX = stations_userX[1:100,] #only the 100 closest stations...
  row.names(stations_userX)<-NULL
  return(stations_userX)
}

我用mclapply运行这个函数50k次。 StationUserX呼叫Distance2StationX 90k次。

是否有明显的方法来优化StationUserX功能?


11454
2018-04-22 22:12


起源

你有没有 Vectorize 要么 cmpfun (在里面 compiler 包)看它是否提供任何简单的加速? - Gary Weissman
也想想 foreach 用于并行化,这是很容易实现的 - Gary Weissman


答案:


mclapply 无法将工作线程中的所有数据发送回主线程。这是因为预先调度,每个线程运行大量迭代,然后同步所有数据。这很好而且速度很快,但会导致大约2GB的数据被发回,这是不可能做到的。

mclapply 同 mc.preschedule=F 关闭预先安排。现在,每次迭代都会产生自己的线程并返回自己的数据。它不会那么快,但它解决了问题。


14
2017-11-10 18:41





尝试使用 nextElem() 来自 iterators 包。它就像一个 Python中的“生成器”,因此您不必将整个列表加载到内存中。


-1
2018-04-22 22:25



我正在查看nextElem的手册页,但我真的不知道应该如何修改我的函数来使用它。能给我看看么?谢谢! - Ignacio
你能告诉哪个对象是导致问题的“长向量”吗?这个想法是你会用的 nextElem() 一个接一个地传递向量的元素,而不是一次性传递整个向量。 - rsoren
错误消息并没有真正说出来。我正在使用mclapply调用StationUserX并传递StationUserX。 StationUserX是50k观测值的向量。函数生成的对象,stations_userX是一个非常大的对象。我有100个站50倍用户。因此输出将有5 Millon行和3列。 - Ignacio
啊,我明白了。 mclapply 肯定很难让你回来 产量 因为它太大了 nextElem() 对此没有帮助。另一种选择是找出什么 mclapply think是一个“长矢量”,并且工作在比那个小的块中。抱歉。 - rsoren