"মাল্টিকোর" ব্যবহার করার জন্য কীভাবে আমার আর স্ক্রিপ্টটি অনুকূল করা যায়


15

আমি একটি উবুন্টু-লুসিড পিসিতে জিএনইউ আর ব্যবহার করছি যার মধ্যে 4 টি সিপিইউ রয়েছে। সমস্ত 4 টি সিপিইউ ব্যবহার করার জন্য, আমি "আর-ক্র্যান-মাল্টিকোর" প্যাকেজটি ইনস্টল করেছি। প্যাকেজের ম্যানুয়ালটিতে আমি যে বাস্তব উদাহরণগুলি বুঝতে পারি তার অভাব হওয়ায়, সমস্ত 4 সিপিইউ ব্যবহার করতে আমার স্ক্রিপ্টটি কীভাবে অনুকূল করা যায় সে সম্পর্কে আমার পরামর্শ প্রয়োজন need

আমার ডেটাসেটটি একটি ডেটা ফ্রেম (পি 1 নামে পরিচিত) যা 50,000 সারি এবং 1600 কলস রয়েছে। প্রতিটি সারির জন্য, আমি ম্যাক্সিমুন, যোগফল এবং গড় গণনা করতে চাই। আমার লিপিটি নিম্নরূপ দেখায়:

p1max <- 0
p1mean <- 0
p1sum <-0
plength <- length(P1[,1])
for(i in 1:plength){
   p1max <- c(p1max, max(P1[i,]))
   p1mean <- c(p1mean, mean(P1[i,]))
   p1sum <- c(p1sum, sum(P1[i,]))
}

কেউ দয়া করে সমস্ত 4 সিপিইউ ব্যবহার করার জন্য কীভাবে স্ক্রিপ্টটি সংশোধন ও পরিচালনা করবেন তা আমাকে বলতে পারেন?


উপরের প্রোগ্রামটিতে একটি ত্রুটি রয়েছে: লাইনটি "এর জন্য (1 ইন: লাভ)" হওয়া উচিত
সাইমন বায়ার্ন

আপনি দৃth়, thx!
প্রোডুনিস

1
এটি স্ট্যাকওভারফ্লোতে অন্তর্ভুক্ত নয়?
আর_চোলিক

1
এটি স্ট্যাকওভারফ্লোতে অন্তর্ভুক্ত। এখানে কোনও পরিসংখ্যানের প্রশ্ন নেই। শুধুমাত্র একটি সাধারণ প্রোগ্রামিং প্রশ্ন।
জেডি লং

উত্তর:


11

ফরচ এবং ডোএমসি ব্যবহার করুন । বিস্তারিত ব্যাখ্যা এখানে পাওয়া যাবে । আপনার স্ক্রিপ্টটি খুব সামান্য পরিবর্তন হবে, রেখাটি

