অ্যারেফুন মতলবটিতে সুস্পষ্ট লুপের তুলনায় উল্লেখযোগ্যভাবে ধীর হতে পারে। কেন?


105

নিম্নলিখিত সাধারণ গতির পরীক্ষা বিবেচনা করুন arrayfun:

T = 4000;
N = 500;
x = randn(T, N);
Func1 = @(a) (3*a^2 + 2*a - 1);

tic
Soln1 = ones(T, N);
for t = 1:T
    for n = 1:N
        Soln1(t, n) = Func1(x(t, n));
    end
end
toc

tic
Soln2 = arrayfun(Func1, x);
toc

আমার মেশিনে (লিনাক্স মিন্ট 12 এ মতলব 2011 বি), এই পরীক্ষার আউটপুটটি হ'ল:

Elapsed time is 1.020689 seconds.
Elapsed time is 9.248388 seconds.

কি?!? arrayfunস্বীকারোক্তি সহকারে একটি ক্লিনার দেখা সলিউশন, এটি ধীরে ধীরে ধীরে ধীরে ক্রম হয়। এখানে কি হচ্ছে?

আরও, আমি পরীক্ষার মতো একটি শৈলী করেছি cellfunএবং এটি স্পষ্ট লুপের চেয়ে প্রায় 3 গুণ ধীর হতে দেখেছি। আবার, এই ফলাফলটি আমার প্রত্যাশার বিপরীত।

আমার প্রশ্ন হ'ল কেন arrayfunএবং cellfunএত ধীর? এবং এটি প্রদত্ত, এগুলি ব্যবহারের কোনও ভাল কারণ আছে (কোডটি ভাল দেখানো ছাড়া অন্য)?

দ্রষ্টব্য: আমি arrayfunএখানে স্ট্যান্ডার্ড সংস্করণ সম্পর্কে কথা বলছি , সমান্তরাল প্রক্রিয়াকরণ টুলবক্সের জিপিইউ সংস্করণ নয়।

সম্পাদনা: কেবল পরিষ্কার বলতে Func1গেলে , আমি সচেতন যে ওলি দ্বারা নির্দেশিত হিসাবে উপরে ভেক্টরাইজ করা যেতে পারে। আমি কেবল এটিই বেছে নিলাম কারণ এটি আসল প্রশ্নের উদ্দেশ্যে একটি সাধারণ গতি পরীক্ষা দেয় yield

সম্পাদনা: গ্রুঙ্গেটের পরামর্শ অনুসরণ করে, আমি আবার পরীক্ষা দিয়েছিলাম feature accel off। ফলাফলগুলি হ'ল:

Elapsed time is 28.183422 seconds.
Elapsed time is 23.525251 seconds.

অন্য কথায়, এটি উপস্থিত হতে পারে যে পার্থক্যের একটি বড় অংশটি হ'ল জেআইটি এক্সিলারেটর স্পষ্ট লুপটির গতি বাড়ানোর চেয়ে আরও ভাল কাজ forকরে arrayfun। এটি আমার কাছে অদ্ভুত বলে মনে হচ্ছে, যেহেতু arrayfunপ্রকৃতপক্ষে আরও বেশি তথ্য সরবরাহ করা হয়, অর্থাত্ এর ব্যবহারের মাধ্যমে বোঝা যায় যে কলগুলির ক্রম Func1কোনও ব্যাপার না। এছাড়াও, আমি উল্লেখ করেছি যে জেআইটি এক্সিলারেটর চালু আছে বা বন্ধ, আমার সিস্টেমটি কেবল কখনও একটি সিপিইউ ব্যবহার করে ...


10
ভাগ্যক্রমে, "স্ট্যান্ডার্ড সলিউশন" এখনও পর্যন্ত দ্রুততম থেকে যায়: টিক; 3 * এক্স ^ 2 + + 2 * এক্স-1। টোক বিগত সময় 0.030662 সেকেন্ড।
অলি

4
@ অলি আমি মনে করি আমার অনুমান করা উচিত ছিল যে কেউ এটি নির্দেশ করবে এবং এমন একটি ফাংশন ব্যবহার করেছে যা ভেক্টরাইজ করা যায় না :-)
কলিন টি বোয়ার্স

