2010-01-02 35 views
16

मैंने पावरपीसी पर एक अच्छी मेमोरी रणनीति की खोज में कई प्रतिलिपि कार्य लिखे हैं। कैश संकेतों (डीसीबी *) के साथ Altivec या fp रजिस्टरों का उपयोग बड़े डेटा के लिए एक साधारण बाइट कॉपी लूप पर प्रदर्शन को दोगुना करता है। शुरुआत में उस से प्रसन्नता हुई, मैंने यह देखने के लिए एक नियमित memcpy में फेंक दिया कि यह कैसे तुलना की गई ... मेरे सर्वोत्तम से 10x तेज! मुझे memcpy को फिर से लिखने का कोई इरादा नहीं है, लेकिन मुझे इससे सीखने की उम्मीद है और कई सरल छवि फ़िल्टरों को तेज़ करने की उम्मीद है जो अपना अधिकांश समय स्मृति में और स्मृति से आगे बढ़ते हैं।ऐप्पल की पावरपीसी इतनी तेजी से क्या बनाता है?

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

 
prefetch 
    dcbt future 
    dcbt distant future 
load stuff 
    lvx image 
    lvx image + 16 
    lvx image + 32 
    lvx image + 48 
    image += 64 
prepare to store 
    dcbz filtered 
    dcbz filtered + 32 
store stuff 
    stvxl filtered 
    stvxl filtered + 16 
    stvxl filtered + 32 
    stvxl filtered + 48 
    filtered += 64 
repeat 

क्या किसी के पास कुछ विचार हैं कि क्यों इसी तरह के कोड में नाटकीय प्रदर्शन अंतर है? मुझे असली छवि फ़िल्टरों को मारना अच्छा लगेगा जो भी गुप्त सॉस memcpy उपयोग कर रहा है!

अतिरिक्त जानकारी: सभी डेटा वेक्टर गठबंधन है। मैं छवि की फ़िल्टर की गई प्रतियां बना रहा हूं, मूल को प्रतिस्थापित नहीं कर रहा हूं। कोड पावरपीसी जी 4, जी 5, और सेल पीपीयू पर चलता है। सेल एसपीयू संस्करण पहले से ही बहुत तेज है।

उत्तर

0

शायद यह सीपीयू कैशिंग के कारण है। CacheGrind चलाने की कोशिश करें:

कैशग्रींड एक कैश प्रोफाइलर है। यह आपके सीपीयू और में आई 1, डी 1 और एल 2 कैश का विस्तृत अनुकरण करता है, इसलिए आपके कोड में कैश मिस के स्रोतों को सटीक रूप से इंगित कर सकते हैं। यह कैश मिस की संख्या की पहचान करता है, मेमोरी संदर्भ और निर्देश प्रति कोड, 0 -प्रति-फ़ंक्शन, प्रति-मॉड्यूल और संपूर्ण-कार्यक्रम सारांश के साथ निष्पादित किया गया है। यह किसी भी भाषा में लिखे गए कार्यक्रमों के साथ उपयोगी है। कैश्रिंड सामान्य से धीमे 20--100x के बारे में प्रोग्राम चलाता है।

+0

कैशग्रिंड बिल्कुल पीपीसी/डार्विन पर काम नहीं करता है। –

+0

@ निक, क्या आप वाकई हैं? http://en.wikipedia.org/wiki/Valgrind "संस्करण 3.4.0 के रूप में, वालग्रिंड x86, x86-64 और PowerPC पर लिनक्स का समर्थन करता है" –

+1

@Andreas: यह * linux * पर काम करता है, लेकिन निश्चित रूप से डार्विन नहीं। केवल समर्थित (और मुश्किल) डार्विन x86 है। –

2

मुझे नहीं पता कि आप क्या कर रहे हैं, क्योंकि मैं आपका कोड नहीं देख सकता, लेकिन ऐप्पल का गुप्त सॉस here है।

+0

मैं शार्क में डिस्सेप्लर देख सकता था, इसलिए पता करें कि वे कॉपी लूप में क्या कर रहे हैं। बस सोच रहा है कि उस लूप से पहले क्या है जो इसे ओवरड्राइव में लात मारता है। उस कोड को मदद करनी चाहिए, इसलिए लिंक के लिए धन्यवाद! –

+0

@ अविश्वसनीय गाय: हाँ, मैं बस उम्मीद कर रहा था कि थोड़ा और संदर्भ (और टिप्पणियां) प्रदान करेगा जो अंतर्दृष्टिपूर्ण हो सकता है। –

+0

