2013-05-05 14 views
7

के साथ वस्तुओं को डुप्लिकेट मैं एक बहुत ही विशाल स्ट्रिंग वेक्टर है और एक समानांतर कंप्यूटिंग foreach और dosnow पैकेज का उपयोग करना चाहते हैं से बचने के लिए कैसे। मैंने देखा कि foreach प्रत्येक प्रक्रिया के लिए वेक्टर की प्रतियां बनायेगा, इस प्रकार सिस्टम मेमोरी को जल्दी से निकालें। मैंने सूची वस्तु में वेक्टर को छोटे टुकड़ों में तोड़ने की कोशिश की, लेकिन अभी भी कोई स्मृति उपयोग में कमी नहीं दिख रही है। क्या किसी के पास इस पर विचार है? उपयोग किए जा रहे आम तौर पर क्योंकि श्रमिकों को प्रभावी ढंग से fork के जादू से tt साझा कर सकते हैं doMC बैकएंड के साथ अच्छी तरह से काम करता है बार-बार दोहराना कीforeach

library(foreach) 
library(doSNOW) 
library(snow) 

x<-rep('some string', 200000000) 
# split x into smaller pieces in a list object 
splits<-getsplits(x, mode='bysize', size=1000000) 
tt<-vector('list', length(splits$start)) 
for (i in 1:length(tt)) tt[[i]]<-x[splits$start[i]: splits$end[i]] 

ret<-foreach(i = 1:length(splits$start), .export=c('somefun'), .combine=c) %dopar% somefun(tt[[i]]) 
+1

बस एक विचार: यदि आप स्मृति की खपत में गिरावट दिखाई दे रही है जब 'सेवानिवृत्त बुला <-foreach (के टीटी में, .export = c ('somefun'), .combine = ग)% dopar% somefun (के) ' – Beasterfield

+0

संकेत, बीस्टरफील्ड के संकेत के लिए धन्यवाद, लेकिन ऐसा लगता है कि 'foreach'' वाक्यविन्यास 'को पहचानने में विफल रहता है। – baidao

+0

मुझे खेद है, बेशक मेरा मतलब था 'foreach (k = tt, ...) '। – Beasterfield

उत्तर

4

शैली: नीचे कुछ डेमो कोड हैं। लेकिन doSNOW के साथ, tt श्रमिकों को स्वत: निर्यात किया जाएगा, बहुत सारी मेमोरी का उपयोग करके, भले ही उन्हें केवल इसके एक अंश की आवश्यकता हो। @Beasterfield द्वारा सीधे tt पर फिर से शुरू करने के सुझाव को हल किया गया है, लेकिन यह इटरेटर्स के उपयोग और उचित समांतर बैकएंड के माध्यम से और अधिक मेमोरी कुशल होना संभव है।

इस तरह के मामलों में, मैं itertools पैकेज से isplitVector फ़ंक्शन का उपयोग करता हूं। यह एक वेक्टर को उप-वैक्टरों के अनुक्रम में विभाजित करता है, जिससे उन्हें वेक्टरेशन के लाभों को खोए बिना समानांतर में संसाधित किया जा सकता है। दुर्भाग्यवश, doSNOW के साथ, यह clusterApplyLB फ़ंक्शन snow पर clusterApplyLB पर इटरेटर्स का समर्थन नहीं करता है, तो यह इन उप-वैक्टरों को एक सूची में रखेगा। हालांकि, doMPI और doRedis बैकएंड ऐसा नहीं करेंगे। वे उप-वैक्टरों को श्रमिकों को सीधे आधे से ज्यादा स्मृति का उपयोग करके, श्रमिकों को भेज देंगे।

यहां एक संपूर्ण उदाहरण doMPI का उपयोग कर रहा है:

suppressMessages(library(doMPI)) 
library(itertools) 
cl <- startMPIcluster() 
registerDoMPI(cl) 
n <- 20000000 
chunkSize <- 1000000 
x <- rep('some string', n) 
somefun <- function(s) toupper(s) 
ret <- foreach(s=isplitVector(x, chunkSize=chunkSize), .combine='c') %dopar% { 
    somefun(s) 
} 
print(length(ret)) 
closeCluster(cl) 
mpi.quit() 

जब मैं अपने मैकबुक पर इस चलाने के प्रो स्मृति

$ time mpirun -n 5 R --slave -f split.R 

इसके बारे में 16 सेकंड लेता है 4 GB के साथ।

आप, श्रमिकों है कि आप एक ही मशीन पर बनाने की संख्या के साथ सावधान रहना होगा हालांकि chunkSize का मूल्य कम हो रही आप और अधिक शुरू करने के लिए अनुमति दे सकता है है।

यदि आप एक इटरेटर का उपयोग करने में सक्षम हैं, तो आप अपने मेमोरी उपयोग को और भी कम कर सकते हैं, जिसमें सभी तारों को एक ही समय में स्मृति में होने की आवश्यकता नहीं होती है। उदाहरण के लिए, यदि तार 'strings.txt' नाम की फ़ाइल में हैं, तो आप s=ireadLines('strings.txt', n=chunkSize) का उपयोग कर सकते हैं।

+0

विशेष रूप से 'ireadLines' के संबंध में, यह एक प्रबंधक/कार्यकर्ता प्रतिमान का पालन करता है जहां श्रमिक एक प्रबंधक प्रक्रिया द्वारा उत्पन्न होते हैं; 'itertools' का उपयोग करने का कोई तरीका है लेकिन एए में अधिक एसपीएमडी फैशन ([पीबीडीआर] (https://rdav.nics.tennessee.edu/2012/09/pbdr/) -like), ताकि आर श्रमिकों का प्रबंधन mpirun के लिए छोड़ दिया गया है? पूरी तरह से mpirun के हाथों में प्रक्रिया प्रबंधन की ज़िम्मेदारी रखकर जिम्मेदारियों के बेहतर विभाजन की तरह लगता है। –

+0

@ मार्टिन मॉर्गन: यह एक दिलचस्प विचार है।मैंने अपने स्वयं के एसपीएमडी-स्टाइल पैकेज के साथ 'आरएमपीआई' पर बनाया है, लेकिन मैंने उस संदर्भ में इटरेटर्स का उपयोग करने के बारे में नहीं सोचा था, हालांकि मुझे अन्य संदर्भों में वितरित इटरेटर्स के विचार में दिलचस्पी है। मैंने कभी 'पीबीडीआर' का उपयोग नहीं किया है, लेकिन मुझे इसे देखना चाहिए। –