mclapply暂不支持长向量

11

我试图运行一些 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?


你尝试过使用Vectorize或者compiler包中的cmpfun来看是否能够提供简单的加速吗? - Gary Weissman
同时考虑使用foreach进行并行化,这是非常容易实现的。 - Gary Weissman
2个回答

14

mclapply在将数据从工作线程发送回主线程时存在问题。这是由于预调度,在每个线程中运行大量迭代,然后同步所有数据回来。这很快,但导致发送超过2GB的数据,而这是无法完成的。

使用mc.preschedule=F运行mclapply以关闭预调度。现在,每次迭代都会生成自己的线程并返回自己的数据。虽然速度不会那么快,但可以解决这个问题。


-1

尝试使用iterators包中的nextElem()。它的行为类似于Python中的"生成器", 因此您不必将整个列表加载到内存中。


我正在查看nextElem的手册,但我不太明白如何修改我的函数来使用它。你能给我展示一下吗?谢谢! - Ignacio
你能告诉我哪个对象是导致问题的“长向量”吗?思路是使用nextElem()逐一传递向量的元素,而不是一次性传递整个向量。 - rsoren
错误信息并没有真正说明问题。我正在使用mclapply调用StationUserX,并传递了StationUserX。StationUserX是一个包含5万个观测值的向量。该函数产生的对象stations_userX是一个非常大的对象。我有100个站点,每个站点有5万个用户。因此,输出将具有500万行和3列。 - Ignacio
啊,我明白了。 mclapply 明显无法返回太大的 输出nextElem() 也无法解决这个问题。另一个选择是找出 mclapply 认为是“长向量”的大小,并分块处理,使其小于该大小。抱歉。 - rsoren

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接