2015-09-20 8 views
9

में सिम के लिए वेक्टर का उपयोग करके मैं एक एल्गोरिदम को सदिश बनाने और सीपीयू के सिमड ऑपरेशंस का लाभ लेने के लिए System.Numerics.Vector (T) का उपयोग करने का प्रयास कर रहा हूं। हालांकि, मेरे मूल कार्यान्वयन से मेरा वेक्टर कार्यान्वयन काफी धीमा था। क्या वेक्टरों का उपयोग करने के लिए कोई चाल है जो दस्तावेज नहीं हो सकते हैं? यहां का विशिष्ट उपयोग डेटा के केबी के एक्सर्स को तेज करने की कोशिश करना है। यूनिवर्सल विंडोज प्लेटफार्म

दुर्भाग्यवश, मैं लगभग सभी दस्तावेज जो इसे प्राप्त कर सकता हूं वह RyuJIT के पूर्व-रिलीज़ संस्करण पर आधारित है, और मुझे नहीं पता कि उस सामग्री का कितना भाग .NET मूल के लिए पोर्टेबल है।

जब मैं एक वेक्टर XOR आपरेशन के दौरान disassembly का निरीक्षण किया, यह पता चलता है:

00007FFB040A9C10 xor   eax,eax 
00007FFB040A9C12 mov   qword ptr [rcx],rax 
00007FFB040A9C15 mov   qword ptr [rcx+8],rax 
00007FFB040A9C19 mov   rax,qword ptr [r8] 
00007FFB040A9C1C xor   rax,qword ptr [rdx] 
00007FFB040A9C1F mov   qword ptr [rcx],rax 
00007FFB040A9C22 mov   rax,qword ptr [r8+8] 
00007FFB040A9C26 xor   rax,qword ptr [rdx+8] 
00007FFB040A9C2A mov   qword ptr [rcx+8],rax 
00007FFB040A9C2E mov   rax,rcx 

ऐसा क्यों है XMM रजिस्टरों और इस के लिए SIMD निर्देश का उपयोग नहीं करता? यह भी अजीब बात यह है कि सिम निर्देश इस कोड के एक संस्करण के लिए जेनरेट किए गए थे जिन्हें मैंने स्पष्ट रूप से वेक्टरिज्ड नहीं किया था, लेकिन नियमित रजिस्ट्रारों और निर्देशों के पक्ष में उन्हें कभी निष्पादित नहीं किया जा रहा था।

मुझे यकीन है कि मैं रिलीज, x64, ऑप्टिमाइज़ कोड सक्षम के साथ चल रहा था। मैंने x86 संकलन के साथ समान व्यवहार देखा। मैं मशीन-स्तरीय सामान पर कुछ हद तक नौसिखिया हूं, इसलिए संभव है कि यहां कुछ ऐसा चल रहा है जिसे मैं ठीक से समझ नहीं पा रहा हूं।

फ्रेमवर्क संस्करण 4.6 है, वेक्टर। IHardwareAccelerated रनटाइम पर गलत है।

अद्यतन: ".NET मूल उपकरण श्रृंखला के साथ संकलित" अपराधी है। इसे सक्षम करने से वेक्टर का कारण बनता है। IHardwareAccelerated == false; इसे अक्षम करने से वेक्टर का कारण बनता है। IHardwareAccelerated == true। मैंने पुष्टि की है कि जब .NET मूल अक्षम किया जाता है, तो कंपाइलर ymm रजिस्टरों का उपयोग करके AVX निर्देशों का उत्पादन कर रहा है। जो सवाल की ओर जाता है ... .NET मूल में सिमड क्यों सक्षम नहीं है? और क्या इसे बदलने का कोई तरीका है?

अद्यतन स्पर्शरेखा: मुझे पता चला कि कारण ऑटो SSE-vectorized सरणी कोड निष्पादित नहीं किया जा रहा था था, क्योंकि संकलक एक निर्देश है कि देखने के लिए देखा है, तो सरणी के शुरू होने से एक कम पते पर था डाला था सरणी के अंतिम तत्वों में से एक की तुलना में, और यदि यह था, तो सामान्य रजिस्टरों का उपयोग करने के लिए। मुझे लगता है कि संकलक में एक बग होना चाहिए, क्योंकि एक सरणी की शुरुआत हमेशा सम्मेलन द्वारा अपने अंतिम तत्वों की तुलना में कम पते पर होना चाहिए। यह प्रत्येक ऑपरेंड सरणी के मेमोरी पतों का परीक्षण करने वाले निर्देशों के एक सेट का हिस्सा था, मुझे लगता है कि वे यह सुनिश्चित करने के लिए नहीं हैं कि वे गैर-ओवरलैपिंग थे। मैं इस के लिए एक Microsoft कनेक्ट बग रिपोर्ट दायर किया है: https://connect.microsoft.com/VisualStudio/feedback/details/1831117

