मैट्रिक्स गुणन में MATLAB इतना तेज़ क्यों है?


190

मैं CUDA, C ++, C #, Java के साथ कुछ मानक बना रहा हूं, और सत्यापन और मैट्रिक्स पीढ़ी के लिए MATLAB का उपयोग कर रहा हूं। जब मैं MATLAB के साथ मैट्रिक्स गुणन करता हूं, 2048x2048और यहां तक ​​कि बड़े मैट्रिक्स भी लगभग तुरंत गुणा हो जाते हैं।

             1024x1024   2048x2048   4096x4096
             ---------   ---------   ---------
CUDA C (ms)      43.11      391.05     3407.99
C++ (ms)       6137.10    64369.29   551390.93
C# (ms)       10509.00   300684.00  2527250.00
Java (ms)      9149.90    92562.28   838357.94
MATLAB (ms)      75.01      423.10     3133.90

केवल CUDA प्रतिस्पर्धी है, लेकिन मुझे लगा कि कम से कम C ++ कुछ करीब होगा और 60 गुना धीमा नहीं होगा। मुझे यह भी नहीं पता कि C # परिणामों के बारे में क्या सोचना है। एल्गोरिथ्म सी ++ और जावा के समान ही है, लेकिन इसमें से एक विशाल छलांग 2048है 1024

MATLAB मैट्रिक्स गुणन इतनी तेजी से कैसे कर रहा है?

C ++ कोड:

float temp = 0;
timer.start();
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] * matice2[m][k];
        }
        matice3[j][k] = temp;
    }
}
timer.stop();

14
संभवतः इसका एक सवाल है कि आप किस एल्गोरिथ्म का उपयोग करते हैं।
राबर्ट जे।

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

27
लैपैक और वेक्टराइजेशन। mathworks.com/company/newsletters/news_notes/clevescorner/…
जेम्स

10
मुझे वास्तव में लगता है कि यह पोस्ट वास्तव में दिलचस्प है लेकिन मैं वास्तव में अधिक उपयुक्त बेंचमार्क देखना चाहूंगा। उदाहरण के लिए, मुझे लगता है कि Matlab R2011a अपने आप मल्टीथ्रेडिंग का उपयोग कर रहा है और मैट्रिक्स गुणन इंटेल के mkl / blas लाइब्रेरी का उपयोग करके कार्यान्वित किया जाता है। इस प्रकार, मुझे लगता है कि c ++ तेज है अगर कोई मैट्रिक्स कॉल करने के लिए mkl कॉल का उपयोग करता है। सवाल तब होगा कि मतलाब का उपरि क्या है। मुझे पता है कि यह मैट्रिक्स गुणा के अतिरिक्त विवरणों पर निर्भर करता है, लेकिन उपरोक्त संख्याएं अभी बहुत ही व्यर्थ हैं।
लुकास

1
आप बड़े वर्ग मैट्रिक्स गुणन के लिए रनिंग टाइम O (n ^ 2.81) के "स्ट्रैसेन एल्गोरिथ्म" का उपयोग कर सकते हैं जो कि ओ (एन ^ 3) में चलने वाले देशी गुणन की तुलना में लगभग 10 गुना तेज है। कोड निष्पादन के लिए SSE / AVX आपको लगभग 8-20x तेज़ी से प्राप्त करने में मदद कर सकता है। सभी एक साथ आप matlab की तुलना में तेजी से एसी कार्यान्वयन कर सकते हैं।
डीयू जिएन

जवाबों:


85

यहां एक टेस्ला C2070 के साथ मशीन पर MATLAB R2011a + समानांतर कम्प्यूटिंग टूलबॉक्स का उपयोग करके मेरे परिणाम हैं :

>> A = rand(1024); gA = gpuArray(A);
% warm up by executing the operations a couple of times, and then:
>> tic, C = A * A; toc
Elapsed time is 0.075396 seconds.
>> tic, gC = gA * gA; toc
Elapsed time is 0.008621 seconds.

MATLAB मैट्रिक्स गुणन के लिए अत्यधिक अनुकूलित पुस्तकालयों का उपयोग करता है यही कारण है कि सादा MATLAB मैट्रिक्स गुणन इतनी तेजी से होता है। gpuArrayसंस्करण का उपयोग करता MAGMA