for(i in 1:plength){

পরিবর্তন করা উচিত

foreach(i=1:plength) %dopar% { 

এই প্যাকেজগুলি ব্যবহার করে যে কোনও মাল্টিটাস্কিং স্ক্রিপ্টের পূর্বশর্তগুলি হ'ল

library(foreach)
library(doMC)
registerDoMC()

সাবধানতা নোট। ডকুমেন্টেশন অনুযায়ী আপনি এটি জিইউতে ব্যবহার করতে পারবেন না।

আপনার সমস্যা হিসাবে, আপনার কি সত্যিই মাল্টিটাস্কিং দরকার? আপনার ডেটা.ফ্রেমে প্রায় 1.2 গিগাবাইট র‌্যাম লাগে, তাই এটি আপনার স্মৃতিতে মাপসই করা উচিত। সুতরাং আপনি কেবল প্রয়োগ প্রয়োগ করতে পারেন:

p1smry <- apply(P1,1,summary)

ফলাফল প্রতিটি সারির সংক্ষিপ্তসার সহ একটি ম্যাট্রিক্স হবে।

আপনি প্যাকেজ মাল্টিকোর মধ্যে যে mclapply ফাংশন ব্যবহার করতে পারেন । তারপরে আপনার স্ক্রিপ্টটি দেখতে দেখতে এটির মতো হতে পারে:

loopfun <- function(i) {
     summary(P1[i,])
}

res <- mclapply(1:nrow(P1),loopfun)

এটি তালিকাটি ফিরিয়ে দেবে, যেখানে আই-থিম উপাদানটি আই-তম সারির সংক্ষিপ্তসার হবে। আপনি এটিকে স্যাপ্লি ব্যবহার করে ম্যাট্রিক্সে রূপান্তর করতে পারেন

mres <- sapply(res,function(x)x)

আপনাকে অনেক ধন্যবাদ. আপনি ঠিক বলেছেন, "প্রয়োগ" দিয়ে স্ক্রিপ্টটি অনুকূলিত করা যেতে পারে। আমি আমার স্ক্রিপ্টটি কেবলমাত্র একটি ন্যূনতম উদাহরণ হিসাবে ব্যবহার করে বার্তাটি পাওয়ার জন্য ব্যবহার করেছি ... অনেক ধন্যবাদ, আপনার উত্তরটি ঠিক আমি যা খুঁজছিলাম তা হ'ল !!
প্রোডুনিস

15

একাধিক কোর কীভাবে ব্যবহার করবেন সে সম্পর্কে ইতিমধ্যে আপনার কাছে একটি উত্তর পেয়েছে, তবে আসল সমস্যাটি আপনি নিজের লুপগুলি লিখেছেন with লুপের প্রতিটি পুনরাবৃত্তিতে কখনই আপনার ফলাফল ভেক্টর / অবজেক্টটি প্রসারিত করবেন না । আপনি যদি এটি করেন, আপনি আর কে আপনার ফলাফল ভেক্টর / অবজেক্টটি অনুলিপি করতে বাধ্য করেন এবং এটি সমস্ত সময় লাগে বলে প্রসারিত করে। পরিবর্তে, লুপটি শুরু করার আগে পর্যাপ্ত স্টোরেজ স্পেসটি বানাবেন এবং আপনি পাশাপাশি যাবেন। এখানে একটি উদাহরণ:

set.seed(1)
p1 <- matrix(rnorm(10000), ncol=100)
system.time({
p1max <- p1mean <- p1sum <- numeric(length = 100)
for(i in seq_along(p1max)){
   p1max[i] <- max(p1[i,])
   p1mean[i] <- mean(p1[i,])
   p1sum[i ]<- sum(p1[i,])
}
})

   user  system elapsed 
  0.005   0.000   0.005

অথবা আপনি এই জিনিসগুলি এর মাধ্যমে করতে পারেন apply():

system.time({
p1max2 <- apply(p1, 1, max)
p1mean2 <- apply(p1, 1, mean)
p1sum2 <- apply(p1, 1, sum)
})
   user  system elapsed 
  0.007   0.000   0.006 

তবে মনে রাখবেন এটি কোনটি নয় লুপ সঠিকভাবে এবং কখনও কখনও ধীর করছেন তুলনায় দ্রুততর।

তবে, সবসময় ভেক্টরাইজড কোডের সন্ধানে থাকুন। আপনি সারি অঙ্কের অর্থ এবং ব্যবহারগুলি করতে পারেন rowSums()এবং rowMeans()এটি লুপ বা applyসংস্করণগুলির চেয়ে দ্রুততর :

system.time({
p1max3 <- apply(p1, 1, max)
p1mean3 <- rowMeans(p1)
p1sum3 <- rowSums(p1)
})

   user  system elapsed 
  0.001   0.000   0.002 

আমি যদি বাজি ধরার লোক ছিলাম, তৃতীয় পদ্ধতির কাছে আমি মারধরের কথা উল্লেখ করে টাকা পেতাম foreach() আপনার ম্যাট্রিক্সের গতি পরীক্ষার জন্য বা অন্য মাল্টি-কোর বিকল্পগুলির পেতাম কারণ তাদের ওভারহেড সেট আপ করার ক্ষেত্রে ন্যায্যতা প্রমাণ করতে তাদের জিনিসগুলি যথেষ্ট গতিতে হবে would পৃথক পৃথক প্রসেসগুলি যা বিভিন্ন সিপিইউ কোরগুলি তৈরি করে।

আপডেট: @ শ্যাববিচেফের মন্তব্য অনুসরণ করে একবারের অঙ্কগুলি করা এবং গড়ের গণনায় পুনরায় ব্যবহার করা কি দ্রুত?

system.time({
    p1max4 <- apply(p1, 1, max)
    p1sum4 <- rowSums(p1)
    p1mean4 <- p1sum4 / ncol(p1)
    })

   user  system elapsed 
  0.002   0.000   0.002

এই পরীক্ষার দৌড়ে নয়, তবে এটি পরিসীমা থেকে দূরে ...


এফডাব্লুআইডাব্লু, মতলব প্র্যাক্টিকেশন এবং প্রসারণকারী ভেক্টর সম্পর্কিত একই সমস্যা রয়েছে এবং এটি একটি ক্লাসিক কোড 'ব্লোপার'। আপনার বাজী ছাড়াও, এটি সম্ভবত ফলাফল ব্যবহার করতে দ্রুততর rowSumsসারি মানে গনা (যদি না আমি সংক্রান্ত কিছু অনুপস্থিত করছি যেমন নার বা NAN)। আপনার তৃতীয় পদ্ধতির কোডটি প্রতিটি কলামে দুবার যোগ করে
shabbychef

@ শ্যাববিচেফ আপনি অবাক হবেন (আমার সম্পাদিত উত্তর দেখুন) হ্যাঁ অঙ্কের ধারণাগত দুইবার নির্ণিত হয়, কিন্তু rowSumsrowMeansঅত্যন্ত কম্পাইল কোড এবং কি আমরা কেবল অঙ্কের কম্পিউটিং একবার লাভ অপ্টিমাইজ করা হয়, আমরা ব্যাখ্যা কোডে গড় গণনার করছেন আবার আলগা।
মনিকা পুনরায় ইনস্টল করুন - জি সিম্পসন

@ গ্যাভিন সিম্পসন: এত দ্রুত নয়: পরিবর্তে system.time({ for (iii in c(1:1000)) { p1max3 <- apply(p1, 1, max) p1mean3 <- rowMeans(p1) p1sum3 <- rowSums(p1) } })এবং একইভাবে চেষ্টা করুন system.time({ for (iii in c(1:1000)) { p1max4 <- apply(p1, 1, max) p1sum4 <- rowSums(p1) p1mean4 <- p1sum4 / ncol(p1) } }); যে সংস্করণটি যোগফলটি পুনরুদ্ধার করে না তা আমার কম্পিউটারে 1.368 সেকেন্ড সময় নেয়; এক যা লাগে 1.396। আবার
পরিস্ফুটিত

@shabbychef আমরা কি বা বাধ্যকারী নয় ;-) আসলে, আপনার আরও কঠোর সিমিউলেশন আমার মূল বিন্দু শক্তিশালী, যে হিসাবে বিভিন্ন ধারনা থাকতে হবে rowMeansএবং rowSumsদক্ষ, অপ্টিমাইজ কম্পাইল কোডে প্রয়োগ করা হয় তারা বীট করা কঠিন হতে যাচ্ছি।
মনিকা পুনরায় ইনস্টল করুন - জি সিম্পসন

@ গ্যাভিন সিম্পসন আসলে, আমার উদাহরণটিতে সমস্যাটি হ'ল বেশিরভাগ সময় প্রয়োগের অংশে সর্বাধিক গণনা করা হয়। আমি আপনার সাথে একমত যে একটি সি-ভিত্তিক ভেক্টরাইজড ফাংশনটি rowMeanসাধারণ-উদ্দেশ্যে আর সরঞ্জামের মতো মারতে শক্ত হতে চলেছে *apply। যাইহোক, আপনি সুপারিশ এটা 10000 সংখ্যার যোগফল দ্রুত যে মনে দুইবার মাধ্যমে rowMeanএবং rowSumবরং শুধুমাত্র একবার এবং ব্যবহার আর এর builtin বিভাজন অপারেটর নয়। আমি জানি আর এর কয়েকটি দক্ষতার সমস্যা রয়েছে ( যেমন: কোঁকড়া ধনুর্বন্ধনী বনাম প্রথম বন্ধনী সম্পর্কিত সাম্প্রতিক আবিষ্কার), তবে এটি পাগল বলে মনে হচ্ছে।
shabbychef

1

কটাক্ষপাত আছে তুষার এবং তুষারপাত প্যাকেজ। সেগুলির সাথে প্রচুর উদাহরণ ...

আপনি যদি আর এবং সমান্তরালতা সম্পর্কে শিখার চেয়ে সেই নির্দিষ্ট কোডটি দ্রুত করতে চান তবে আপনার এটি করা উচিত

P1 = matrix(rnorm(1000), ncol=10, nrow=10
apply(P1, 1, max)
apply(P1, 1, mean)
apply(P1, 1, sum)

দয়া করে আমার স্ক্রিপ্টটি সংশোধন করতে আমাকে সহায়তা করুন ...
প্রোডুনিস

2
এগুলি কেবল আপনার কাছ থেকে লুপটি আড়াল করছে। @ প্রোডুনিস কোডের সাথে আসল সমস্যাটি হ'ল জোর করে অনুলিপি চলছে কারণ ফলাফল ভেক্টরগুলি লুপের প্রতিটি পুনরাবৃত্তিতে বাড়ানো হচ্ছে।
মনিকা পুনরায় ইনস্টল করুন - জি সিম্পসন

তুষারপাত প্যাকেজ "কেক" বলার মতো গ্যাভিনের সমাধান বাড়িয়ে দিতে পারে। প্যাকেজটিতে মাল্টিকোরিং করার জন্য প্রয়োগ ফাংশনটির আধিক্য রয়েছে। ফাংশন প্রয়োগের জন্য আপনি sfApply (<প্রয়োগের জন্য সংযুক্তি>) ব্যবহার করবেন। তুষারপাতও নথিবদ্ধ। আমার উল্লেখ করা উচিত যে মাল্টি-কোর প্রসেসরে এটি সম্পাদনের জন্য কোনও অতিরিক্ত সফ্টওয়্যার প্রয়োজন নেই। দেখুন stackoverflow.com/questions/4164960/... একটি sfLapply উদাহরণস্বরূপ।
রোমান Luštrik
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.