3
আমি জেআইটি এক্সিলারেটরটি বন্ধ হয়ে গেলে কীভাবে এই সময় পরিবর্তন হয় তা দেখতে আগ্রহী। 'ফিচার অ্যাক্সেল অফ' কমান্ডটি কার্যকর করুন এবং তারপরে আপনার পরীক্ষাটি পুনরায় চালু করুন।
গ্রুঙ্গেটা

@grungetta আকর্ষণীয় পরামর্শ। আমি কয়েকটি মন্তব্যে প্রশ্নটিতে ফলাফল যুক্ত করেছি।
কলিন টি বোয়র্স

উত্তর:


101

আপনি আপনার কোডের অন্যান্য সংস্করণ চালিয়ে ধারণাটি পেতে পারেন। আপনার লুপে কোনও ফাংশন ব্যবহার না করে স্পষ্টভাবে গণনাগুলি লিখতে বিবেচনা করুন

tic
Soln3 = ones(T, N);
for t = 1:T
    for n = 1:N
        Soln3(t, n) = 3*x(t, n)^2 + 2*x(t, n) - 1;
    end
end
toc

আমার কম্পিউটারে গণনার সময়:

Soln1  1.158446 seconds.
Soln2  10.392475 seconds.
Soln3  0.239023 seconds.
Oli    0.010672 seconds.

এখন, পুরোপুরি 'ভেক্টরাইজড' সমাধানটি স্পষ্টভাবে দ্রুততম, আপনি দেখতে পাচ্ছেন যে প্রতিটি এক্স এন্ট্রির জন্য ডাকা একটি ফাংশনকে সংজ্ঞায়িত করা একটি বিশাল ওভারহেড। খালি স্পষ্টভাবে গণনা লিখে আমাদের ফ্যাক্টর 5 গতিবেগ পেয়েছে। আমি অনুমান করি এটি দেখায় যে ম্যাটল্যাবস জেআইটি সংকলক ইনলাইন ফাংশন সমর্থন করে না । সেখানে জ্নোভাইসের উত্তর অনুসারে, কোনও অনামিকার চেয়ে স্বাভাবিক ফাংশনটি লেখার চেয়ে ভাল। চেষ্টা করে দেখুন

পরবর্তী পদক্ষেপ - অভ্যন্তরীণ লুপটি সরান (ভেক্টরাইজ করুন):

tic
Soln4 = ones(T, N);
for t = 1:T
    Soln4(t, :) = 3*x(t, :).^2 + 2*x(t, :) - 1;
end
toc

Soln4  0.053926 seconds.

আর একটি বিষয় 5 গতিবেগ: এই বিবৃতিতে এমন কিছু আছে যা বলেছে যে আপনার ম্যাটল্যাবে লুপগুলি এড়ানো উচিত ... বা সত্যই আছে? তাহলে এই একবার দেখুন

tic
Soln5 = ones(T, N);
for n = 1:N
    Soln5(:, n) = 3*x(:, n).^2 + 2*x(:, n) - 1;
end
toc

Soln5   0.013875 seconds.

'সম্পূর্ণ' ভেক্টরাইজড সংস্করণটির অনেক কাছাকাছি। মতলব ম্যাট্রিকগুলি কলাম কিতাব অনুসারে সঞ্চয় করে। আপনার গণনাগুলি 'কলাম-ওয়াইজ' ভেক্টরাইজ করার জন্য সর্বদা (যখন সম্ভব) আপনার কাঠামো গঠন করা উচিত।

আমরা এখন সলন 3 এ ফিরে যেতে পারি। লুপের ক্রমটি 'সারি অনুসারে' রয়েছে। এটি পরিবর্তন করতে দিন

tic
Soln6 = ones(T, N);
for n = 1:N
    for t = 1:T
        Soln6(t, n) = 3*x(t, n)^2 + 2*x(t, n) - 1;
    end
end
toc

Soln6  0.201661 seconds.

আরও ভাল, কিন্তু এখনও খুব খারাপ। একক লুপ - ভাল। ডাবল লুপ - খারাপ। আমার ধারণা ম্যাটল্যাব লুপগুলির কার্যকারিতা উন্নত করার জন্য কিছু শালীন কাজ করেছে তবে এখনও লুপের ওভারহেড রয়েছে। যদি আপনার ভিতরে কিছু ভারী কাজ হয় তবে আপনি খেয়াল করবেন না। তবে যেহেতু এই গণনাটি মেমরি ব্যান্ডউইথ সীমাবদ্ধ, আপনি লুপ ওভারহেড দেখতে পাবেন। আর তুমি হবে আরও বেশি পরিষ্কারভাবে সেখানে Func1 কলিং ওভারহেড দেখুন।

