खोज…


टिप्पणियों

Profiler का उपयोग करके प्रदर्शन की अड़चन की पहचान करना

MATLAB प्रोफाइलर के लिए एक उपकरण है सॉफ्टवेयर रूपरेखा MATLAB कोड की। Profiler का उपयोग करना, निष्पादन समय और मेमोरी खपत दोनों का दृश्य प्रतिनिधित्व प्राप्त करना संभव है।

Profiler चलाना दो तरीकों से किया जा सकता है:

  • MATLAB GUI में "रन एंड टाइम" बटन पर क्लिक करते हुए संपादक में कुछ .m फाइल खुली ( R2012b में जोड़ी गई)।

    टूलस्ट्रिप में बटन

  • प्रोग्रामेटिक रूप से, उपयोग करना:

    profile on
    <some code we want to test>
    profile off
    

नीचे कुछ नमूना कोड और इसकी रूपरेखा का परिणाम है:

function docTest

for ind1 = 1:100
  [~] = var(...
            sum(...
                randn(1000)));
end

spy

प्रोफाइलर उत्पादन

ऊपर से हम सीखते हैं कि spy कार्य कुल निष्पादन समय का लगभग 25% लेता है। "वास्तविक कोड" के मामले में, एक ऐसा फ़ंक्शन जो निष्पादन के समय का इतना बड़ा प्रतिशत लेता है, अनुकूलन के लिए एक अच्छा उम्मीदवार होगा, क्योंकि var और cla अनुरूप कार्यों के विपरीत जिनके अनुकूलन से बचा जाना चाहिए।

इसके अलावा, फंक्शन नेम कॉलम में प्रविष्टियों पर क्लिक करना संभव है ताकि उस प्रविष्टि के लिए निष्पादन समय का एक विस्तृत ब्रेकडाउन हो सके। यहाँ spy क्लिक करने का उदाहरण है:

"जासूस" की आंतरिक समयावधि


प्रोफाइलर को चलाने से पहले profile('-memory') को निष्पादित करके मेमोरी की खपत को प्रोफाइल करना भी संभव है।

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

कई कार्यों के निष्पादन समय की तुलना करना

tic और toc का व्यापक रूप से उपयोग किया जाने वाला संयोजन किसी फ़ंक्शन या कोड स्निपेट के निष्पादन समय का एक मोटा विचार प्रदान कर सकता है।

कई कार्यों की तुलना करने के लिए इसका उपयोग नहीं किया जाना चाहिए। क्यों? उपरोक्त कोड का उपयोग करके स्क्रिप्ट के भीतर तुलना करने के लिए सभी कोड स्निपेट्स के लिए समान स्थिति प्रदान करना लगभग असंभव है। हो सकता है कि फ़ंक्शन समान फ़ंक्शन स्थान और सामान्य चर साझा करते हैं, इसलिए बाद में फ़ंक्शन और कोड स्निपेट्स पहले से ही आरंभिक चर और फ़ंक्शन का लाभ उठाते हैं। इसके अलावा, इस बात की कोई जानकारी नहीं है कि क्या JIT कंपाइलर बाद में समान रूप से स्निपेट्स कहे जाने वाले इन हैंडल करेगा।


बेंचमार्क के लिए समर्पित कार्य timeit । निम्न उदाहरण इसके उपयोग को दर्शाता है।

सरणी A और मैट्रिक्स B । यह निर्धारित किया जाना चाहिए कि विभिन्न तत्वों की संख्या की गणना करके B की कौन सी पंक्ति A समान है।

function t = bench()
    A = [0 1 1 1 0 0];
    B = perms(A);

    % functions to compare
    fcns = {
        @() compare1(A,B);
        @() compare2(A,B);
        @() compare3(A,B);
        @() compare4(A,B);
    };

    % timeit
    t = cellfun(@timeit, fcns);
end

function Z = compare1(A,B)  
    Z = sum(  bsxfun(@eq,  A,B) , 2);
end
function Z = compare2(A,B)  
    Z = sum(bsxfun(@xor, A, B),2);
end
function Z = compare3(A,B)  
    A = logical(A);
    Z = sum(B(:,~A),2) + sum(~B(:,A),2);