+0

यह फ्रेमवर्क संस्करण क्या है? क्या हार्डवेयर त्वरण 'सत्य' होने की सूचना दी गई है? – usr

+0

फ्रेमवर्क संस्करण 4.6, और IsHardwareAccelerated रिटर्न झूठी। –

+0

'.NET मूल में सिमड क्यों सक्षम नहीं है?' मैं केवल अनुमान लगा सकता हूं: सिम को जेआईटी (जस्ट-इन-टाइम कंपाइलर, जो चीजटाइम आईएल कोड को देशी कोड में बदलती है) द्वारा संभाला जाता है। .NET देशी पूरी तरह से मूल असेंबली (अनुवाद की आवश्यकता के बिना) बनाकर पूरी तरह से जेआईटी को छोड़ देता है। मुझे लगता है कि उन्होंने .NET मूल उपकरण श्रृंखला में सिम समर्थन को लागू नहीं किया है। या तो क्योंकि उनके पास अभी तक समय नहीं था, या क्योंकि .NET देशी का उपयोग उन CPUs पर चलने वाले प्रोग्राम बनाने के लिए किया जा सकता था जिनके पास सिम रजिस्ट्रार नहीं हैं –

उत्तर

9

मैं माइक्रोसॉफ्ट, जो नेट मूल निवासी सवालों और चिंताओं के लिए एक संपर्क पते तैनात संपर्क: https://msdn.microsoft.com/en-us/vstudio/dotnetnative.aspx

मेरा प्रश्न इयान Bearman में भेजा गया था, प्रधान सॉफ्टवेयर इंजीनियरिंग माइक्रोसॉफ्ट कोड जनरेशन और अनुकूलन टेक्नोलॉजीज टीम में प्रबंधक:

वर्तमान में नेट मूल निवासी System.Numerics पुस्तकालय अनुकूलन और डिफ़ॉल्ट लाइब्रेरी कार्यान्वयन पर निर्भर करता है नहीं करता है। यह (पढ़ सकता है: संभवतः) System.Numerics का उपयोग करके लिखित कोड में परिणाम के रूप में नहीं करने के लिए .NET मूल में है क्योंकि यह अन्य सीएलआर कार्यान्वयन के खिलाफ होगा।

हालांकि यह दुर्भाग्यपूर्ण है, .NET मूल ऑटो-वेक्टरराइजेशन का समर्थन करता है जो ऊपर वर्णित सी ++ अनुकूलन का उपयोग करने के साथ आता है। वर्तमान शिपिंग।नेट मूल संकलक एसएसई 2 आईएसए का समर्थन x86 और x64 पर ऑटो-वेक्टरिज़ेशन और एआरएम पर नीयन आईएसए में करता है।

उन्होंने यह भी कहा है कि वे सी से अधिक लाने के लिए ++ सभी वेक्टर निर्देश (AVX, SSE, आदि) और शाखा अनुदेश क्रम पर सेट का पता लगाने के आधार पर उत्पन्न करने की क्षमता संकलक चाहते हैं।

उन्होंने तब सुझाव दिया कि यदि निर्देशों का उपयोग वास्तव में महत्वपूर्ण है, तो घटक को सी ++ में बनाया जा सकता है, जिसमें कंपाइलर इंट्रिनिक्स (और संभावित रूप से यह शाखा क्षमता) तक पहुंच है और फिर शेष सी # अनुप्रयोग में आसानी से इंटरफेस किया जाता है।

छोड़े गए एसएसई 2 निर्देशों के लिए, मुझे इसे एक निर्देशित "ए = ए^बी" को "ए^= बी" के साथ बदलने के लिए सही निर्देशों को संकलित करने के लिए किया जाना था। चूंकि वे समकक्ष अभिव्यक्ति होना चाहिए, ऐसा लगता है कि यह एक बग है, लेकिन सौभाग्य से एक कामकाज के साथ।

+0

बहुत रोचक/उपयोगी जानकारी, फॉलोअप के लिए धन्यवाद! –

+1

वापस आने के लिए धन्यवाद। यह वह नहीं था जिसे मैं ढूंढ रहा था लेकिन कम से कम कोई भी आकर्षक नहीं था। हमारे बाकी के लिए इस पर आगे बढ़ने के लिए कुडो। – EndsOfInvention

संबंधित मुद्दे