टेस्ला K20c के साथ एक मशीन पर R2014a का उपयोग कर अपडेट करें , और नया timeitऔर gputimeitकार्य:

>> A = rand(1024); gA = gpuArray(A);
>> timeit(@()A*A)
ans =
    0.0324
>> gputimeit(@()gA*gA)
ans =
    0.0022

16 भौतिक कोर और एक टेस्ला V100 के साथ एक Win64 मशीन पर R2018b का उपयोग करके अपडेट करें :

>> timeit(@()A*A)
ans =
    0.0229
>> gputimeit(@()gA*gA)
ans =
   4.8019e-04

(एनबी: कुछ बिंदु पर (मैं भूल जाता हूं जब वास्तव में) gpuArrayमैग्मा से क्यूबास पर स्विच किया जाता है - मैग्मा अभी भी अपने gpuArrayसंचालन के लिए उपयोग किया जाता है )


यह बात क्यों है?
मैड फिजिसिस्ट

क्या फर्क पड़ता है? मैं विभिन्न स्थितियों में MATLAB द्वारा उपयोग किए जाने वाले पुस्तकालयों में कुछ अंतर्दृष्टि देने की कोशिश कर रहा था ताकि यह समझाया जा सके कि MATLAB का प्रदर्शन अच्छा क्यों है - (क्योंकि यह अत्यधिक अनुकूलित संख्यात्मक पुस्तकालयों का उपयोग करता है।
एडिक

175

इस तरह का प्रश्न आवर्ती है और स्टैक ओवरफ्लो पर एक बार "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 के आकार द्वारा परिभाषित मैट्रिक्स के ब्लॉकों पर गुणा करते हैं (अनुवाद लुकसाइड बफर, लंबी कहानी संक्षेप: क्या प्रभावी ढंग से कैश किया जा सकता है), ताकि वे प्रोसेसर को स्ट्रीम करें वास्तव में यह जितना डेटा प्रोसेस कर सकता है। दूसरा पहलू वैश्वीकरण है, वे इष्टतम निर्देश थ्रूपुट के लिए प्रोसेसर के सदिश निर्देशों का उपयोग करते हैं, जो आप वास्तव में अपने क्रॉस-प्लेटफॉर्म सी ++ कोड से नहीं कर सकते हैं।

अंत में, लोगों का दावा है कि स्ट्रैसेन या कोपरसमिथ-विनोग्राद एल्गोरिथ्म के कारण गलत हैं, ये दोनों एल्गोरिदम व्यवहार में लागू नहीं हैं, क्योंकि ऊपर वर्णित हार्डवेयर विचारों के कारण।


2
मैंने अभी-अभी कैश आकार और कैश लाइन साइज़ में डेटा के महत्व पर स्कॉट मेयर्स वीडियो देखा, और जो समस्याएँ आपको बहु-थ्रेडेड समाधानों से हो सकती हैं, जिनका स्रोत में कोई साझा डेटा नहीं है, लेकिन हार्डवेयर में साझा किए गए डेटा के साथ समाप्त होता है / कोर-थ्रेड स्तर: youtu.be/WDIkqP4JbkE
WillC

40

यही कारण है कि है । MATLAB आपके C ++ कोड में आपके द्वारा किए गए हर एक तत्व पर लूप करके एक भोले मैट्रिक्स गुणन का प्रदर्शन नहीं करता है।

बेशक, मैं यह मान रहा हूं कि आपने केवल C=A*Bएक गुणन फ़ंक्शन लिखने के बजाय इसका उपयोग किया है ।


19

मतलाब ने कुछ समय पहले LAPACK को शामिल किया, इसलिए मुझे लगता है कि उनका मैट्रिक्स गुणन कम से कम उस तेज़ का उपयोग करता है। LAPACK स्रोत कोड और प्रलेखन आसानी से उपलब्ध है।

आप http://citeseerx.ist.psu.edu/viewdoc/download?doi/10.1.140.1785&rep=rep1&type=pdf पर गोटो और वैन डी गिजन के पेपर "एनाटॉमी ऑफ़ हाई-परफॉर्मेंस मैट्रिक्स गुणा" को भी देख सकते हैं।


7
MATLAB इंटेल MKL लाइब्रेरी का उपयोग करता है जो BLAS / LAPACK दिनचर्या का अनुकूलित कार्यान्वयन प्रदान करता है: stackoverflow.com/a/16723946/97160
Amro

11

इसका जवाब है LAPACK और BLAS लाइब्रेरी मैट्रिक्स ऑपरेशनों में MATLAB को तेजी से बनाते हैं, MATLAB पर लोगों द्वारा किसी भी मालिकाना कोड को नहीं।

का प्रयोग करें LAPACK और / या BLAS मैट्रिक्स के संचालन के लिए अपने सी ++ कोड में पुस्तकालयों और आप MATLAB के रूप में इसी तरह के प्रदर्शन मिलना चाहिए। इन पुस्तकालयों को किसी भी आधुनिक प्रणाली पर स्वतंत्र रूप से उपलब्ध होना चाहिए और कुछ दशकों में अकादमियों में भागों का विकास किया गया था। ध्यान दें कि कई कार्यान्वयन हैं, जिनमें कुछ बंद स्रोत जैसे Intel MKL शामिल हैं

बीएलएएस को उच्च प्रदर्शन कैसे प्राप्त होता है, इसकी चर्चा यहां उपलब्ध है।


BTW, यह मेरे अनुभव में सी (सीधे इसके लायक) से पुस्तकालयों पुस्तकालयों को कॉल करने के लिए एक गंभीर दर्द है। आपको प्रलेखन को ठीक से पढ़ने की आवश्यकता है।


8

मैट्रिक्स गुणा करते समय, आप भोले गुणन विधि का उपयोग करते हैं जो समय लेता है O(n^3)

वहाँ मौजूद मैट्रिक्स गुणन एल्गोरिथ्म जो लेता है O(n^2.4)। जिसका अर्थ है कि n=2000आपके एल्गोरिथ्म में ~ ~ 100 बार सर्वश्रेष्ठ एल्गोरिथ्म के रूप में गणना की आवश्यकता है।
आपको वास्तव में इसे लागू करने के कुशल तरीकों के बारे में अधिक जानकारी के लिए मैट्रिक्स गुणा के लिए विकिपीडिया पृष्ठ की जांच करनी चाहिए।


और MATLAB शायद इस तरह के एक एल्गोरिथ्म का उपयोग करते हैं क्योंकि 1024 * 1024 मैट्रिक्स के लिए समय 2048 * 2048 मैट्रिक्स गुणा के समय से 8 गुना अधिक है! अच्छा किया MATLAB लोग।
रेनॉड

4
मुझे संदेह है कि वे अपने सैद्धांतिक फायदे के बावजूद "कुशल" गुणन एल्गोरिदम का उपयोग करते हैं। यहां तक ​​कि स्ट्रैसन के एल्गोरिथ्म में कार्यान्वयन संबंधी कठिनाइयाँ हैं, और कोप्परस्मिथ-विनोग्राद एल्गोरिथम जिसे आपने शायद केवल सादे के बारे में पढ़ा है, व्यावहारिक नहीं है (अभी)। इसके अलावा, संबंधित SO थ्रेड: stackoverflow.com/questions/17716565/…
Ernir

वह एल्गोरिथ्म केवल बहुत बड़े मेट्रिसेस के लिए है।

@Renaud। यह अपेक्षाकृत स्थिर उपरि की परिभाषा है
पागल भौतिक विज्ञानी

6

मतलाब के आपके संस्करण के आधार पर, मेरा मानना ​​है कि यह पहले से ही आपके GPU का उपयोग कर रहा होगा।

एक और बात; मतलब अपने मैट्रिक्स के कई गुणों का ट्रैक रखता है; अपने विकर्ण, हेर्मेटियन, और इसके आगे, और इसके एल्गोरिदम को उसके आधार पर माहिर करें। हो सकता है कि इसकी विशेषज्ञता शून्य मैट्रिक्स के आधार पर आप इसे पारित कर रहे हैं, या ऐसा कुछ? हो सकता है कि यह बार-बार फ़ंक्शन कॉल को कैशिंग कर रहा है, जो आपके समय को गड़बड़ करता है? शायद यह दोहराया अप्रयुक्त मैट्रिक्स उत्पादों का अनुकूलन करता है?

हो रही ऐसी चीज़ों से बचाव के लिए, यादृच्छिक संख्याओं के मैट्रिक्स का उपयोग करें, और सुनिश्चित करें कि आप स्क्रीन या डिस्क या सोमेसुच पर परिणाम को प्रिंट करके निष्पादन को मजबूर करते हैं।


4
एक भारी एमएल उपयोगकर्ता के रूप में, मैं आपको बता सकता हूं कि वे अभी तक GPGPU का उपयोग नहीं कर रहे हैं। Matlab का नया संस्करण SSE1 / 2 (अंत में) का उपयोग करें। लेकिन मैंने परीक्षण किए हैं। एक तत्व-वार गुणा करने वाला एक मेक्सफंक्शन दो बार तेजी से चलता A.*Bहै। तो ओपी लगभग निश्चित रूप से कुछ पर नासमझ है।
KitsuneYMG

6
समानांतर कम्प्यूटिंग टूलबॉक्स के साथ Matlab CUDA GPU का उपयोग कर सकता है , लेकिन यह स्पष्ट है - आपको डेटा को GPU पर धकेलना होगा।
Edric

मैं M1 = सिंगल (रैंड (1024,1024) * 255) का उपयोग करता हूं; एम 2 = सिंगल (रैंड (1024,1024) * 255); और एम 3 = एम 1 * एम 2; ... तो फ़्लोट्स की बाइनरी फ़ाइल को लिखें, इसके सभी ने बहुत जल्दी किया।
वुल्फ

3

MATLAB इंटेल मैथ कर्नेल लाइब्रेरी (Intel MKL) के रूप में ज्ञात इंटेल से LAPACK के एक अत्यधिक अनुकूलित कार्यान्वयन का उपयोग करता है - विशेष रूप से dgemm फ़ंक्शन । यह लाइब्रेरी SIMD निर्देशों और मल्टी-कोर प्रोसेसर सहित प्रोसेसर सुविधाओं का लाभ उठाती है। वे दस्तावेज़ का उपयोग नहीं करते हैं जो वे विशिष्ट एल्गोरिथ्म का उपयोग करते हैं। यदि आप C ++ से Intel MKL को कॉल करते थे, तो आपको समान प्रदर्शन देखना चाहिए।

मुझे यकीन नहीं है कि क्या जीपीएल गुणन के लिए MATLAB पुस्तकालय का उपयोग करता है लेकिन शायद nVidia CUBLAS की तरह कुछ है ।


1
आप सही हैं, लेकिन क्या आपने इसका जवाब देखा है ? हालांकि, IPP MKL नहीं है और MKP में IPP की तुलना में कहीं अधिक बेहतर रैखिक बीजगणित प्रदर्शन है। इसके अलावा, आईपीपी ने हाल के संस्करणों में अपने मैट्रिक्स गणित मॉड्यूल को हटा दिया।
chappjc

क्षमा करें, मेरा मतलब है कि MKL IPP नहीं है
gregswiss

आप सही हैं अन्य उत्तर इसे कवर करते हैं। यह बहुत क्रिया है मैं इसे याद किया।
5

2

"क्यों अन्य कार्यक्रमों की तुलना में xxx करने में तेजी से matlab है" का सामान्य उत्तर यह है कि matlab में बहुत सारे बिल्ट इन, अनुकूलित कार्य हैं।

अन्य प्रोग्राम जो अक्सर उपयोग किए जाते हैं उनमें ये फ़ंक्शन नहीं होते हैं इसलिए लोग अपने स्वयं के रचनात्मक समाधान लागू करते हैं, जो पेशेवर रूप से अनुकूलित कोड की तुलना में धीमी गति से होते हैं।

इसकी दो तरह से व्याख्या की जा सकती है:

1) सामान्य / सैद्धांतिक तरीका: मतलाब काफी तेज नहीं है, आप सिर्फ बेंचमार्क गलत कर रहे हैं