end
function Z = compare4(A,B)  
     Z = pdist2( A, B, 'hamming', 'Smallest', 1 );
end

बेंचमार्क का यह तरीका पहली बार इस जवाब में देखा गया था।

यह `सिंगल` होना ठीक है!

अवलोकन:

MATLAB में संख्यात्मक सरणियों के लिए डिफ़ॉल्ट डेटा प्रकार doubledouble का एक फ्लोटिंग पॉइंट प्रतिनिधित्व है , और यह प्रारूप प्रति मूल्य 8 बाइट्स (या 64 बिट्स) लेता है। कुछ मामलों में, जहां उदाहरण केवल पूर्णांक के साथ काम कर रहे हैं या जब संख्यात्मक अस्थिरता एक आसन्न मुद्दा नहीं है, तो ऐसी उच्च बिट गहराई की आवश्यकता नहीं हो सकती है। इस कारण से, single परिशुद्धता (या अन्य उपयुक्त प्रकार ) के लाभों पर विचार करने की सलाह दी जाती है:

  • तेज़ निष्पादन समय (विशेष रूप से GPU पर ध्यान देने योग्य)।
  • मेमोरी की आधी खपत: वह सफल हो सकती है जहाँ double आउट ऑफ़ मेमोरी त्रुटि के कारण विफल हो जाता है; फ़ाइलों के रूप में संग्रहीत करते समय अधिक कॉम्पैक्ट।

किसी समर्थित डेटा प्रकार से single में परिवर्तनशील का उपयोग करके किया जाता है:

sing_var = single(var);

कुछ आमतौर पर उपयोग किए जाने वाले कार्य (जैसे: zeros , eye , ones , आदि ) जो डिफ़ॉल्ट रूप से double मान का उत्पादन करते ones , आउटपुट के प्रकार / वर्ग को निर्दिष्ट करने की अनुमति देते हैं।

स्क्रिप्ट को एक गैर-डिफ़ॉल्ट परिशुद्धता / प्रकार / वर्ग में परिवर्तित करना:

जुलाई 2016 तक, डिफ़ॉल्ट MATLAB डेटा प्रकार को double से बदलने के लिए कोई प्रलेखित तरीका मौजूद नहीं है।

MATLAB में, नए वैरिएबल आमतौर पर बनाते समय उपयोग किए जाने वाले वैरिएबल के डेटा प्रकारों की नकल करते हैं। इसे समझने के लिए, निम्नलिखित उदाहरण पर विचार करें:

A = magic(3);
B = diag(A);
C = 20*B;
>> whos C
  Name      Size            Bytes  Class     Attributes
  C         3x1                24  double 
A = single(magic(3)); % A is converted to "single"
B = diag(A);
C = B*double(20);     % The stricter type, which in this case is "single", prevails
D = single(size(C));  % It is generally advised to cast to the desired type explicitly.
>> whos C
  Name      Size            Bytes  Class     Attributes
  C         3x1                12  single  

इस प्रकार, कोड में परिवर्तन की अनुमति देने के लिए कई प्रारंभिक चर डालना / परिवर्तित करना पर्याप्त लग सकता है - हालाँकि यह हतोत्साहित है (नीचे दिए गए कैवेट और नुकसान देखें)।

