2010-07-12 5 views
15

मुझे समझ में नहीं आता कि सी #/.NET (और यहां तक ​​कि जावा) में मैट्रिक्स गुणा को इतना धीमा कर देता है।.NET में मैट्रिक्स गुणा क्यों धीमा है?

इस बेंचमार्क ( source) पर एक नज़र डालें: एक अद्यतन बेंचमार्क खोजने का प्रयास कर रहा है।

Java vs C# vs C++ breakdown http://img411.imageshack.us/img411/9324/perf.gif

सी # के पूर्णांक और डबल प्रदर्शन लानत सी ++ के करीब MSVC साथ ++ संकलित है। डबल-फास्ट के रूप में 87% और 32-बिट पूर्णांक के लिए तेज़ 99%। बहुत अच्छा अच्छा, मैं कहूंगा। लेकिन फिर मैट्रिक्स गुणा देखें। अंतराल सी # के रूप में तेजी से 1 9% तक बढ़ता है। यह एक बहुत बड़ी विसंगति है जिसे मैं समझ नहीं पा रहा हूं। मैट्रिक्स गुणा सरल गणित का एक गुच्छा है। यह कितना धीमा हो रहा है? क्या यह मोटे तौर पर तेज़ फ्लोटिंग पॉइंट या पूर्णांक ऑपरेशंस की समतुल्य संख्या के रूप में नहीं होना चाहिए?

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

Matrix multiplication comparison http://img237.imageshack.us/img237/2788/resultse.png

यहाँ क्या हो रहा है?

संपादित करें: करीब देखकर, मैंने दूसरे ग्राफ को गलत तरीके से पढ़ा। सी # बहुत करीब आता है। क्या पहला बेंचमार्क बस कुछ गलत कर रहा है? क्षमा करें, मुझे पहले बेंचमार्क पर संस्करण संख्या याद आई। मैंने इसे "सी # रैखिक बीजगणित धीमा" के लिए एक आसान संदर्भ के रूप में पकड़ लिया है जिसे मैंने हमेशा सुना है। मैं एक और खोजने की कोशिश करूंगा।

+2

सी # संस्करण + विकल्प: नेट फ्रेमवर्क 1.1.4322 उह ... क्या कोई नया संस्करण नहीं है? – GalacticJello

+5

* बैठता है और यह देखने के लिए इंतजार कर रहा है कि जोन्सकेट को इस मामले पर क्या कहना है * :-) – WestDiscGolf

+0

परीक्षण वीएस 2003 के साथ किया गया था। (सी ++ संस्करण भी ध्यान दें।) इसलिए .NET का प्राचीन संस्करण। – cHao

उत्तर

13

इस तरह की बड़ी matrices के साथ, सीपीयू कैश सीमित कारक बन जाता है। हाइपर-महत्वपूर्ण क्या है मैट्रिक्स कैसे संग्रहीत किया जाता है। और बेंचमार्क कोड सेब और संतरे की तुलना कर रहा है। सी ++ कोड जाग्रत सरणी का उपयोग करता है, सी # कोड द्वि-आयामी सरणी का उपयोग करता है।

सी # कोड को जॉग किए गए सरणी का उपयोग करने के साथ-साथ इसकी गति को दोगुना करने के लिए रिवाइट करना। सरणी इंडेक्स सीमा जांच से बचने के लिए मैट्रिक्स गुणा कोड को पुनर्निर्मित करना व्यर्थ लग रहा था, कोई भी वास्तविक समस्याओं के लिए इस तरह का कोड उपयोग नहीं करेगा।

+0

धन्यवाद, जो चीज़ों को साफ़ करता है। तो मैं हमेशा क्यों सुनता हूं (अन्य कारणों से) "एक्सएनए धीमा है क्योंकि सी # में मैट्रिक्स गुणा धीमा है"? क्या यह सच नहीं है? –

+1

मुझे पता नहीं, यह एक अविश्वसनीय दावा है जहां से मैं बैठता हूं। क्या एक्सएनए प्रोग्रामर अक्सर अपना खुद का मैट्रिक्स गुणा कोड लिखते हैं? जब गति की बात आती है तो सी/सी ++ कोड असंगत होता है और जब आप इसे उड़ाते हैं तो आप अपने कानों से बाहर निकलने के लिए छोड़ देते हैं। यदि सी # में किसी विशेष एल्गोरिदम के साथ गति समस्या है तो आपके पास हमेशा गिरने के लिए सी/सी ++ है। –

+1

नहीं, वे एक्सएनए द्वारा प्रदान की गई लाइब्रेरी का उपयोग करते हैं। –

7

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

इस question को गहराई से विश्लेषण के लिए देखें कि बहुआयामी सरणी जंजीर सरणी से धीमी क्यों हैं।

सरणी सीमाओं की जांच के बारे में अधिक जानकारी के लिए यह blog देखें। आलेख विशेष रूप से मैट्रिक्स गुणा के लिए बहुआयामी सरणी का उपयोग करने के खिलाफ चेतावनी देता है।

3

यहाँ एक अद्यतन बेंचमार्क मैट्रिक्स multiplcation के साथ काम कर रहा है (और नए कार्य समानांतर लाइब्रेरी का उपयोग कुछ मानक):

Parallel Matrix Multiplication with the Task Parallel Library (TPL)

लेख विभिन्न तरीकों में चला जाता है, और यही कारण है बहुआयामी सरणियों एक गरीब पसंद कर रहे हैं:

मैट्रिक्स गुणा करने के लिए सबसे आसान तरीका है एक .NET मैं के साथ बहुआयामी सरणी के साथ है, J, k छोरों में आदेश । समस्याएं दो गुना हैं। सबसे पहले, i, j.k आदेश एक व्यस्त फैशन में मेमोरी एक्सेस करता है जिससे विभिन्न स्थानों में डेटा हो जाता है। दूसरा, यह बहुआयामी सरणी का उपयोग कर रहा है। हां, .NET बहुआयामी सरणी सुविधाजनक है, लेकिन यह बहुत धीमी है।

10

विचार की उत्पत्ति की व्याख्या करने के लिए कि XNA मैट्रिक्स आपरेशन धीमी गति से कर रहे हैं:

सबसे पहले वहाँ शुरुआत स्तर के पकड़ लिया: XNA Matrix वर्ग के operator* कई प्रतियों कर देगा। यह समतुल्य सी ++ कोड से अपेक्षा की जा सकती है जितनी धीमी है।

(बेशक, अगर आप Matrix.Multiply() उपयोग करते हैं, तो आप संदर्भ द्वारा पारित कर सकते हैं।)

दूसरा कारण यह है कि NET कम्पैक्ट फ्रेमवर्क Xbox 360 पर XNA द्वारा प्रयोग किया जाता वीएमएक्स हार्डवेयर के लिए उपयोग नहीं होता है (सिम) जो मूल, सी ++ गेम के लिए उपलब्ध है।

यही कारण है कि आप सुनते रहते हैं कि कम से कम धीमा है। जैसा कि आप पोस्ट किए गए बेंचमार्क से देख सकते हैं - यह वास्तव में "धीमा" नहीं है, जब आप सेब से सेब की तुलना करते हैं।

+1

यह समझ में आता है। हो सकता है कि कुछ गलतफहमी ऑपरेटर का उपयोग करने से आती है। –