2) यथार्थवादी तरीका: इस सामान के लिए मतलाब व्यवहार में तेज है क्योंकि c ++ जैसी भाषाएं केवल आसानी से अप्रभावी तरीकों से उपयोग की जाती हैं।


7
वह एक फ़ंक्शन की गति के साथ MATLAB की गति की तुलना कर रहा है जो उसने दो मिनट में लिखी थी। मैं 10 मिनट में एक तेज फ़ंक्शन लिख सकता हूं, या दो घंटे में बहुत तेज कार्य कर सकता हूं। MATLAB लोगों ने अपने मैट्रिक्स गुणन को तेज बनाने के लिए दो घंटे से अधिक समय बिताया है।
gnasher729

2

तेज कंट्रास्ट न केवल मैटलैब के अद्भुत अनुकूलन के कारण है (जैसा कि पहले से ही कई अन्य उत्तरों द्वारा चर्चा की गई है), बल्कि जिस तरह से आपने मैट्रिक्स को एक वस्तु के रूप में तैयार किया है।

ऐसा लगता है जैसे आपने मैट्रिक्स को सूचियों की सूची बना दिया है? सूचियों की एक सूची में उन बिंदुओं को इंगित किया जाता है जिनमें तब आपके मैट्रिक्स तत्व होते हैं। निहित सूचियों के स्थानों को मनमाने ढंग से सौंपा गया है। जैसा कि आप अपने पहले सूचकांक (पंक्ति संख्या?) पर लूप कर रहे हैं, मेमोरी एक्सेस का समय बहुत महत्वपूर्ण है। इसकी तुलना में, आप निम्न विधि का उपयोग करके मैट्रिक्स को एकल सूची / वेक्टर के रूप में लागू करने का प्रयास क्यों नहीं करते हैं?