कैविट्स और नुकसान:

  1. संख्यात्मक शोर (जब single से double तक कास्टिंग) या जानकारी के नुकसान (जब double से single , या कुछ पूर्णांक प्रकारों के बीच कास्टिंग) की शुरूआत के कारण बार-बार रूपांतरण हतोत्साहित किया जाता है , जैसे:

    double(single(1.2)) == double(1.2)   
    ans =
         0
    

    यह typecast का उपयोग करके कुछ हद तक कम किया जा सकता है। फ्लोटिंग पॉइंट की अशुद्धि के बारे में भी देखें।

  2. पूरी तरह से अंतर्निहित डेटा-टाइपिंग पर निर्भर (यानी MATLAB का अनुमान है कि एक संगणना के उत्पादन का प्रकार क्या होना चाहिए) कई अवांछित प्रभावों के कारण हतोत्साहित किया जाता है:

    • जानकारी का नुकसान : जब एक double परिणाम की उम्मीद की जाती है, लेकिन single और double ऑपरेंड का एक लापरवाह संयोजन single परिशुद्धता प्राप्त करता है।

    • अप्रत्याशित रूप से उच्च मेमोरी खपत : जब single परिणाम की उम्मीद की जाती है, लेकिन एक लापरवाह गणना एक double आउटपुट में परिणाम देती है।

    • GPU के साथ काम करते समय अनावश्यक ओवरहेड : जब गैर- gpuArray वैरिएबल (अर्थात आमतौर पर रैम में संग्रहीत) के साथ gpuArray प्रकार (अर्थात चर में संग्रहित) को gpuArray , डेटा को gpuArray किए जाने से पहले एक या दूसरे तरीके से स्थानांतरित करना होगा। इस ऑपरेशन में समय लगता है, और दोहराए जाने वाले संगणना में बहुत ध्यान देने योग्य हो सकता है।

    • पूर्णांक प्रकारों के साथ फ़्लोटिंग-पॉइंट प्रकारों को मिलाते समय त्रुटियां : पूर्णांक और फ़्लोटिंग पॉइंट प्रकारों के मिश्रित इनपुट के लिए mtimes ( * ) जैसे कार्य परिभाषित नहीं हैं - और त्रुटि होगी। पूर्णांक प्रकार के इनपुट के लिए times ( .* ) जैसे कार्य परिभाषित नहीं हैं - और फिर त्रुटि होगी।

      >> ones(3,3,'int32')*ones(3,3,'int32')
      Error using  * 
      MTIMES is not fully supported for integer classes. At least one input must be scalar.
      
      >> ones(3,3,'int32').*ones(3,3,'double')
      Error using  .* 
      Integers can only be combined with integers of the same class, or scalar doubles.
      

    बेहतर कोड पठनीयता और अवांछित प्रकार के जोखिम को कम करने के लिए, एक रक्षात्मक दृष्टिकोण की सलाह दी जाती है , जहां चर स्पष्ट रूप से वांछित प्रकार के लिए डाले जाते हैं।


यह सभी देखें:

ND-array को पुनर्व्यवस्थित करने से समग्र प्रदर्शन में सुधार हो सकता है

कुछ मामलों में हमें एनडी-सरणियों के एक सेट पर कार्यों को लागू करने की आवश्यकता होती है। आइए इस सरल उदाहरण को देखें।

A(:,:,1) = [1 2; 4 5];
A(:,:,2) = [11 22; 44 55];
B(:,:,1) = [7 8; 1 2];
B(:,:,2) = [77 88; 11 22];

A =

ans(:,:,1) =

   1   2 
   4   5 

ans(:,:,2) =

   11   22
   44   55

>> B
B =

ans(:,:,1) =

   7   8
   1   2

ans(:,:,2) =

   77   88
   11   22

दोनों मैट्रीक 3 डी हैं, मान लें कि हमें निम्नलिखित गणना करनी है:

result= zeros(2,2);
...
for k = 1:2 
   result(i,j) = result(i,j) + abs( A(i,j,k) - B(i,j,k) );
...

if k is very large, this for-loop can be a bottleneck since MATLAB order the data in a column major fashion. So a better way to compute "result" could be:

% trying to exploit the column major ordering
Aprime = reshape(permute(A,[3,1,2]), [2,4]);
Bprime = reshape(permute(B,[3,1,2]), [2,4]);


>> Aprime
Aprime =

    1    4    2    5
   11   44   22   55

>> Bprime
Bprime =

    7    1    8    2
   77   11   88   22

अब हम निम्नलिखित के लिए उपरोक्त लूप को प्रतिस्थापित करते हैं:

result= zeros(2,2);
....
temp = abs(Aprime - Bprime);
for k = 1:2
    result(i,j) = result(i,j) + temp(k, i+2*(j-1));
...

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

उपदेश का महत्व

MATLAB में Arrays को मेमोरी में निरंतर ब्लॉक के रूप में रखा जाता है, MATLAB द्वारा स्वचालित रूप से आवंटित और जारी किया जाता है। MATLAB सिंटैक्स का उपयोग करने के लिए एक सरणी का आकार बदलने के रूप में स्मृति प्रबंधन संचालन को छुपाता है:

a = 1:4

a =

     1     2     3     4

a(5) = 10  % or alternatively a = [a, 10]

