2012-12-11 6 views
6

में चल रहे थ्रेड्स मैं एंड्रॉइड/ओपनजीएल में एक गेम लिख रहा हूं और प्रदर्शन को बेहतर बनाने के लिए प्रत्येक को अपने थ्रेड पर चलाकर, अपने गेम अपडेट लॉजिक से अपना ओपनजीएल (रेंडर) तर्क अलग करने का प्रयास कर रहा हूं।एंड्रॉइड: समांतर

URL दिखाई के रूप में मैं नहीं:

मैं प्रत्येक की अपनी धागा पर चल रहा है, फिर भी डी डी एम एस में ट्रेसर के अनुसार, धागे अभी भी क्रमिक रूप से चल रहे हैं पाने में कामयाब रहे (दुनिया मेरे खेल अद्यतन धागा है) छवि विशेषाधिकार हैं: http://img849.imageshack.us/img849/9688/capturegff.png

धागे एक ही समय में कोड निष्पादित नहीं करते हैं। इस प्रकार मैं दुनिया धागा आरंभ:

public class World implements Runnable { 

    Thread thread; 

    public World(...) { 
    ... 
     // Initialise the player/ball objects 
     initialiseObjects(); 

     thread = new Thread(this, "World"); 
     thread.start(); 
} 
} 

मैं दो धागे के बीच अपने ही तुल्यकालन क्रियान्वित किया है। प्रतिकृति द्वीप में इसी तरह के दृष्टिकोण का उपयोग करके, मेरे पास दो रेंडर बफर हैं: अपडेट थ्रेड (आदर्श रूप से) बफर में से एक को लिखते हैं जबकि रेंडर थ्रेड अन्य बफर पढ़ रहा है। बफर में प्रत्येक स्प्राइट को आकर्षित करने के लिए रेंडरर के लिए आवश्यक जानकारी होती है। एक बार जब अपडेट थ्रेड ने अपने बफर को अपडेट करना समाप्त कर दिया है और रेंडरर ने ड्राइंग समाप्त कर लिया है, तो वे बफर स्वैप करते हैं और प्रक्रिया दोहराती है।

(धागा प्रस्तुत करना में इसी तरह के कोड) खेल अद्यतन धागे से कोड में:

currBuffer.write(); 
    player.draw(currBuffer.getNext()); 

    ball.draw(currBuffer.getNext()); 

    if (particleEffect != null) { 
     particleEffect.draw(currBuffer); 
    } 

    currBuffer.finished(); 

    while(otherBuffer.isFinished() == false) { 
     //otherBuffer is finished once the render thread has finished drawing 
    } 

    DrawBuffer tempBuffer = currBuffer; 
    currBuffer = otherBuffer; 
    otherBuffer = tempBuffer; 

    currBuffer.changed(); 
    while(otherBuffer.isChanged() == false) { 
     //otherBuffer is changed once the render thread has also swapped buffered 
    } 

मैं नहीं देख सकते हैं कि इसके बाद के संस्करण कोड, धागे की अनुक्रमिक निष्पादन के लिए ले जा सकता है, हालांकि मैं कभी नहीं किया है इससे पहले बहु-थ्रेडिंग का प्रयास किया गया, इसलिए यह संभव है कि मैं कुछ मौलिक रूप से गलत कर रहा हूं। खेल को तेज करने के मेरे प्रयास ने इसे काफी धीमा और बहुत कम चिकनी बना दिया है। कोई विचार क्यों धागे समानांतर में नहीं चल रहे हैं?

अद्यतन: मुद्दा यह था कि मेरा फोन का प्रोसेसर केवल एक कोर था। मुझे यकीन था कि अविश्वसनीय एस दोहरी कोर था लेकिन हां यह केवल एकल है। मैंने इसे एस 2 पर करने की कोशिश की और यह वास्तव में समानांतर में धागे चला गया।

हालांकि, बाजार में केवल नए फोन ही इसका समर्थन करते हैं तो बहु-थ्रेडिंग का क्या फायदा है? मुझे समझ में नहीं आता कि प्रतिकृति द्वीप ने बहु-थ्रेडिंग को कार्यान्वित करके पुराने, एकल कोर फोन पर बेहतर प्रदर्शन कैसे किया। निश्चित रूप से धागे के बीच सिंक्रनाइज़ करने में अतिरिक्त ओवरहेड का लाभ उठाने के लिए दूसरा कोर नहीं होने पर धीमी कार्यक्षमता होनी चाहिए?

