पर सी में बहु-थ्रेडिंग की प्रोफाइलिंग पर विचारों की आवश्यकता है मेरा एप्लिकेशन परिदृश्य इस तरह है: मैं प्रदर्शन लाभ का मूल्यांकन करना चाहता हूं जो डेटा की मात्रा को संसाधित करने के लिए क्वाड-कोर मशीन पर प्राप्त कर सकता है। मेरे पास निम्नलिखित दो कॉन्फ़िगरेशन हैं:लिनक्स
i) 1-प्रक्रिया: 1 एम .. 1 जी से किसी भी थ्रेडिंग और प्रक्रिया डेटा के बिना एक प्रोग्राम, जबकि सिस्टम को अपने 4-कोर के केवल एक कोर को चलाने के लिए माना जाता था।
ii) 4-धागे-प्रक्रिया: 4-थ्रेड्स वाला एक प्रोग्राम (एक ही ऑपरेशन करने वाले सभी थ्रेड) लेकिन इनपुट डेटा का 25% प्रोसेसिंग।
4-थ्रेड बनाने के लिए मेरे प्रोग्राम में, मैंने pthread के डिफ़ॉल्ट विकल्प (यानी, किसी विशिष्ट pthread_attr_t के बिना) का उपयोग किया। मेरा मानना है कि 1-प्रोसेस कॉन्फ़िगरेशन की तुलना में 4-थ्रेड कॉन्फ़िगरेशन का प्रदर्शन लाभ 400% (या कहीं 350% और 400% के बीच) होना चाहिए।
timer_start(&threadCreationTimer);
pthread_create(&thread0, NULL, fun0, NULL);
pthread_create(&thread1, NULL, fun1, NULL);
pthread_create(&thread2, NULL, fun2, NULL);
pthread_create(&thread3, NULL, fun3, NULL);
threadCreationTime = timer_stop(&threadCreationTimer);
pthread_join(&thread0, NULL);
pthread_join(&thread1, NULL);
pthread_join(&thread2, NULL);
pthread_join(&thread3, NULL);
इनपुट डेटा का आकार भी प्रत्येक थ्रेड की स्मृति आवश्यकता में वृद्धि हो सकती है में वृद्धि के बाद से, तो सभी डेटा लोड हो रहा:
मैं समय सिर्फ इस नीचे की तरह धागे के निर्माण में खर्च प्रोफाइल अग्रिम में निश्चित रूप से एक व्यावहारिक विकल्प नहीं है। इसलिए, प्रत्येक धागे की स्मृति आवश्यकता को बढ़ाने के लिए सुनिश्चित करने के लिए, प्रत्येक धागा छोटे हिस्सों में डेटा पढ़ता है, इसे संसाधित करता है और अगली खंड प्रक्रिया को पढ़ता है और इसी तरह। इसलिए, मेरी कार्यों धागे द्वारा चलाए का कोड की संरचना इस तरह है:
timer_start(&threadTimer[i]);
while(!dataFinished[i])
{
threadTime[i] += timer_stop(&threadTimer[i]);
data_source();
timer_start(&threadTimer[i]);
process();
}
threadTime[i] += timer_stop(&threadTimer[i]);
चर dataFinished[i]
प्रक्रिया द्वारा true
चिह्नित है जब यह प्राप्त है और इस प्रक्रिया में सभी आवश्यक डेटा।
execTime4Thread = max(threadTime[0], threadTime[1], threadTime[2], threadTime[3]) + threadCreationTime
: Process()
जानता है जब कि :-) क्या करना
मुख्य कार्य में, मैं समय नीचे के रूप में 4-पिरोया विन्यास द्वारा उठाए गए की गणना कर रहा हूँ।
और प्रदर्शन लाभ बस
gain = execTime1process/execTime4Thread * 100
जारी करके की जाती है: 4M करने के लिए 1M भर में छोटे डेटा आकार पर , प्रदर्शन लाभ आम तौर पर अच्छा है (350% से 400% के बीच)। हालांकि, प्रदर्शन लाभ की प्रवृत्ति इनपुट आकार में वृद्धि के साथ तेजी से घट रही है। यह 50 एम या उससे अधिक तक के कुछ डेटा आकार तक घटता रहता है, और फिर 200% के आसपास स्थिर हो जाता है। एक बार यह उस बिंदु तक पहुंचने के बाद, यह 1 जीबी डेटा के लिए लगभग स्थिर रहता है।
मेरा प्रश्न यह है कि कोई भी इस व्यवहार का मुख्य तर्क सुझा सकता है (यानी, शुरुआत में प्रदर्शन ड्रॉप और बाद में स्थिर रहें)?
और सुझावों को कैसे ठीक किया जाए?
आपकी जानकारी के लिए, मैंने प्रत्येक थ्रेड के लिए क्या हो रहा है यह देखने के लिए threadCreationTime
और threadTime
के व्यवहार की भी जांच की। डेटा के 1 एम के लिए इन चर के मान छोटे होते हैं और डेटा आकार में वृद्धि के साथ इन दोनों चर दोनों तेजी से बढ़ते हैं (लेकिन threadCreationTime
डेटा आकार और threadTime
पर ध्यान दिए बिना डेटा के संसाधित होने की दर से बढ़ना चाहिए)।50 एम तक बढ़ने के बाद या threadCreationTime
स्थिर हो जाता है और threadTime
(जैसे प्रदर्शन ड्रॉप स्थिर हो जाता है) और threadCreationTime
संसाधित होने के लिए डेटा में वृद्धि के अनुरूप निरंतर दर पर बढ़ते रहते हैं (जिसे समझा जा सकता है)।
क्या आपको लगता है कि प्रत्येक थ्रेड के स्टैक आकार को बढ़ाने, प्रक्रिया प्राथमिकता सामग्री या अन्य पैरामीटर के कस्टम मान शेड्यूलर के प्रकार (pthread_attr_init
का उपयोग करके) मदद कर सकते हैं?
पीएस: रूट के साथ लिनक्स के असफल सुरक्षित मोड के तहत प्रोग्राम चलाने के दौरान परिणाम प्राप्त किए जाते हैं (यानी, न्यूनतम ओएस जीयूआई और नेटवर्किंग सामान के बिना चल रहा है)।
आपके सीपीयू का मॉडल क्या है? – Tudor
धागे के बीच कैश का सबसे अधिक संभावना पार प्रदूषण। क्या आपने डेटा के हिस्सों के आकार को बदलने की कोशिश की है? आपको अपने माप में डेटा लोडिंग भी शामिल करनी चाहिए क्योंकि यह एक बाधा हो सकती है, यानी 2 कोर आपकी मेमोरी बस को संतृप्त कर सकते हैं। (इसके अलावा, यदि आप इसे पहले से नहीं कर रहे हैं, तो आपको अपने टाइमर को विभिन्न कैश-लाइनों पर रखना चाहिए।) – Mats
@ मैट्स: प्रोसेसर इंटेल (आर) कोर (टीएम) 2 क्वाड सीपीयू Q9950 @ 2.83GHz है। नहीं, मैंने डेटा खंड के आकार की पुष्टि नहीं की है। ठीक है, मैं डेटा खंड के आकार को बदलने की कोशिश करूंगा। हालांकि, मुझे समझ में नहीं आया कि कैश-लाइनों से आपका क्या मतलब है। टाइमर को कैश में कैसे रखा जाए? – Junaid