a =

     1     2     3     4    10

यह समझना महत्वपूर्ण है कि ऊपर एक तुच्छ ऑपरेशन नहीं है, a(5) = 10 MATLAB का कारण होगा आकार 5 की स्मृति का एक नया ब्लॉक आवंटित करने के लिए, पहले 4 संख्याओं की प्रतिलिपि बनाएँ, और 5'th को 10 पर सेट करें। वह O(numel(a)) ऑपरेशन है, और O(1)

निम्नलिखित को धयान मे रखते हुए:

clear all
n=12345678;
a=0;
tic
for i = 2:n
    a(i) = sqrt(a(i-1)) + i;
end
toc

Elapsed time is 3.004213 seconds.

इस लूप में a वास्तविक बार n (MATLAB द्वारा किए गए कुछ अनुकूलन को छोड़कर)! ध्यान दें कि MATLAB हमें एक चेतावनी देता है:

"चर 'ए' प्रत्येक लूप पुनरावृत्ति पर आकार बदलता प्रतीत होता है। गति के लिए प्रचार करने पर विचार करें।"

जब हम प्रचार करते हैं तो क्या होता है?

a=zeros(1,n);
tic
for i = 2:n
    a(i) = sqrt(a(i-1)) + i;
end
toc

Elapsed time is 0.410531 seconds.

हम देख सकते हैं कि रनटाइम को परिमाण के एक क्रम से कम किया जाता है।

उपदेश के लिए तरीके:

MATLAB वैक्टर और मैट्रिस के आवंटन के लिए उपयोगकर्ता की विशिष्ट आवश्यकताओं के आधार पर विभिन्न कार्य प्रदान करता है। इनमें शामिल हैं: zeros , ones , nan , eye , true आदि।

a = zeros(3)       % Allocates a 3-by-3 matrix initialized to 0
a =

     0     0     0
     0     0     0
     0     0     0

a = zeros(3, 2)     % Allocates a 3-by-2 matrix initialized to 0
a =

     0     0
     0     0
     0     0

a = ones(2, 3, 2)      % Allocates a 3 dimensional array (2-by-3-by-2) initialized to 1
a(:,:,1) =

     1     1     1
     1     1     1


a(:,:,2) =

     1     1     1
     1     1     1

a = ones(1, 3) * 7  % Allocates a row vector of length 3 initialized to 7
a =

     7     7     7

एक डेटा प्रकार भी निर्दिष्ट किया जा सकता है:

a = zeros(2, 1, 'uint8');  % allocates an array of type uint8

मौजूदा सरणी के आकार को क्लोन करना भी आसान है:

a = ones(3, 4);       % a is a 3-by-4 matrix of 1's
b = zeros(size(a));  % b is a 3-by-4 matrix of 0's

और क्लोन प्रकार:

a = ones(3, 4, 'single');       % a is a 3-by-4 matrix of type single
b = zeros(2, 'like', a);        % b is a 2-by-2 matrix of type single

ध्यान दें कि 'like' भी क्लोनिंग जटिलता और स्पार्सिटी है

प्रीक्लोकेशन को किसी भी फ़ंक्शन का उपयोग करके प्राप्त किया जाता है जो अंतिम आवश्यक आकार की एक सरणी देता है, जैसे कि rand , gallery , kron , bsxfun , colon और कई अन्य। उदाहरण के लिए, रैखिक भिन्न तत्वों के साथ वैक्टर आवंटित करने का एक सामान्य तरीका कोलन ऑपरेटर (2- या 3-ऑपरेंड संस्करण 1 के साथ ) का उपयोग करके है:

a = 1:3 
a =

     1     2     3

a = 2:-3:-4
a =

     2    -1    -4

सेल सरणियों को cell() फ़ंक्शन का उपयोग करके उसी तरह से आवंटित किया जा सकता है जैसे कि zeros()

a = cell(2,3)
a = 

    []    []    []
    []    []    []

ध्यान दें कि सेल एरे को सेल कंटेंट की याद में स्थानों पर पॉइंटर्स लगाकर काम करते हैं। इसलिए सभी उपदेश युक्तियाँ व्यक्तिगत सेल सरणी तत्वों पर भी लागू होती हैं।


आगे की पढाई:



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow