R Производительность обработки данных (пакет снегопада и объем функций)
Я немного новичок в мире программирования на R и имею дело с некоторыми проблемами, связанными с распараллеливанием обработки (не так много) больших данных.
Для этого я использую пакет data.table для хранения и обработки данных, а пакет snowfall - в качестве оболочки для распараллеливания работы.
Я привел пример конкретного случая: у меня большой вектор элементов, и я хочу применить функцию f (я использую векторизованную версию) для каждого элемента; затем я балансирую большой вектор на N частей (меньшие векторы) следующим образом:
sfInit(parallel = TRUE, cpus = ncpus)
balancedVector <-myVectorLoadBalanceFunction(myLargeVector, ncpus)
processedSubVectors <- sfLapply(balancedVector, function(subVector) {
myVectorizedFunction(subVector)
})
sfStop()
Что я вижу странным, так это то, что когда я запускаю этот кусок кода из командной строки или скрипта (то есть, largeVector находится в глобальной среде), производительность хорошая с точки зрения времени, и я вижу в диспетчере задач MS Windows, что каждое ядро кажется, использует объем памяти, пропорциональный размеру subVector; но когда я запускаю код в функциональной среде (то есть вызывая его из командной строки и передавая LargeVector в качестве аргумента), производительность ухудшается с точки зрения времени, и я проверяю, что теперь каждое ядро использует полную копию largeVector...
Имеет ли это смысл?
С уважением
РЕДАКТИРОВАТЬ, чтобы добавить воспроизводимый пример
Для простоты - фиктивный пример с вектором даты ~300 МБ с элементами +36 М и функцией дня недели:
library(snowfall)
aSomewhatLargeVector <- seq.Date(from = as.Date("1900-01-01"), to = as.Date("2000-01-01"), by = 1)
aSomewhatLargeVector <- rep(aSomewhatLargeVector, 1000)
# Sequential version to compare
system.time(processedSubVectorsSequential <- weekdays(aSomewhatLargeVector))
# user system elapsed
# 108.05 1.06 109.53
gc() # I restarted R
# Parallel version within a function scope
myCallingFunction = function(aSomewhatLargeVector) {
sfInit(parallel = TRUE, cpus = 2)
balancedVector <- list(aSomewhatLargeVector[seq(1, length(aSomewhatLargeVector)/2)],
aSomewhatLargeVector[seq(length(aSomewhatLargeVector)/2+1, length(aSomewhatLargeVector))])
processedSubVectorsParallelFunction <- sfLapply(balancedVector, function(subVector) {
weekdays(subVector)
})
sfStop()
processedSubVectorsParallelFunction <- unlist(processedSubVectorsParallelFunction)
return(processedSubVectorsParallelFunction)
}
system.time(processedSubVectorsParallelFunction <- myCallingFunction(aSomewhatLargeVector))
# user system elapsed
# 11.63 10.61 94.27
# user system elapsed
# 12.12 9.09 99.07
gc() # I restarted R
# Parallel version within the global scope
time0 <- proc.time()
sfInit(parallel = TRUE, cpus = 2)
balancedVector <- list(aSomewhatLargeVector[seq(1, length(aSomewhatLargeVector)/2)],
aSomewhatLargeVector[seq(length(aSomewhatLargeVector)/2+1, length(aSomewhatLargeVector))])
processedSubVectorsParallel <- sfLapply(balancedVector, function(subVector) {
weekdays(subVector)
})
sfStop()
processedSubVectorsParallel <- unlist(processedSubVectorsParallel)
time1 <- proc.time()
time1-time0
# user system elapsed
# 7.94 4.75 85.14
# user system elapsed
# 9.92 3.93 89.69
Мои времена появляются в комментариях, хотя для этого фиктивного примера нет столь существенной разницы, но видно, что последовательное время> параллельное в функции> параллельное в глобальном
Кроме того, вы можете увидеть различия в распределенной памяти:
3,3 ГБ < 5,2 ГБ> 4,4 ГБ
Надеюсь это поможет