তাহলে অ্যারেফুনের কি অবস্থা? সেখানে কোনও ফাংশন অন্তর্ভুক্ত নয়, তাই প্রচুর ওভারহেড। তবে ডাবল নেস্টেড লুপের চেয়ে এত খারাপ কেন? প্রকৃতপক্ষে, সেলফান / অ্যারেফুন ব্যবহারের বিষয়টি বহুবার ব্যাপক আলোচনা করা হয়েছে (যেমন এখানে , এখানে , এখানে এবং এখানে ) হয়েছে । এই ফাংশনগুলি কেবল ধীর গতির, আপনি এগুলিকে সূক্ষ্ম শস্য গণনার জন্য ব্যবহার করতে পারবেন না। আপনি সেগুলি কোষ এবং অ্যারের মধ্যে কোড ব্রেভিটি এবং অভিনব রূপান্তরগুলির জন্য ব্যবহার করতে পারেন। তবে আপনি যা লিখেছেন তার চেয়ে ফাংশনটি ভারী হওয়া দরকার:

tic
Soln7 = arrayfun(@(a)(3*x(:,a).^2 + 2*x(:,a) - 1), 1:N, 'UniformOutput', false);
toc

Soln7  0.016786 seconds.

দ্রষ্টব্য যে সলন 7 এখন একটি ঘর .. কখনও কখনও এটি দরকারী। কোড পারফরম্যান্স এখন বেশ ভাল, এবং আউটপুট হিসাবে আপনার যদি সেল প্রয়োজন হয়, আপনি সম্পূর্ণ ভেক্টরাইজড সলিউশন ব্যবহার করার পরে আপনার ম্যাট্রিক্স রূপান্তর করতে হবে না।

তাহলে অ্যারেফুন সাধারণ লুপ কাঠামোর চেয়ে ধীর কেন? দুর্ভাগ্যক্রমে, আমাদের পক্ষে নিশ্চিতভাবে বলা অসম্ভব, যেহেতু কোনও উত্স কোড উপলব্ধ নেই। আপনি কেবল অনুমান করতে পারেন যেহেতু অ্যারেফুন একটি সাধারণ উদ্দেশ্য ফাংশন, যা বিভিন্ন ধরণের বিভিন্ন ডেটা স্ট্রাকচার এবং আর্গুমেন্ট পরিচালনা করে, তাই সাধারণ ক্ষেত্রে এটি খুব দ্রুত প্রয়োজন হয় না, যা আপনি লুপ নীড় হিসাবে সরাসরি প্রকাশ করতে পারেন। ওভারহেড কোথা থেকে আসে তা আমরা জানতে পারি না। ওভারহেড একটি ভাল বাস্তবায়ন দ্বারা এড়ানো যেতে পারে? হয়তো না. তবে দুর্ভাগ্যক্রমে কেবলমাত্র আমরা যা করতে পারি তা হল কেসগুলি সনাক্ত করতে পারফরম্যান্স অধ্যয়ন করা, যেখানে এটি ভালভাবে কাজ করে এবং সেগুলি যেখানে এটি হয় না।

আপডেট যেহেতু এই পরীক্ষার কার্যকর করার সময়টি খুব কম, নির্ভরযোগ্য ফলাফল পেতে আমি এখন পরীক্ষাগুলির চারপাশে একটি লুপ যুক্ত করেছি:

for i=1:1000
   % compute
end

কিছু সময় নীচে দেওয়া হয়েছে:

Soln5   8.192912 seconds.
Soln7  13.419675 seconds.
Oli     8.089113 seconds.

