2016-07-06 10 views
10

मैं लोड करने के लिए क्या करता है यह समझने के लिए parLapplyLB() फ़ंक्शन का परीक्षण कर रहा हूं। लेकिन मुझे कोई संतुलन नहीं दिख रहा है। के लिए सोने होगा: उदाहरण के लिए,parLapplyLB वास्तव में लोड संतुलन क्यों नहीं करता है?

cl <- parallel::makeCluster(2) 

system.time(
    parallel::parLapplyLB(cl, 1:4, function(y) { 
    if (y == 1) { 
     Sys.sleep(3) 
    } else { 
     Sys.sleep(0.5) 
    }})) 
## user system elapsed 
## 0.004 0.009 3.511 

parallel::stopCluster(cl) 

यदि यह सही मायने में लोड, पहली नौकरी (नौकरी 1) कि 3 सेकंड के लिए सोता संतुलन था प्रथम नोड और अन्य तीन नौकरियों (4 नौकरियों 2) पर होगा अन्य नोड पर कुल 1.5 सेकंड। कुल मिलाकर, सिस्टम का समय केवल 3 सेकंड होना चाहिए।

इसके बजाय, मुझे लगता है कि नौकरी 1 और 2 नोड 1 को दी जाती हैं और नौकरियां 3 और 4 नोड 2 को दी जाती हैं। परिणामस्वरूप कुल समय 3 + 0.5 = 3.5 सेकंड होता है। यदि हम parLapplyLB() के बजाय parLapply() के साथ एक ही कोड चलाते हैं, तो हमें लगभग 3.5 सेकंड का सिस्टम सिस्टम मिलता है।

मैं समझ नहीं रहा या गलत क्या कर रहा हूं?

+0

मुझे लगता है कि आर स्वत: लोड संतुलन नहीं करता है। मुझे लगता है कि यह प्रत्येक कार्य को करने के लिए जितना समय लगता है, या जब प्रत्येक कार्य पूरा हो जाता है, तो यह * कार्यों * को कई कोरों में उपलब्ध कराता है। ऐसा नहीं है कि कार्यों की कतार है, और जब एक कार्यकर्ता समाप्त होता है तो वह अगले को पकड़ लेता है। प्रत्येक कोर को दो कार्य सौंपा गया था। इसलिए पहले कार्यकर्ता पर 3 + 0.5, और कुल 3.5। * गलत होने के लिए खुश होगा * – gregmacfarlane

+3

हां वह 3.5 है जहां से आ रहा है। यह भार संतुलन नहीं है। लेकिन parLapplyLB संतुलन का दावा करता है। – josiekre

उत्तर

10

एक (उस बात के लिए किसी भी कार्य के लिए, जिसके लिए मैंने कभी जरूरत गए समानांतर और,,) parLapplyLB आपके जैसे कार्य के लिए वास्तव में इस काम के लिए सही उपकरण नहीं है। क्यों नहीं देखने के लिए, जिस तरह से पर एक नज़र है कि यह लागू हो जाता है है:

parLapplyLB 
# function (cl = NULL, X, fun, ...) 
# { 
#  cl <- defaultCluster(cl) 
#  do.call(c, clusterApplyLB(cl, x = splitList(X, length(cl)), 
#   fun = lapply, fun, ...), quote = TRUE) 
# } 
# <bytecode: 0x000000000f20a7e8> 
# <environment: namespace:parallel> 

## Have a look at what `splitList()` does: 
parallel:::splitList(1:4, 2) 
# [[1]] 
# [1] 1 2 
# 
# [[2]] 
# [1] 3 4 

समस्या यह है कि यह पहली बार जिनमें से प्रत्येक समान आकार की उप-सूचियों कि यह तो नोड्स के बीच वितरित करता है, में नौकरियों की अपनी सूची विभाजन है अपने दिए गए उपन्यास पर lapply() चलाता है। तो यहां, आपका पहला नोड पहले और दूसरे इनपुट पर नौकरियां चलाता है, जबकि दूसरा नोड तीसरे और चौथे इनपुट का उपयोग करके नौकरियां चलाता है।

इसके बजाय, अधिक बहुमुखी clusterApplyLB() है, जो काम करता है आप आशा करता हूँ बस के रूप में उपयोग करें:

system.time(
    parallel::clusterApplyLB(cl, 1:4, function(y) { 
    if (y == 1) { 
     Sys.sleep(3) 
    } else { 
     Sys.sleep(0.5) 
    }})) 
# user system elapsed 
# 0.00 0.00 3.09 
+0

धन्यवाद! वह जो मैं खोज रहा था। मैं ऐसे मामले के बारे में नहीं सोच सकता जहां parLapplyLB parLapply से कुछ अलग उत्पादन करेगा, और इसलिए मुझे यकीन नहीं है कि इसका उद्देश्य क्या है। – josiekre

+0

क्या 'क्लस्टरएप्लीएलबी (सीएल, एक्स, मजेदार)' का समान उद्देश्य व्यवहार 'parLapplyLB' है? मैं अपने सिस्टम पर यह कोशिश कर रहा हूं, और ऐसा लगता है कि 'एक्स' एक सूची है, लेकिन यह एक छोटा आउटपुट देता है, लेकिन मैं' क्लस्टरएप्लीएलबी 'के साथ' parLapplyLB' को बस स्वैप कर रहा हूं .. – guy

+2

यहां उपयोगी जानकारी , साथ ही उपयोगकर्ता परिभाषित parlapplyLB http://detritus.fundacioace.com/pub/books/Oreilly.Parallel.R.Oct.2011.pdf – Olivia

1

parLapplyLB लोड संतुलन नहीं है क्योंकि यह एक अर्थ बग है। हमने बग पाया और एक फिक्स प्रदान किया, here देखें। अब, यह तय करने के लिए आर devs तक है।

संबंधित मुद्दे