गति मैं बहुत लंबे पूर्णांक (कुछ 100,000 दशमलव अंक) के गुणा के लिए अंकगणित पर काम कर रहा हूं। मेरी लाइब्रेरी के हिस्से के रूप में मैं दो लंबी संख्याओं को जोड़ना चाहता हूं।एक्स 64 असेंबलर एडीडी लूप
प्रोफाइलिंग से पता चलता है कि मेरा कोड ऐड() और उप() दिनचर्या में 25% तक चलता है, इसलिए यह महत्वपूर्ण है कि वे जितनी जल्दी हो सके। लेकिन मुझे अभी तक बहुत संभावना नहीं दिख रही है। शायद आप मुझे कुछ मदद, सलाह, अंतर्दृष्टि या विचार दे सकते हैं। मैं उनका परीक्षण करूंगा और आपको वापस ले जाऊंगा।
अब तक मेरी ऐड दिनचर्या कुछ सेटअप करता है और फिर एक 8-बार unrolled पाश का उपयोग करता है:
mov rax, QWORD PTR [rdx+r11*8-64]
mov r10, QWORD PTR [r8+r11*8-64]
adc rax, r10
mov QWORD PTR [rcx+r11*8-64], rax
7 अधिक विभिन्न ऑफसेट के साथ ब्लॉक का पालन करें और फिर इसे लूप।
मैंने पहले स्मृति से मूल्यों को लोड करने का प्रयास किया, लेकिन इससे मदद नहीं मिली। मुझे लगता है कि अच्छा prefetching के कारण है। मैं इंटेल i7-3770 आइवी ब्रिज 4-कोर सीपीयू का उपयोग करता हूं। लेकिन मैं कोड लिखना चाहता हूं जो किसी भी आधुनिक सीपीयू पर अच्छा काम करता है।
संपादित करें: मैंने कुछ समय किया: यह लगभग 2.25 चक्र/शब्द में 1k शब्द जोड़ता है। अगर मैं एडीसी हटा देता हूं, तो केवल एमओवी ही रहती है, फिर भी इसमें लगभग 1.95 चक्र/शब्द लगते हैं। तो मुख्य बाधा स्मृति पहुंच प्रतीत होता है। एक पुस्तकालय memcpy()
लगभग 0.65 चक्र/शब्द में काम करता है, लेकिन इसमें केवल एक इनपुट है, दो नहीं। फिर भी, एसएसई रजिस्टरों के उपयोग के कारण यह बहुत तेज है, मुझे लगता है।
कुछ सवाल:
- इसका इस्तेमाल करने के लिए उपयोगी है "लोड, लोड,, स्टोर जोड़ें" संरचना या एक "लोड, जोड़ने करने वाली स्मृति" मदद मिलेगी? अब तक मेरे परीक्षणों ने कोई लाभ नहीं दिखाया है।
- सामान्य रूप से, एसएसई (2,3,4) से अपेक्षित होने की कोई मदद नहीं है?
- क्या पता (स्केल किए गए इंडेक्स प्लस बेस प्लस ऑफसेट) को बुरी तरह प्रभावित किया जाता है? मैं इसके बजाय
ADD r11, 8
का उपयोग कर सकता था। - लूप अनोलिंग के बारे में क्या? मैंने पढ़ा है सैंडी ब्रिज आर्किटेक्चर (एग्नेर फॉग http://www.agner.org/optimize/) के लिए अनोलिंग खराब था। क्या इसे प्राथमिकता दी जानी चाहिए या इससे बचा जा सकता है?
- (संपादित करें) क्या मैं एसएसई रजिस्टरों का उपयोग स्मृति से बड़े हिस्सों में लोड और स्टोर करने के लिए कर सकता हूं और सामान्य प्रयोजन रजिस्टरों और एसएसई रजिस्टरों के साथ कुशलता से शब्दों का आदान-प्रदान कर सकता हूं?
मैं किसी भी टिप्पणी की अत्यधिक सराहना करता हूं।
बहुत बड़ी संख्या में गुणा करने के लिए सबसे तेज़ तरीका (मुझे पता है) एक तेज़ चौकोर परिवर्तन है http://en.wikipedia.org/wiki/Multiplication_algorithm मैंने कभी भी एंबलर में अपने तर्क को लागू करने की कोशिश नहीं की। तत्काल प्राइम 95 में x86 असेंबली तर्क में एक तेज़ चौकोर परिवर्तन होता है और आप इसे –
से (स्वतंत्र रूप से) ले सकते हैं धन्यवाद, मुझे इसके बारे में पता है। अभी मैं केवल तेज़ जोड़ना चाहता हूं। – cxxl
आप जीएमपी स्रोतों में देख सकते हैं। – zch