আপনি দেখতে পাচ্ছেন যে অ্যারেফুনটি এখনও খারাপ, তবে কমপক্ষে কমপক্ষে তিনটি আদেশ ভেক্টরাইজড দ্রবণের চেয়ে খারাপ নয়। অন্যদিকে, কলাম-ভিত্তিক গণনাগুলির একটি একক লুপ সম্পূর্ণ ভেক্টরাইজড সংস্করণ হিসাবে তত দ্রুত ... এটি সবই একটি সিপিইউতে সম্পন্ন হয়েছিল। সোলন 5 এবং সোলন 7-এর ফলাফল পরিবর্তন হয় না যদি আমি 2 কোরে স্যুইচ করি - সোলন 5-এ আমাকে এটি সমান্তরাল করে তুলতে পারফর্ম ব্যবহার করতে হবে। স্পিডআপ সম্পর্কে ভুলে যান ... Soln7 সমান্তরালে চলবে না কারণ অ্যারেফুন সমান্তরালে চলবে না। অন্যদিকে ওলী ভেক্টরাইজড সংস্করণ:

Oli  5.508085 seconds.

9
দুর্দান্ত উত্তর! এবং মাতলাব কেন্দ্রীয় সকলের লিঙ্কগুলি খুব আকর্ষণীয় পাঠ সরবরাহ করে। অনেক ধন্যবাদ.
কলিন টি বোলার

এটি একটি দুর্দান্ত বিশ্লেষণ।
এইচ.মাস্টার

এবং একটি আকর্ষণীয় আপডেট! এই উত্তরটি কেবল :-) দেয়
কলিন টি বোলারস

3
একটি ছোট মন্তব্য; ফিরে ম্যাটল্যাব .5.৫ এ cellfunম্যাক্স-ফাইল হিসাবে প্রয়োগ করা হয়েছিল (এর পাশের সি উত্স কোড সহ)। এটা আসলে বেশ সোজা ছিল। অবশ্যই এটি কেবলমাত্র 6 টি হার্ড-কোডেড ফাংশনগুলির একটির প্রয়োগকে সমর্থন করে (আপনি কোনও ফাংশনের হ্যান্ডেলটিই দিতে পারেননি, কেবল একটি ফাংশনের নাম দিয়ে একটি স্ট্রিং)
আম্রো

1
অ্যারেফুন + ফাংশন হ্যান্ডেল = ধীর! ভারী কোড এগুলি এড়ানো।
ইভন

-8

যে কারণ!!!!

x = randn(T, N); 

gpuarrayটাইপ নয় ;

আপনার যা করা দরকার তা হ'ল

x = randn(T, N,'gpuArray');

2
আমি মনে করি আপনার @angainor দ্বারা প্রশ্নটি এবং দুর্দান্ত উত্তরটি আরও কিছুটা সাবধানতার সাথে পড়তে হবে। এর সাথে কিছু করার নেই gpuarray। এই কারণটি প্রায় নিশ্চিতভাবেই এই উত্তরটি হ্রাস করা হয়েছে।
কলিন টি বোয়র্স

@ কলিন - আমি স্বীকার করি অ্যাংগিনোররা আরও পুঙ্খানুপুঙ্খ, তবে উত্তরটিতে 'জিপিউআর'এর উল্লেখ নেই। আমি মনে করি যে এখানে 'জিপুআরে'ই একটি ভাল অবদান (যদি এটি সঠিক হয়)। এছাড়াও, "এখানে কী চলছে?" নিয়ে প্রশ্নটি কিছুটা opালু হয়ে গেল ? , সুতরাং আমি মনে করি এটি ডেটা ভেক্টরাইজিং এবং এটি কোনও জিপিইউতে পাঠানোর মতো অতিরিক্ত পদ্ধতির জন্য দরজা খুলেছে। আমি এই উত্তরটি যাত্রায় দিচ্ছি কারণ এটি ভবিষ্যতের দর্শকদের জন্য মান যোগ করতে পারে। আমি ভুল কল করলে আমার ক্ষমা চাই ologies
jwww

1
আপনি gpuarrayকেবল এনভিডিয়া গ্রাফিক্স কার্ডের জন্য সমর্থিত এই সত্যটিও ভুলে যান । তাদের যদি এমন হার্ডওয়্যার না থাকে তবে আপনার পরামর্শ (বা অভাব) অর্থহীন। -1
রায়রেং

অন্যদিকে, জিপুয়ারে হ'ল ম্যাট্লাব ভেক্টরাইজড প্রোগ্রামিংয়ের হালকা সাবার।
MrIO
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.