इस तरह का प्रश्न आवर्ती है और स्टैक ओवरफ्लो पर एक बार "MATLAB अत्यधिक अनुकूलित पुस्तकालयों का उपयोग करता है" या "MATLAB MKL का उपयोग करता है" की तुलना में अधिक स्पष्ट रूप से उत्तर दिया जाना चाहिए।
इतिहास:
मैट्रिक्स गुणन (मैट्रिक्स-वेक्टर, वेक्टर-वेक्टर गुणन और मैट्रिक्स के कई डिकम्पोज़िशन के साथ) रैखिक बीजगणित में सबसे महत्वपूर्ण समस्याएं हैं (हैं)। इंजीनियर शुरुआती दिनों से ही कंप्यूटर के साथ इन समस्याओं को हल कर रहे हैं।
मैं इतिहास का विशेषज्ञ नहीं हूं, लेकिन जाहिरा तौर पर फिर से, हर कोई बस अपने फोरट्रान संस्करण को सरल छोरों के साथ फिर से लिखता है। कुछ मानकीकरण तब "कर्नेल" (मूल दिनचर्या) की पहचान के साथ आया, जिसे हल करने के लिए सबसे अधिक रैखिक बीजगणित की समस्याओं की आवश्यकता थी। इन बुनियादी ऑपरेशनों को तब एक विनिर्देशन में मानकीकृत किया गया था: बेसिक रैखिक बीजगणित उपप्रोग्राम (BLAS)। इंजीनियर तब अपने कोड में इन मानक, अच्छी तरह से परीक्षण किए गए BLAS रूटीन को कॉल कर सकते थे, जिससे उनका काम बहुत आसान हो गया।
BLAS:
स्तर 1 (प्रथम संस्करण जो स्केलर-वेक्टर और वेक्टर-वेक्टर ऑपरेशन) से लेवल 2 (वेक्टर-मैट्रिक्स ऑपरेशन) से लेवल 3 (मैट्रिक्स-मैट्रिक्स ऑपरेशन) तक विकसित हुआ, और अधिक से अधिक "गुठली" प्रदान किया ताकि मानकीकृत हो सके और मौलिक रैखिक बीजगणित संचालन के अधिक। मूल फोरट्रान 77 कार्यान्वयन अभी भी नेटलिब की वेबसाइट पर उपलब्ध हैं ।
बेहतर प्रदर्शन की ओर:
इसलिए वर्षों में (विशेष रूप से बीएलएएस स्तर 1 और स्तर 2 रिलीज: शुरुआती 80 के दशक के बीच), हार्डवेयर बदल गया, वेक्टर ऑपरेशन और कैश पदानुक्रम के आगमन के साथ। इन प्रस्तावों ने बीएलएएस उप-क्षेत्रों के प्रदर्शन को काफी हद तक बढ़ाना संभव बना दिया। विभिन्न विक्रेताओं ने तब BLAS दिनचर्या के अपने कार्यान्वयन के साथ आए जो अधिक से अधिक कुशल थे।
मुझे सभी ऐतिहासिक कार्यान्वयनों का पता नहीं है (मैं तब पैदा नहीं हुआ था या बच्चा वापस नहीं आया था), लेकिन 2000 के दशक की शुरुआत में दो सबसे उल्लेखनीय व्यक्ति निकले: इंटेल एमकेएल और गोटोब्लास। आपका Matlab Intel MKL का उपयोग करता है, जो कि एक बहुत अच्छा, अनुकूलित BLAS है, और यह आपके द्वारा देखे गए महान प्रदर्शन की व्याख्या करता है।
मैट्रिक्स गुणन पर तकनीकी विवरण:
तो क्यों Matlab (MKL) इतनी तेजी से dgemm
(डबल-सटीक सामान्य मैट्रिक्स-मैट्रिक्स गुणन) है? सरल शब्दों में: क्योंकि यह डेटा के वेक्टरकरण और अच्छे कैशिंग का उपयोग करता है। अधिक जटिल शब्दों में: जोनाथन मूर द्वारा प्रदान किया गया लेख देखें ।
मूल रूप से, जब आप अपने द्वारा प्रदान किए गए C ++ कोड में अपना गुणा करते हैं, तो आप बिल्कुल भी कैश-फ्रेंडली नहीं होते हैं। चूंकि मुझे संदेह है कि आपने पंक्ति सरणियों के लिए व्यूअर का एक सरणी बनाया है, इसलिए आपके आंतरिक लूप में "matice2" के k-th कॉलम तक आपकी पहुंच matice2[m][k]
बहुत धीमी है। दरअसल, जब आप पहुंचते हैं, तो आपको matice2[0][k]
अपने मैट्रिक्स के सरणी 0 का k-th तत्व मिलना चाहिए। फिर अगले पुनरावृत्ति में, आपको एक्सेस करना होगा matice2[1][k]
, जो कि किसी अन्य सरणी का k-th तत्व है (सरणी 1)। फिर अगले पुनरावृत्ति में आप अभी तक एक और सरणी का उपयोग करते हैं, और इसी तरह ... चूंकि पूरी मैट्रिक्स matice2
उच्चतम कैश में फिट नहीं हो सकती है (यह 8*1024*1024
बाइट्स बड़ी है), प्रोग्राम को मुख्य मेमोरी से वांछित तत्व प्राप्त करना होगा, बहुत सारा खोना। समय।
यदि आपने केवल मैट्रिक्स ट्रांसपोज़ किया है, ताकि एक्सेस सन्निहित स्मृति पतों में हो, तो आपका कोड पहले से बहुत तेज़ी से चलेगा क्योंकि अब कंपाइलर कैश में पूरी पंक्तियों को एक ही समय में लोड कर सकता है। बस इस संशोधित संस्करण का प्रयास करें:
timer.start();
float temp = 0;
//transpose matice2
for (int p = 0; p < rozmer; p++)
{
for (int q = 0; q < rozmer; q++)
{
tempmat[p][q] = matice2[q][p];
}
}
for(int j = 0; j < rozmer; j++)
{
for (int k = 0; k < rozmer; k++)
{
temp = 0;
for (int m = 0; m < rozmer; m++)
{
temp = temp + matice1[j][m] * tempmat[k][m];
}
matice3[j][k] = temp;
}
}
timer.stop();
तो आप देख सकते हैं कि कैसे सिर्फ कैश इलाके ने आपके कोड के प्रदर्शन को काफी हद तक बढ़ा दिया है। अब वास्तविक dgemm
कार्यान्वयन बहुत व्यापक स्तर तक शोषण करते हैं: वे TLB के आकार द्वारा परिभाषित मैट्रिक्स के ब्लॉकों पर गुणा करते हैं (अनुवाद लुकसाइड बफर, लंबी कहानी संक्षेप: क्या प्रभावी ढंग से कैश किया जा सकता है), ताकि वे प्रोसेसर को स्ट्रीम करें वास्तव में यह जितना डेटा प्रोसेस कर सकता है। दूसरा पहलू वैश्वीकरण है, वे इष्टतम निर्देश थ्रूपुट के लिए प्रोसेसर के सदिश निर्देशों का उपयोग करते हैं, जो आप वास्तव में अपने क्रॉस-प्लेटफॉर्म सी ++ कोड से नहीं कर सकते हैं।
अंत में, लोगों का दावा है कि स्ट्रैसेन या कोपरसमिथ-विनोग्राद एल्गोरिथ्म के कारण गलत हैं, ये दोनों एल्गोरिदम व्यवहार में लागू नहीं हैं, क्योंकि ऊपर वर्णित हार्डवेयर विचारों के कारण।