जी 4 और इसके 32-बाइट कैकेलाइन के लिए, प्रश्न में कुछ कोड जोड़ा गया। –

7

शार्क विश्लेषण से पता चलता है कि उनके आंतरिक पाश डीसीबीटी का उपयोग प्रीफेच करने के लिए करता है, 4 वेक्टर पढ़ने के साथ, फिर 4 वेक्टर लिखते हैं। मेरे सबसे अच्छे समारोह में सुधार करने के बाद भी यात्रा प्रति 64 बाइट्स ढोना को

मैं स्पष्ट करते हुए कहा जा सकता है, लेकिन जब से तुम सब पर अपने प्रश्न में निम्नलिखित का उल्लेख नहीं है, यह इसके उनका कहना है लायक हो सकता है:

मैं शर्त लगाता हूं कि ऐप्पल की 4 वैक्टरों की पसंद पढ़ने के बाद 4 वेक्टर लिखने के बाद G5's pipeline and its management of out-of-order instruction execution in "dispatch groups" के साथ बहुत कुछ करना है क्योंकि इसमें जादुई 64-बाइट सही लाइन आकार है। क्या आपने निक बस्टिन के लिंक किए गए bcopy.s में लाइन स्किप को देखा था? इसका मतलब यह है कि डेवलपर ने सोचा कि जी 5 द्वारा निर्देश धारा का उपभोग कैसे किया जाएगा। यदि आप एक ही प्रदर्शन को पुन: पेश करना चाहते हैं, तो एक समय में डेटा 64 बाइट पढ़ने के लिए पर्याप्त नहीं है, आपको यह सुनिश्चित करना होगा कि आपके निर्देश समूह अच्छी तरह से भरे हुए हैं (मूल रूप से, मुझे याद है कि निर्देशों को पांच स्वतंत्र लोगों तक समूहीकृत किया जा सकता है, पहले चार गैर-कूद निर्देश हैं और पांचवें केवल कूदने की अनुमति है। विवरण अधिक जटिल हैं)।

संपादित करें: यदि आप भी एक ही पृष्ठ पर निम्नलिखित पैराग्राफ द्वारा रुचि हो सकती है:

dcbz अनुदेश अभी भी शून्य जी -4 और G3 के अनुसार स्मृति के 32 बाइट क्षेत्रों गठबंधन। हालांकि, चूंकि यह जी 5 पर पूर्ण कैशलाइन नहीं है, इसलिए इसमें ऐसे प्रदर्शन लाभ नहीं होंगे जिनकी आप उम्मीद कर रहे थे। जी 5 के लिए हाल ही में एक डीसीबीजीएल निर्देश पेश किया गया है जो एक पूर्ण 128-बाइट कैशलाइन शून्य है।

+0

पर नहीं था, मैंने सोचा नहीं था प्रेषण समूह। जी 5 के पूरे "निर्देश सूप" ने हमेशा मुझे परेशान किया है, और मैं सेल के साथ काम करना पसंद करता हूं, क्योंकि इसका निष्पादन मॉडल मेरे सिर में फिट बैठता है। संपादन के लिए, कोड पहले से ही बड़े cachelines के लिए अलग है। –

0

अभी भी कोई जवाब नहीं है, लेकिन क्या आपने सत्यापित किया है कि memcpy वास्तव में डेटा को स्थानांतरित कर रहा है? हो सकता है कि इसे सिर्फ कॉपी-ऑन-राइट रीमेप किया गया हो। आप अभी भी शार्क में आंतरिक memcpy पाश देखेंगे क्योंकि पहले और अंतिम पृष्ठों के हिस्से वास्तव में कॉपी किए गए हैं।

0

जैसा कि एक और उत्तर में बताया गया है, "डीसीबीज़", जैसा कि ऐप्पल द्वारा जी 5 पर परिभाषित किया गया है, केवल 32-बाइट्स पर काम करता है, इसलिए आप इस निर्देश के साथ एक जी 5 पर प्रदर्शन खो देंगे जिसमें 128 बाइट कैनलाइन हैं। गंतव्य कैशलाइन को स्मृति से प्राप्त होने से रोकने के लिए आपको "dcbzl" का उपयोग करने की आवश्यकता है (और प्रभावी रूप से आपकी उपयोगी पठन मेमोरी बैंडविड्थ को आधा से कम करना)।

+1

और न भूलें - आपको केवल 128 बाइट लाइन प्रति 1 "dcbzl" का उपयोग करना चाहिए। ऐसा लगता है कि आपका कोड प्रत्येक 32 बाइट्स "डीसीबीजे" कर रहा है। – JanePhanie