#include <vector>

struct matrix {
    matrix(int x, int y) : n_row(x), n_col(y), M(x * y) {}
    int n_row;
    int n_col;
    std::vector<double> M;
    double &operator()(int i, int j);
};

तथा

double &matrix::operator()(int i, int j) {
    return M[n_col * i + j];
}

एक ही गुणन एल्गोरिथ्म का उपयोग किया जाना चाहिए ताकि फ्लॉप की संख्या समान हो। (n ^ 3 वर्ग मीटर आकार के लिए n)

मैं आपसे इसे समय देने के लिए कह रहा हूं ताकि परिणाम आपके पहले (उसी मशीन पर) के बराबर हो। तुलना के साथ, आप वास्तव में दिखाएंगे कि मेमोरी एक्सेस का समय कितना महत्वपूर्ण हो सकता है!


2

यह C ++ में धीमा है क्योंकि आप मल्टीथ्रेडिंग का उपयोग नहीं कर रहे हैं। अनिवार्य रूप से, यदि ए = बीसी, जहां वे सभी मैट्रिसेस हैं, तो ए की पहली पंक्ति को दूसरी पंक्ति से स्वतंत्र रूप से गणना की जा सकती है, आदि यदि ए, बी, और सी सभी एन मैट्रिस हैं, तो आप गुणा को तेज कर सकते हैं। n ^ 2 का एक कारक, के रूप में