बहु-थ्रेडिंग ने एकल कोर पर धीरे-धीरे प्रदर्शन किया जिससे बफर उत्पन्न करने के कारण ड्रॉ थ्रेड को पास किया गया। दोहरे कोर पर, यह 5-10% तेज था, हालांकि लगभग 500 sprites पर अद्यतन चक्र बफर के कारण फिर से ड्रॉ चक्र से अधिक समय लेता था, इस प्रकार गति लाभ सीमित करता था। स्पष्ट रूप से अनुकूलन के साथ मैं इसे सुधार सकता हूं लेकिन सवाल यह हो जाता है कि एकल कोर प्रोसेसर की कीमत पर बहु-थ्रेडिंग का समर्थन करना उचित है या नहीं। क्या यह निर्धारित करने के लिए एक फोन के प्रोसेसर निर्धारित करना संभव है कि बहु-थ्रेडिंग का उपयोग करें या रनटाइम पर नहीं?

+0

यदि आपके पास केवल एक कोर है और दोनों कार्य CPU-limited हैं, तो वे वास्तव में समानांतर में नहीं चल सकते हैं। इसके अलावा, इन 'लूप्स' के अंदर क्या है? क्या वे वास्तव में खाली लूप हैं? –

+0

धन्यवाद @ डेविड श्वार्टज़ - यह वास्तव में मुद्दा था। मुझे यकीन था कि अविश्वसनीय एस दोहरी कोर था लेकिन हां यह केवल एकल है। मैंने इसे एस 2 पर करने की कोशिश की और यह वास्तव में समानांतर में धागे चला गया। हालांकि, मल्टी-थ्रेडिंग का क्या फायदा है यदि बाजार में केवल नए फोन ही इसका समर्थन करते हैं? मुझे समझ में नहीं आता कि प्रतिकृति द्वीप ने बहु-थ्रेडिंग को कार्यान्वित करके पुराने, एकल कोर फोन पर बेहतर प्रदर्शन कैसे किया। निश्चित रूप से धागे के बीच सिंक्रनाइज़ करने में अतिरिक्त ओवरहेड का लाभ उठाने के लिए दूसरा कोर नहीं होने पर धीमी कार्यक्षमता होनी चाहिए? – awr

+0

यदि कार्य CPU-सीमित नहीं हैं, तो बहु-थ्रेडिंग के लिए बहुत से लाभ हो सकते हैं। यदि एक कार्य आगे बढ़ नहीं सकता है (कहें क्योंकि यह I/O की प्रतीक्षा कर रहा है), दूसरा कर सकता है। हालांकि, अगर केवल एक कोर है, और आपके कार्य सीपीयू-सीमित हैं, तो बहु-थ्रेडिंग मदद नहीं करेगा। –

उत्तर

3

ठीक है, तकनीकी रूप से, 1 सीपीयू एक समय में केवल एक कोड खंड चलाता है। आपके OS scheduler मिलीसेकंड के एक अंश में प्रक्रियाओं/धागे को बदलता है जो आपको एक ही समय में कई प्रक्रियाओं को चलाने का भ्रम देता है।

रनटाइम को सूचित करने का एक तरीका है कि आपका थ्रेड अब के लिए किया गया है Thread.yield पर कॉल कर रहा है। आपके कोड में व्यस्त लूप है जो आपकी स्थिति में मदद नहीं करता है। यह CPU को कुछ भी करने में व्यस्त रहता है।

while(otherBuffer.isFinished() == false) 

आप व्यस्त पाश के बजाय Loks का उपयोग करना चाहिए या आप एक प्रारंभिक प्रदर्शन को बढ़ावा देने के लिए Thread.yield कि जब लूप के अंदर बुला की कोशिश कर सकते हैं। बीटीडब्ल्यू, semaphore पर भी एक नज़र डालें जो कि निर्माता-उपभोक्ता समस्याओं के लिए सबसे आसान समाधान है। यदि आप अपना वर्तमान कोडबेस रखना चाहते हैं, तो आप प्रति बफर लॉक का उपयोग कर सकते हैं।

0

की तरह नीचे

class Threadcalling implements Runnable 
    { 

     @Override 
     public void run() { 
} 
} 

तो जैसे

नीचे
Thread t=new Thread(new Threadcalling()); 
        t.start(); 

आप इस तरह के कई धागा वर्गों बना सकते हैं और समानांतर रूप में यह कॉल कर सकते हैं का उपयोग कर इसे कहते वर्ग के रूप में धागा बनाने के लिए। यह कोई जांच नहीं करेगा। अच्छी तरह से काम करो।