a_ {i, j} = sum_ {k} b_ {i, k} c_ {k, j}

यदि आप कहते हैं, कहते हैं, Eigen [ http://eigen.tuxfamily.org/dox/GettingStarted.html ], मल्टीथ्रेडिंग अंतर्निहित है और थ्रेड्स की संख्या समायोज्य है।


2

क्योंकि MATLAB संख्यात्मक रेखीय बीजगणित (मैट्रिक्स जोड़तोड़) के लिए पहले विकसित एक प्रोग्रामिंग भाषा है, जिसमें विशेष रूप से मैट्रिक्स गुणन के लिए विकसित पुस्तकालय हैं। और अब MATLAB भी इसके लिए GPU (ग्राफिक्स प्रोसेसिंग यूनिट) का उपयोग कर सकते हैं ।

और अगर हम आपके गणना परिणामों को देखें:

             1024x1024   2048x2048   4096x4096
             ---------   ---------   ---------
CUDA C (ms)      43.11      391.05     3407.99
C++ (ms)       6137.10    64369.29   551390.93
C# (ms)       10509.00   300684.00  2527250.00
Java (ms)      9149.90    92562.28   838357.94
MATLAB (ms)      75.01      423.10     3133.90

तब हम देख सकते हैं कि न केवल MATLAB मैट्रिक्स गुणा में इतना तेज है: CUDA C (NVIDIA से प्रोग्रामिंग भाषा) MATLAB की तुलना में कुछ बेहतर परिणाम हैं। CUDA C में विशेष रूप से मैट्रिक्स गुणन के लिए विकसित पुस्तकालय हैं और यह GPU का उपयोग करता है।

MATLAB का संक्षिप्त इतिहास

न्यू मैक्सिको विश्वविद्यालय में कंप्यूटर विज्ञान विभाग के अध्यक्ष क्लीव मोलर ने 1970 के दशक के अंत में MATLAB का विकास शुरू किया। उन्होंने अपने छात्रों को LINPACK (संख्यात्मक लीनियर बीजगणित के प्रदर्शन के लिए एक सॉफ्टवेयर लाइब्रेरी) और EISPACK तक पहुँच देने के लिए इसे तैयार किया(उन्हें रेखीय बीजगणित के संख्यात्मक अभिकलन के लिए एक सॉफ्टवेयर लाइब्रेरी है) उनके बिना फोरट्रान सीखना। यह जल्द ही अन्य विश्वविद्यालयों में फैल गया और लागू गणित समुदाय के भीतर एक मजबूत दर्शकों को मिला। जैक लिटिल, एक इंजीनियर, 1983 में स्टैनफोर्ड विश्वविद्यालय में किए गए एक मोलर की यात्रा के दौरान इसे उजागर किया गया था। इसकी व्यावसायिक क्षमता को पहचानते हुए, वह मोलर और स्टीव बैंगर्ट के साथ जुड़ गए। उन्होंने सी में MATLAB को फिर से लिखा और अपने विकास को जारी रखने के लिए 1984 में MathWorks की स्थापना की। इन पुनर्लेखन पुस्तकालयों को JACKPAC के रूप में जाना जाता था। 2000 में, MATLAB मैट्रिक्स हेरफेर के लिए पुस्तकालयों के एक नए सेट का उपयोग करने के लिए फिर से लिखा गया था, LAPACK (संख्यात्मक रैखिक बीजगणित के लिए एक मानक सॉफ़्टवेयर लाइब्रेरी है)।

स्रोत

CUDA C क्या है

CUDA C, विशेष रूप से OpenGL (ओपन ग्राफिक्स लाइब्रेरी) जैसे मैट्रिक्स गुणन के लिए विकसित पुस्तकालयों का उपयोग करता है । यह GPU और Direct3D (MS Windows पर) का भी उपयोग करता है।

CUDA मंच सी, सी ++, और फोरट्रान के रूप में प्रोग्रामिंग भाषाओं के साथ काम करने के लिए बनाया गया है। यह पहुंच सीधे समानांतर प्रोग्रामिंग के विशेषज्ञों के लिए GPU संसाधनों का उपयोग करने में आसान बनाता है, Direct3D और OpenGL जैसे पूर्व API के विपरीत , जिन्हें ग्राफिक्स प्रोग्रामिंग में उन्नत कौशल की आवश्यकता थी। इसके अलावा, CUDA OpenACC और OpenCL जैसे प्रोग्रामिंग फ्रेमवर्क का समर्थन करता है ।

यहां छवि विवरण दर्ज करें

CUDA प्रसंस्करण प्रवाह का उदाहरण:

  1. मुख्य मेमोरी से GPU मेमोरी में डेटा कॉपी करें
  2. CPU, GPU कंप्यूट कर्नेल आरंभ करता है
  3. GPU के CUDA कोर समानांतर में कर्नेल को निष्पादित करते हैं
  4. GPU मेमोरी से मुख्य मेमोरी में परिणामी डेटा की प्रतिलिपि बनाएँ

सीपीयू और GPU निष्पादन गति की तुलना

हमने एक बेंचमार्क चलाया, जिसमें हमने इंटेल एक्सॉन प्रोसेसर X5650 पर 64, 128, 512, 1024 और 2048 के ग्रिड साइज़ के लिए 50 टाइम स्टेप्स को अंजाम देने में लगने वाले समय को मापा और फिर एक NVIDIA टेस्ला C208 GPU का उपयोग किया।

यहां छवि विवरण दर्ज करें

2048 के ग्रिड आकार के लिए, एल्गोरिथ्म सीपीयू पर एक मिनट से अधिक समय में GPU पर 10 सेकंड से भी कम समय में 7.5x की कमी दिखाता है। लॉग स्केल प्लॉट से पता चलता है कि सीपीयू वास्तव में छोटे ग्रिड आकार के लिए तेज़ है। जैसे-जैसे तकनीक विकसित होती है और परिपक्व होती है, हालांकि, GPU समाधान तेजी से छोटी समस्याओं को संभालने में सक्षम होते हैं, एक प्रवृत्ति जिसे हम जारी रखने की उम्मीद करते हैं।

स्रोत

CUDA C प्रोग्रामिंग गाइड के लिए परिचय से:

वास्तविक समय, उच्च परिभाषा 3 डी ग्राफिक्स के लिए लालची बाजार की मांग से प्रेरित, प्रोग्राम ग्राफिक प्रोसेसर यूनिट या GPU के रूप में के रूप में रेखांकित जबरदस्त कम्प्यूटेशनल अश्वशक्ति और बहुत ही उच्च स्मृति बैंडविड्थ के साथ एक उच्च समानांतर, थ्रेड, manycore प्रोसेसर में विकसित हुआ है Figure 1और Figure 2

चित्र 1. सीपीयू और जीपीयू के लिए प्रति सेकंड फ्लोटिंग-पॉइंट ऑपरेशन

यहां छवि विवरण दर्ज करें

चित्र 2 । CPU और GPU के लिए मेमोरी बैंडविड्थ

यहां छवि विवरण दर्ज करें

सीपीयू और जीपीयू के बीच फ्लोटिंग-पॉइंट क्षमता में विसंगति का कारण यह है कि GPU कम्प्यूट-सघन, अत्यधिक समानांतर गणना के लिए विशेष है - वास्तव में ग्राफिक्स रेंडरिंग क्या है - और इसलिए इसे ऐसे डिज़ाइन किया गया है कि अधिक ट्रांजिस्टर डेटा प्रोसेसिंग के लिए समर्पित हैं डेटा कैशिंग और प्रवाह नियंत्रण के बजाय, योजनाबद्ध रूप से सचित्र है Figure 3

चित्र 3 । GPU डाटा प्रोसेसिंग के लिए अधिक ट्रांजिस्टर को समर्पित करता है

यहां छवि विवरण दर्ज करें

अधिक विशेष रूप से, GPU विशेष रूप से डेटा-समानांतर संगणना के रूप में व्यक्त की जा सकने वाली समस्याओं के समाधान के लिए अच्छी तरह से अनुकूल है - एक ही कार्यक्रम को समानांतर में कई डेटा तत्वों पर निष्पादित किया जाता है - उच्च अंकगणितीय तीव्रता के साथ - स्मृति संचालन के लिए अंकगणितीय संचालन का अनुपात। क्योंकि प्रत्येक डेटा तत्व के लिए एक ही प्रोग्राम निष्पादित किया जाता है, परिष्कृत प्रवाह नियंत्रण के लिए कम आवश्यकता होती है, और क्योंकि यह कई डेटा तत्वों पर निष्पादित होता है और इसमें उच्च अंकगणितीय तीव्रता होती है, मेमोरी एक्सेस विलंबता को बड़े डेटा कैश के बजाय गणना के साथ छिपाया जा सकता है। ।

डेटा-समानांतर प्रसंस्करण डेटा डेटा तत्वों को समानांतर प्रसंस्करण थ्रेड्स में मैप करता है। बड़े डेटा सेट को संसाधित करने वाले कई एप्लिकेशन कंप्यूटर्स को गति देने के लिए डेटा-समानांतर प्रोग्रामिंग मॉडल का उपयोग कर सकते हैं। 3 डी रेंडरिंग में, पिक्सेल के बड़े सेट और वर्टिकल को समानांतर थ्रेड में मैप किया जाता है। इसी तरह, इमेज और मीडिया प्रोसेसिंग एप्लिकेशन जैसे कि रेंडर इमेज, वीडियो एन्कोडिंग और डिकोडिंग, इमेज स्केलिंग, स्टीरियो विजन, और पैटर्न रिकॉग्निशन जैसे पोस्ट इमेज और मैप्स को समानांतर प्रोसेसिंग थ्रेड्स में मैप कर सकते हैं। वास्तव में, इमेज रेंडरिंग और प्रोसेसिंग के क्षेत्र के बाहर कई एल्गोरिदम डेटा-समानांतर प्रसंस्करण द्वारा सामान्य सिग्नल प्रोसेसिंग या भौतिकी सिमुलेशन से कम्प्यूटेशनल फाइनेंस या कम्प्यूटेशनल बायोलॉजी में तेजी लाते हैं।

स्रोत

उन्नत पढ़ने


कुछ दिलचस्प पहलू

मैंने C ++ मैट्रिक्स गुणन लिखा है जो कि Matlab जितना तेज़ है लेकिन इसमें कुछ ध्यान रखा गया है। (इससे पहले मतलाब इसके लिए जीपीयू का इस्तेमाल कर रहा था)।

इस जवाब से उत्तेजना ।


2
वह अंतिम उद्धरण "एक तथ्य" नहीं है, यह खाली घमंड है। उस व्यक्ति ने कोड के लिए कई अनुरोध प्राप्त किए हैं क्योंकि उसने पोस्ट किया है। लेकिन देखने में कोई कोड नहीं।
क्राइस लुआंगो

1
GPU पर आप कितनी जल्दी कंप्‍यूटेशन कर सकते हैं, इस बारे में आपका विवरण प्रश्‍न का समाधान नहीं करता है। हम सभी जानते हैं कि 128 छोटे कोर 2 बड़े कोर की तुलना में अधिक, नीरस काम कर सकते हैं। "और अब MATLAB भी इसके लिए GPU (ग्राफिक्स प्रोसेसिंग यूनिट) का उपयोग कर सकते हैं।" हां, लेकिन डिफ़ॉल्ट रूप से नहीं। सामान्य मैट्रिक्स गुणन अभी भी BLAS का उपयोग करता है।
क्रूस लुआंगो

@ क्रिसलेंगो, ठीक है, यह एक तथ्य नहीं है! शायद आपके पास उसके "घमंड" के बारे में सही है - हम इसके बारे में नहीं जानते हैं और हम यह भी नहीं जानते कि वह जवाब क्यों नहीं देता। दूसरी टिप्पणी के लिए: GPU पर संगणना का वर्णन प्रश्न का उत्तर देता है क्योंकि रैखिक बीजगणित में मैट्रिक्स गुणन के लिए यह फ्लोटिंग-पॉइंट ऑपरेशन का उपयोग करता है। शायद यह सभी समझने योग्य खूंटे के लिए नहीं है, लेकिन मुझे लगता है कि उन्हें इस मूल बातें को समझना होगा। अन्य मामलों में उन्हें पहले इस मूल बातें को सीखना होगा, इससे पहले कि वे मेट्रिसेस के बारे में कुछ लेख पढ़ें। और यदि कोई अन्य मुझे इसके बारे में लिखेगा तो मैं यह विवरण जोड़ूंगा। धन्यवाद!
भरत

@ क्रिसलूंगो, मैंने शब्द लिखा था "additionally"। इसका अर्थ है: इसका उपयोग किया जा सकता है। इसका मतलब यह भी है कि सामान्य मैट्रिक्स गुणन अभी भी सॉफ्टवेयर पुस्तकालयों का उपयोग करता है। क्या आपको लगता है कि मुझे अपनी पोस्ट को और अधिक समझने के लिए बदलना होगा? आपकी टिप्पणियों के लिए धन्यवाद!
भरत
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.