কীভাবে বিএলএএস এর মতো চরম পারফরম্যান্স পায়?


108

কৌতূহলের বাইরে আমি বিএলএএস বাস্তবায়ন বনাম আমার নিজের ম্যাট্রিক্স গুণনের ফাংশনটি বেঞ্চমার্ক করার সিদ্ধান্ত নিয়েছি ... ফলাফলটি সম্পর্কে আমি কমপক্ষে অবাক হয়ে বলছিলাম:

কাস্টম বাস্তবায়ন, 1000x1000 ম্যাট্রিক্স গুণনের 10 ট্রায়াল:

Took: 15.76542 seconds.

BLAS বাস্তবায়ন, 1000x1000 ম্যাট্রিক্স গুণনের 10 টি ট্রায়াল:

Took: 1.32432 seconds.

এটি একক নির্ভুলতা ভাসমান পয়েন্ট সংখ্যা ব্যবহার করছে।

আমার বাস্তবায়ন:

template<class ValT>
void mmult(const ValT* A, int ADim1, int ADim2, const ValT* B, int BDim1, int BDim2, ValT* C)
{
    if ( ADim2!=BDim1 )
        throw std::runtime_error("Error sizes off");

    memset((void*)C,0,sizeof(ValT)*ADim1*BDim2);
    int cc2,cc1,cr1;
    for ( cc2=0 ; cc2<BDim2 ; ++cc2 )
        for ( cc1=0 ; cc1<ADim2 ; ++cc1 )
            for ( cr1=0 ; cr1<ADim1 ; ++cr1 )
                C[cc2*ADim2+cr1] += A[cc1*ADim1+cr1]*B[cc2*BDim1+cc1];
}

আমার দুটি প্রশ্ন আছে:

  1. প্রদত্ত ম্যাট্রিক্স-ম্যাট্রিক্সের গুণটি বলুন: এনএক্সএম * এমএক্সএন এর জন্য এন * এন * এম গুণক প্রয়োজন, সুতরাং 1000 ^ 3 বা 1e9 ক্রিয়াকলাপের ক্ষেত্রে। আমার ২.S গিগাহার্টজ প্রসেসরে কীভাবে বিএলএএস এর জন্য 1.32 সেকেন্ডে 10 * 1e9 অপারেশন করা সম্ভব? এমনকি যদি গুণকগুলি একটি একক অপারেশন ছিল এবং অন্য কিছুই করা হচ্ছে না, এটিতে ~ 4 সেকেন্ড সময় নেওয়া উচিত।
  2. আমার বাস্তবায়ন এত ধীর কেন?

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

3
তবুও আপনি কীভাবে 1.3 সেকেন্ডের মধ্যে একটি 2.63E9 চক্র / দ্বিতীয় প্রসেসরে 1E10 অপারেশন করবেন?
ডিউসএডুরো

9
একাধিক এক্সিকিউশন ইউনিট, পাইপ-আস্তরণ এবং একক নির্দেশনা একাধিক ডেটা (সিমডি) যার অর্থ একই সময়ে একাধিক জোড়া অপারেন্ডে একই ক্রিয়াকলাপ করা। কিছু সংকলক সাধারণ চিপগুলিতে সিমড ইউনিটগুলিকে লক্ষ্য করতে পারে তবে আপনাকে প্রায় সবসময় স্পষ্টভাবে চালু করতে হবে এবং এটি কীভাবে কাজ করে তা জানতে সহায়তা করে ( en.wikedia.org/wiki/SIMD )। ক্যাশে মিসের বিরুদ্ধে বীমা করা প্রায় নিশ্চিত অংশ।
ডিএমকেকে --- প্রাক্তন-মডারেটর বিড়ালছানা

13
অনুমান ভুল। আরও ভাল অ্যালগরিদম জানা আছে, উইকিপিডিয়া দেখুন।
এমসাল্টারস 20:38

2
@ ডিউসএডুরো: আমার উত্তরে কীভাবে ম্যাট্রিক্স ম্যাট্রিক্স পণ্যটি লিখবেন যা ইগেনের সাথে প্রতিযোগিতা করতে পারে? ক্যাশে দক্ষ ম্যাট্রিক্স-ম্যাট্রিক্স পণ্য কীভাবে প্রয়োগ করা যায় সে সম্পর্কে আমি একটি ছোট উদাহরণ পোস্ট করেছি।
মাইকেল লেহন

উত্তর:


141

একটি ভাল সূচনা পয়েন্ট হ'ল রবার্ট এ। ভ্যান ডি গেইজন এবং এনরিক এস কুইন্টানা-অর্টির দ্য সায়েন্স অফ প্রোগ্রামিং ম্যাট্রিক্স কম্পিউটেশন book তারা বিনামূল্যে ডাউনলোড সংস্করণ সরবরাহ করে।

BLAS তিনটি স্তরে বিভক্ত:

  • স্তর 1 লিনিয়ার বীজগণিত ফাংশনগুলির একটি সেট সংজ্ঞা দেয় যা কেবল ভেক্টরগুলিতেই কাজ করে। এই ফাংশনগুলি ভেক্টরাইজেশন (যেমন এসএসই ব্যবহার করে) থেকে উপকৃত হয়।

  • স্তর 2 ফাংশন হ'ল ম্যাট্রিক্স-ভেক্টর অপারেশন, যেমন কিছু ম্যাট্রিক্স-ভেক্টর পণ্য। এই ফাংশনগুলি স্তর 1 এর ফাংশনগুলির ক্ষেত্রে প্রয়োগ করা যেতে পারে। যাইহোক, আপনি যদি এই ডেডিকেটেড বাস্তবায়ন সরবরাহ করতে পারেন যা কিছু মাল্টিপ্রসেসর আর্কিটেকচারকে ভাগ করে নেওয়া মেমরির সাথে ব্যবহার করে তবে আপনি এই ক্রিয়াকলাপগুলির কার্যকারিতা বাড়িয়ে তুলতে পারেন।

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

যাইহোক, বেশিরভাগ (বা সমস্ত) উচ্চ কার্যকারিতা বিএলএএস বাস্তবায়ন ফোর্টরানে প্রয়োগ করা হয় না। ATLAS সি তে প্রয়োগ করা হয় GotoBLAS / ওপেনবিএলএস সি তে প্রয়োগ করা হয় এবং এসেম্ব্লারগুলিতে এর কার্য সম্পাদনের গুরুতর অংশ। ফোর্টরানে কেবল বিএলএএস-এর রেফারেন্স প্রয়োগকরণ কার্যকর করা হয়। যাইহোক, এই সমস্ত BLAS বাস্তবায়ন একটি ফোর্টরান ইন্টারফেস সরবরাহ করে যাতে এটিকে ল্যাপাকের সাথে যুক্ত করা যেতে পারে (ল্যাপাক তার সমস্ত কর্মক্ষমতা BLAS থেকে লাভ করে)।

অনুকূলিত সংকলকগণ এই ক্ষেত্রে সামান্য ভূমিকা পালন করে (এবং গোটোব্ল্যাএস / ওপেনবিএলএসের জন্য সংকলকটি মোটেই গুরুত্বপূর্ণ নয়)।

আইএমএইচও-র কোনও বিএএলএস বাস্তবায়ন কপারস্মিথ-উইনোগ্রাদ অ্যালগরিদম বা স্ট্র্যাসেন অ্যালগরিদমের মতো অ্যালগরিদম ব্যবহার করে না। কারণ সম্পর্কে আমি ঠিক নিশ্চিত নই, তবে এটি আমার অনুমান:

  • এই অ্যালগরিদমগুলির একটি ক্যাশে অনুকূলিতকরণ বাস্তবায়ন সরবরাহ করা সম্ভব নয় (যেমন আপনি আরও looseিলে থাকতেন তবে আপনি জিততেন)
  • এই অ্যালগরিদমগুলি সংখ্যাগতভাবে স্থিতিশীল নয়। যেহেতু বিএলএএস হ'ল ল্যাপাকের গণনামূলক কার্নেল এটি কোনও অগ্রগতি নয়।

সম্পাদনা / আপডেট:

এই বিষয়ের জন্য নতুন এবং গ্রাউন্ড ব্রেকিং পেপার হলেন বিএলআইএসের কাগজপত্র । এগুলি ব্যতিক্রমীভাবে খুব ভাল লেখা আছে। আমার বক্তৃতাটির জন্য "হাই পারফরম্যান্স কম্পিউটিংয়ের জন্য সফটওয়্যার বেসিকস" আমি তাদের কাগজ অনুসরণ করে ম্যাট্রিক্স-ম্যাট্রিক্স পণ্যটি প্রয়োগ করেছি। আসলে আমি ম্যাট্রিক্স-ম্যাট্রিক্স পণ্যটির বেশ কয়েকটি রূপ প্রয়োগ করেছি implemented সহজতম রূপগুলি সম্পূর্ণ প্লেইন সিতে লিখিত এবং কোডের 450 এরও কম লাইনের রয়েছে। অন্যান্য সমস্ত রূপগুলি কেবল লুপগুলি অনুকূল করে তোলে

    for (l=0; l<MR*NR; ++l) {
        AB[l] = 0;
    }
    for (l=0; l<kc; ++l) {
        for (j=0; j<NR; ++j) {
            for (i=0; i<MR; ++i) {
                AB[i+j*MR] += A[i]*B[j];
            }
        }
        A += MR;
        B += NR;
    }

ম্যাট্রিক্স-ম্যাট্রিক্স পণ্যের সামগ্রিক কর্মক্ষমতা শুধুমাত্র এই লুপ উপর নির্ভর করে। প্রায় 99.9% সময় এখানে ব্যয় করা হয়। অন্যান্য ভেরিয়েন্টে আমি পারফরম্যান্সের উন্নতির জন্য ইন্টার্নিক এবং এসেম্বলার কোড ব্যবহার করেছি। আপনি টিউটোরিয়ালটি এখানে সমস্ত রূপের মধ্য দিয়ে যেতে দেখতে পারেন:

#BLAS: জিমের টিউটোরিয়াল (ম্যাট্রিক্স-ম্যাট্রিক্স পণ্য)

বিএলআইএসের কাগজপত্রগুলির সাথে একত্রে এটি বুঝতে মোটামুটি সহজ হয়ে যায় যে কীভাবে ইনটেল এমকেএল এর মতো লাইব্রেরিগুলি এই ধরনের পারফরম্যান্স অর্জন করতে পারে। এবং কেন আপনি সারি বা কলামের বড় স্টোরেজ ব্যবহার করেন তা বিবেচ্য নয়!

চূড়ান্ত মানদণ্ডগুলি এখানে রয়েছে (আমরা আমাদের প্রকল্পকে ulBLAS বলেছি):

#BLAS, BLIS, MKL, ওপেনবিএলএস এবং ইগেনের জন্য বেঞ্চমার্ক

অন্য সম্পাদনা / আপডেট:

আমি লিনিয়ার সমীকরণের সিস্টেম সমাধানের মতো সংখ্যাগত লিনিয়ার বীজগণিত সমস্যার জন্য কীভাবে বিএলএলএস ব্যবহার করা হয় সে সম্পর্কে কিছু টিউটোরিয়াল লিখেছিলাম:

উচ্চ পারফরম্যান্স এলইউ ফ্যাক্টরাইজেশন

(এই এলইউ অনুকরণটি উদাহরণস্বরূপ রৈখিক সমীকরণের একটি সিস্টেম সমাধান করার জন্য মতলব দ্বারা ব্যবহৃত))

আমি সময় খুঁজে আশা করি বর্ণনা প্রদর্শন কিভাবে মত এল ইউ গুণকনির্ণয় এর অতিমাত্রায় প্রসারণযোগ্য সমান্তরাল বাস্তবায়ন উপলব্ধি করা থেকে টিউটোরিয়াল প্রসারিত করতে রক্তরস

ঠিক আছে, আপনি এখানে যান: একটি ক্যাশে কোডিং অপ্টিমাইজড সমান্তরাল এলইউ ফ্যাক্টরাইজেশন

পিএস: আমি ইউবিএলএসের কর্মক্ষমতা উন্নত করতে কিছু পরীক্ষা-নিরীক্ষাও করেছি। ইউবিএলএসের পারফরম্যান্সকে উত্সাহিত করতে এটি বেশ সহজ (হ্যাঁ, কথায় কথায় খেলুন :))

ইউবিএলএস-এ পরীক্ষা-নিরীক্ষা

এখানে ব্লেজ সহ একই প্রকল্প :

ব্লাজে পরীক্ষা-নিরীক্ষা


3
"বিএমআইএলএস, বিএলআইএস, এমকেএল, ওপেনবিএলএস এবং ইজেনের জন্য বেঞ্চমার্ক" - এর নতুন লিঙ্ক: apfel.mathematik.uni-ulm.de/~lehn/ulmBLAS/#toc3
আহমেদ ফ্যাসিহ

দেখা যাচ্ছে যে আইবিএম এর ইএসএসএল স্ট্র্যাসেন অ্যালগরিদম - আইবিএম
বেন-অ্যালব্রেচট

2
বেশিরভাগ লিঙ্কগুলি মারা গেছে
অরলিয়ান পিয়ের

টিএসওপিএমসির একটি পিডিএফ cs.utexas.edu/users/rvdg/tmp/TSoPMC.pdf
অ্যালেক্স শপিলকিন

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

26

সুতরাং সকল বিএলএএস এর প্রথমটি হ'ল প্রায় 50 টি কার্যের ইন্টারফেস। ইন্টারফেসের অনেকগুলি প্রতিযোগিতামূলক বাস্তবায়ন রয়েছে।

প্রথমত আমি সেই জিনিসগুলি উল্লেখ করব যা মূলত সম্পর্কিত নয়:

  • ফোর্টরান বনাম সি, কোনও পার্থক্য করে না
  • স্ট্র্যাসেনের মতো উন্নত ম্যাট্রিক্স অ্যালগরিদম, বাস্তবায়নে সেগুলি ব্যবহার করতে পারবেন না কারণ তারা অনুশীলনে সহায়তা করবেন না

বেশিরভাগ বাস্তবায়ন প্রতিটি অপারেশনকে কম-বেশি সুস্পষ্ট উপায়ে ছোট মাত্রার ম্যাট্রিক্স বা ভেক্টর অপারেশনগুলিতে বিভক্ত করে। উদাহরণস্বরূপ একটি বড় 1000x1000 ম্যাট্রিক্স গুণনটি 50x50 ম্যাট্রিক্স গুণনের ক্রমিকায় বিভক্ত হতে পারে।

এই নির্দিষ্ট আকারের ছোট-মাত্রার ক্রিয়াকলাপগুলি (কার্নেল নামে পরিচিত) তাদের টার্গেটের বেশ কয়েকটি সিপিইউ বৈশিষ্ট্য ব্যবহার করে সিপিইউ-নির্দিষ্ট সমাবেশ কোডে হার্ডকোড করা হয়:

  • সিমডি-স্টাইল নির্দেশাবলী
  • নির্দেশ স্তর সমান্তরালতা
  • Cache-সচেতনতা

তদুপরি এই কার্নেলগুলি একাধিক থ্রেড (সিপিইউ কোর) ব্যবহার করে একে অপরের সাথে সমান্তরালভাবে কার্যকর করা যেতে পারে, আদর্শ মানচিত্র-হ্রাস নকশার প্যাটার্নে।

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

(টিপ: এজন্য আপনি যদি আটলাস ব্যবহার করে থাকেন তবে আপনি নিজের নির্দিষ্ট মেশিনের জন্য হাতের সাহায্যে গ্রন্থাগারটি তৈরি এবং সুরক্ষার চেয়ে আরও ভাল ব্যবহার করতে পারেন তবে প্রাক-বিল্ট একটি ব্যবহার করে))


আটলাস আর সর্বাধিক ব্যবহৃত ওপেন সোর্স BLAS বাস্তবায়ন নয়। এটি ওপেনব্লাস (গোটোব্লাসের একটি কাঁটাচালক) এবং বিএলআইএস (গোটোব্লাসের একটি রিফ্যাক্টরিং) ছাড়িয়ে গেছে।
রবার্ট ভ্যান ডি গিজেন

1
@ ulaff.net: সম্ভবত। এটি লেখা হয়েছিল 6 বছর আগে। আমি মনে করি বর্তমানে দ্রুততম BLAS বাস্তবায়নটি (অবশ্যই ইন্টেলের উপর) ইন্টেল এমকেএল, তবে এটি উন্মুক্ত উত্স নয়।
অ্যান্ড্রু তোমাজস

14

প্রথমত, ম্যাট্রিক্স গুণনের জন্য আপনি যেটি ব্যবহার করছেন তার চেয়ে আরও দক্ষ অ্যালগরিদম রয়েছে।

দ্বিতীয়ত, আপনার সিপিইউ একসাথে একাধিক নির্দেশাবলম্বন করতে পারে।

আপনার সিপিইউ প্রতি চক্র অনুসারে 3-4 নির্দেশাবলী কার্যকর করে এবং সিমডি ইউনিট ব্যবহার করা হলে প্রতিটি নির্দেশ 4 টি ফ্লোট বা 2 ডাবল প্রসেস করে। (অবশ্যই এই চিত্রটিও সঠিক নয়, কারণ সিপিইউ সাধারণত প্রতিটি চক্রের জন্য একটি সিমডি নির্দেশ প্রক্রিয়া করতে পারে)

তৃতীয়ত, আপনার কোড অনুকূল থেকে অনেক দূরে:

  • আপনি কাঁচা পয়েন্টার ব্যবহার করছেন, যার অর্থ কম্পাইলারটি ধরে নিতে পারে যে তারা উপনাম হতে পারে। সংকলক-নির্দিষ্ট কীওয়ার্ড বা পতাকা রয়েছে যা আপনি সংকলকটি বলতে পারেন যে তারা উপনাম নয়। বিকল্পভাবে, আপনার কাঁচা পয়েন্টার ছাড়া অন্য ধরণের ব্যবহার করা উচিত, যা সমস্যার যত্ন নেয়।
  • আপনি ইনপুট ম্যাট্রিক্সের প্রতিটি সারি / কলামের একটি নিষ্পাপ ট্র্যাভারসাল করে ক্যাশে ছিটকে যাচ্ছেন। পরবর্তী ব্লকে যাওয়ার আগে ম্যাট্রিক্সের একটি ছোট ব্লকে যথাসম্ভব কাজ করতে আপনি ব্লকিং ব্যবহার করতে পারেন, যা সিপিইউ ক্যাশে ফিট করে fits
  • খাঁটি অঙ্কের কাজগুলির জন্য, ফোর্টরান বেশ অপূরণীয়, এবং সি ++ অনুরূপ গতিতে উঠতে প্রচুর পরিমাণে কক্সিক্স লাগবে। এটি করা যেতে পারে এবং কয়েকটি গ্রন্থাগার এটি প্রদর্শন করে (সাধারণত অভিব্যক্তি টেম্পলেট ব্যবহার করে) তবে এটি তুচ্ছ নয়, এবং এটি কেবল ঘটে না ।

ধন্যবাদ, আমি জাস্টিকেলের পরামর্শ অনুযায়ী সঠিক কোড সীমাবদ্ধ করেছি, খুব বেশি উন্নতি দেখতে পাইনি, আমি ব্লকওয়াইজ ধারণা পছন্দ করি। কৌতূহলের বাইরে, সিপিইউ'র ক্যাশে আকার না জেনে কীভাবে একটি সঠিক কোড করবে?
ডিউসএডুরো

2
আপনি না। অনুকূল কোড পেতে, আপনার সিপিইউর ক্যাশে আকার জানতে হবে। অবশ্যই এর খারাপ দিকটি হ'ল আপনি সিপিইউ'র একটি পরিবারে সেরা পারফরম্যান্সের জন্য আপনার কোডটিকে কার্যকরভাবে হার্ডকড করছেন ।
জলফ

2
কমপক্ষে এখানে অভ্যন্তরীণ লুপটি স্ট্রেড লোডগুলি এড়িয়ে চলে। দেখে মনে হচ্ছে এটি ইতিমধ্যে স্থানান্তরিত হওয়া একটি ম্যাট্রিক্সের জন্য লেখা। এ কারণেই এটি BLAS এর চেয়ে ধীরে ধীরে মাত্রার একমাত্র ক্রম! তবে হ্যাঁ, ক্যাশে-ব্লকিংয়ের অভাবে এটি এখনও মারছে ra আপনি কি নিশ্চিত যে ফোর্টরান অনেক সাহায্য করবে? আমি মনে করি আপনি এখানে যা অর্জন করেছেন তা restrictহ'ল সি (সি) ++ এর বিপরীতে ডিফল্ট হোন (কোনও এলিয়াসিং নয়)। (এবং দুর্ভাগ্যক্রমে আইএসও সি ++ এর কোনও restrictকীওয়ার্ড নেই, সুতরাং আপনাকে __restrict__এটি সংযোজনকারীগুলিতে ব্যবহার করতে হবে যা এটি একটি এক্সটেনশান হিসাবে সরবরাহ করে)।
পিটার কর্ডস

11

আমি বিএলএএস বাস্তবায়ন সম্পর্কে স্পষ্টভাবে জানি না তবে ম্যাট্রিক্স গুণণের জন্য আরও দক্ষ অ্যালগরিদম রয়েছে যা ও (এন 3) জটিলতার চেয়ে ভাল। একটি ভাল জানেন স্ট্রেসেন অ্যালগোরিদম


8
স্ট্র্যাসেন অ্যালগরিদম দুটি কারণে সংখ্যায় ব্যবহৃত হয় না: 1) এটি স্থিতিশীল নয়। 2) আপনি কিছু গণনা সংরক্ষণ করেন কিন্তু সেই দামের সাথে আসে যা আপনি ক্যাশে শ্রেণিবিন্যাস শোষণ করতে পারেন। অনুশীলনে আপনি এমনকি কর্মক্ষমতা আলগা।
মাইকেল লেহন

4
বিএলএএস লাইব্রেরি উত্স কোডের উপর দৃly়ভাবে নির্মিত স্ট্র্যাসেন অ্যালগোরিদমের ব্যবহারিক বাস্তবায়নের জন্য একটি সাম্প্রতিক প্রকাশনা রয়েছে: এসসি 16 এ "স্ট্র্যাসেন অ্যালগরিদম রিলোডেড ", যা বিএলএএস এর চেয়ে উচ্চতর কর্মক্ষমতা অর্জন করে এমনকি সমস্যা আকার 1000x1000 এর জন্যও।
জিয়ানু হুয়াং

4

দ্বিতীয় প্রশ্নের বেশিরভাগ যুক্তি - এসেম্বেলার, ব্লকগুলিতে বিভক্ত হওয়া ইত্যাদি (তবে এন ^ 3 অ্যালগরিদমের চেয়ে কম নয়, তারা সত্যই অপ্রচলিত) - একটি ভূমিকা পালন করে। তবে আপনার অ্যালগরিদমের কম বেগ ম্যাট্রিক্স আকার এবং তিনটি নেস্টেড লুপের দুর্ভাগ্যজনক বিন্যাসের কারণে ঘটে caused আপনার ম্যাট্রিকগুলি এত বড় যে তারা ক্যাশে স্মৃতিতে একবারে ফিট করে না। আপনি লুপগুলি পুনরায় সাজিয়ে তুলতে পারেন যতটা সম্ভব ক্যাশে একটি সারিতে করা হবে, নাটকীয়ভাবে ক্যাশে রিফ্রেশকে হ্রাস করতে হবে (ছোট ব্লকে বিটিডব্লিউ বিভক্তকরণের সাথে একটি অ্যানালগ প্রভাব রয়েছে, সেরা যদি ব্লকের উপরের লুপগুলি একইভাবে সাজানো থাকে)। বর্গ ম্যাট্রিক্সের জন্য একটি মডেল বাস্তবায়ন নিম্নলিখিত। আমার কম্পিউটারে স্ট্যান্ডার্ড বাস্তবায়নের (আপনার হিসাবে) তুলনায় এর সময় খরচ প্রায় 1:10 ছিল। অন্য কথায়: "বরাবর কোনও ম্যাট্রিক্স গুণনের প্রোগ্রাম করবেন না"

    void vector(int m, double ** a, double ** b, double ** c) {
      int i, j, k;
      for (i=0; i<m; i++) {
        double * ci = c[i];
        for (k=0; k<m; k++) ci[k] = 0.;
        for (j=0; j<m; j++) {
          double aij = a[i][j];
          double * bj = b[j];
          for (k=0; k<m; k++)  ci[k] += aij*bj[k];
        }
      }
    }

আরও একটি মন্তব্য: BLAS রুটিন cblas_dgemm (আপনার কম্পিউটারে এটি চেষ্টা করুন!) দ্বারা প্রতিস্থাপনের চেয়ে এই প্রয়োগটি আমার কম্পিউটারে আরও ভাল। তবে আরও দ্রুত (1: 4) সরাসরি ফোর্টরান লাইব্রেরির ডিজিএমএম_কে কল করছে। আমি মনে করি এই রুটিনটি আসলে ফোর্টরান নয় বরং এসেম্বলারের কোড (লাইব্রেরিতে কী আছে আমি তা জানি না, উত্স নেই)। আমার কাছে পুরোপুরি অস্পষ্ট কারণ কেন আমার জ্ঞানের কাছে cblas_dgemm তত দ্রুত নয় কারণ এটি কেবল ডিজেএমএম_এর জন্য একটি মোড়ক।


3

এটি একটি বাস্তবসম্মত গতি। সি ++ কোডের মাধ্যমে সিমডি এসেম্বলারের সাথে কী করা যায় তার উদাহরণের জন্য দেখুন আইফোন ম্যাট্রিক্স ফাংশনগুলি দেখুন - এগুলি সি সংস্করণের চেয়ে 8x এর বেশি দ্রুত ছিল এবং এমনকি "অনুকূলিত" সমাবেশও নয় - এখনও পাইপ-আস্তরণ নেই there অপ্রয়োজনীয় স্ট্যাক অপারেশন।

এছাড়াও আপনার কোডটি " সীমাবদ্ধ সঠিক " নয় - সংকলকটি কীভাবে জানতে পারে যে যখন এটি সি সংশোধন করে, তখন এটি এ এবং বি সংশোধন করে না?


আপনি যদি মিম্বল্ট (এ ..., এ ..., এ) এর মতো ফাংশনটি ডাকেন তবে অবশ্যই; আপনি অবশ্যই প্রত্যাশিত ফলাফল পাবেন না। আবার যদিও আমি বিএলএএসকে পরাজিত / পুনরায় বাস্তবায়ন করার চেষ্টা করছিলাম না, ঠিক কতটা তত দ্রুত তা দেখে তাই ত্রুটি পরীক্ষা করা মনের মধ্যে ছিল না, কেবলমাত্র প্রাথমিক কার্যকারিতা।
DeusAduro

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

@ ডিউসএডুরো: এটি পরীক্ষা করা ত্রুটি নয় - এটি সম্ভব যে সংকলকটি অভ্যন্তরীণ লুপের বি [] অ্যারেতে অ্যাক্সেসগুলি অপ্টিমাইজ করতে অক্ষম কারণ এটি এবং সি পয়েন্টারগুলি কখনই বি নামটি উপস্থাপন করে না তা নির্ধারণ করতে সক্ষম হতে পারে অ্যারে। যদি এলিয়াসিং থাকে তবে অভ্যন্তরীণ লুপটি কার্যকর হওয়ার সময় বি অ্যারেটির মান পরিবর্তন করা সম্ভব হবে। অভ্যন্তরীণ লুপের বাইরে বি [] মানটির অ্যাক্সেস উত্তোলন এবং স্থানীয় ভেরিয়েবলের মধ্যে রাখলে সংকলকটি বিতে নিয়মিত অ্যাক্সেস এড়াতে সক্ষম হতে পারে []।
মাইকেল

1
হুম, সুতরাং আমি প্রথমে ভিএস ২০০৮-তে '__restrict' কীওয়ার্ডটি ব্যবহার করে চেষ্টা করেছি, এ, বি এবং সি প্রয়োগ করেছি এটি ফলাফলটিতে কোনও পরিবর্তন দেখায়নি। তবে বি এর অ্যাক্সেসকে সর্বাধিক লুপ থেকে বাইরে লুপের দিকে নিয়ে যাওয়া সময়কে 10 ডলার দ্বারা উন্নত করেছে।
DeusAduro

1
দুঃখিত, আমি ভিসি সম্পর্কে নিশ্চিত নই, তবে জিসিসির সাথে আপনাকে সক্ষম করতে হবে -fstrict-aliasing। এখানে "সীমাবদ্ধ" এর আরও ভাল ব্যাখ্যা রয়েছে: সেল্পার
পারফরম্যান্স.বিইন্ড 3

2

এমএম গুণায় মূল কোডটি সম্পর্কে শ্রদ্ধা জানায়, বেশিরভাগ অপারেশনের জন্য মেমরি রেফারেন্সটি খারাপ পারফরম্যান্সের মূল কারণ। মেমরিটি ক্যাশের তুলনায় 100-1000 গুণ বেশি ধীর গতিতে চলছে।

এমপি গুণায় এই ট্রিপল লুপ ফাংশনটির জন্য লুপ অপ্টিমাইজেশান কৌশলগুলি নিয়োগ করা থেকে বেশিরভাগ গতি আসে। দুটি প্রধান লুপ অপ্টিমাইজেশান কৌশল ব্যবহৃত হয়; আনরোলিং এবং ব্লক করা। তালিকাভুক্তির বিষয়ে আমরা বাইরের দুটি সর্বাধিক লুপগুলি তালিকাভুক্ত করেছি এবং ক্যাশে ডেটা পুনঃব্যবহারের জন্য এটি অবরোধ করি। আউটার লুপ আন্রোলিং পুরো অপারেশন চলাকালীন সময়ে বিভিন্ন সময়ে একই ডেটাতে মেমরি রেফারেন্সের সংখ্যা হ্রাস করে অস্থায়ীভাবে ডেটা-অ্যাক্সেসকে অনুকূল করতে সহায়তা করে। নির্দিষ্ট সংখ্যায় লুপ সূচকটি ব্লক করা ক্যাশে থাকা ডেটা ধরে রাখতে সহায়তা করে। আপনি L2 ক্যাশে বা L3 ক্যাশে অনুকূল করতে বেছে নিতে পারেন।

https://en.wikipedia.org/wiki/Loop_nest_optimization


-24

অনেক কারণে.

প্রথমত, ফোর্টরান সংকলকগুলি অত্যন্ত অপ্টিমাইজ করা হয় এবং ভাষা তাদেরকে এ জাতীয় হতে দেয়। সি এবং সি ++ অ্যারে হ্যান্ডলিংয়ের ক্ষেত্রে খুব আলগা হয় (যেমন একই মেমরির ক্ষেত্রের উল্লেখ করে পয়েন্টারগুলির ক্ষেত্রে)। এর অর্থ এই যে সংকলকটি আগে থেকে কী করতে হবে তা জানতে পারে না এবং জেনেরিক কোড তৈরি করতে বাধ্য হয়। ফোর্টরানে আপনার কেসগুলি আরও প্রবাহিত হয় এবং সংকলকটির কী ঘটে তার আরও ভাল নিয়ন্ত্রণ থাকে যা তাকে আরও অনুকূলিতকরণের অনুমতি দেয় (যেমন নিবন্ধগুলি ব্যবহার করে)।

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

তৃতীয়ত, এটি আপনি ব্যবহার করছেন ব্লেস বাস্তবায়নের উপর নির্ভর করে। কিছু বাস্তবায়ন এসেম্বলারে লেখা হতে পারে এবং আপনি যে নির্দিষ্ট প্রসেসরটি ব্যবহার করছেন তার জন্য অনুকূলিত হতে পারে। নেটলিব সংস্করণটি fort 77 ফোরআরে লেখা আছে।

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

উদাহরণস্বরূপ, আপনি আপনার কোডটি এভাবে পুনরায় কাজ করতে পারেন

template<class ValT>
void mmult(const ValT* A, int ADim1, int ADim2, const ValT* B, int BDim1, int BDim2, ValT* C)
{
if ( ADim2!=BDim1 ) throw std::runtime_error("Error sizes off");

memset((void*)C,0,sizeof(ValT)*ADim1*BDim2);
int cc2,cc1,cr1, a1,a2,a3;
for ( cc2=0 ; cc2<BDim2 ; ++cc2 ) {
    a1 = cc2*ADim2;
    a3 = cc2*BDim1
    for ( cc1=0 ; cc1<ADim2 ; ++cc1 ) {
          a2=cc1*ADim1;
          ValT b = B[a3+cc1];
          for ( cr1=0 ; cr1<ADim1 ; ++cr1 ) {
                    C[a1+cr1] += A[a2+cr1]*b;
           }
     }
  }
} 

এটি চেষ্টা করে দেখুন, আমি নিশ্চিত আপনি কিছু সংরক্ষণ করবেন।

আপনার # 1 প্রশ্নের, কারণটি হল যদি আপনি একটি তুচ্ছ অ্যালগরিদম ব্যবহার করেন তবে ম্যাট্রিক্সের গুণকে O (n ^ 3) হিসাবে স্কেল করে। আরও ভাল স্কেল যে অ্যালগরিদম আছে ।


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

10
হ্যাঁ, এই উত্তর হয় সম্পূর্ণ ভুল। দুর্ভাগ্যক্রমে এটি সাধারণ জ্ঞানহীনতায় পূর্ণ, উদাহরণস্বরূপ দাবিটি ফোরট্রানের কারণে দ্রুত ছিল। 20 (!) ইতিবাচক রেটিং পাওয়া খারাপ জিনিস। স্ট্যাকওভারফ্লোটির জনপ্রিয়তার কারণে এখন এই অজ্ঞানতা আরও ছড়িয়ে পড়ে!
মাইকেল লেহন

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

5
@KyleKanos: হ্যাঁ, এখানে এটলাস উৎস: sourceforge.net/projects/math-atlas/files/Stable/3.10.1 যতদূর আমি জানি এটা সবচেয়ে বেশি ব্যবহৃত ওপেন সোর্স পোর্টেবল Blas বাস্তবায়ন। এটি সি / এএসএম-তে লেখা আছে। ইন্টেলের মতো উচ্চ কার্যকারিতা সিপিইউ নির্মাতারা তাদের চিপগুলির জন্য বিশেষত অনুকূলিত করে বিএলএএস বাস্তবায়ন সরবরাহ করে। আমি গ্যারান্টি দিচ্ছি যে ইনটেলস লাইব্রেরির নিম্ন স্তরের অংশগুলি (duuh) x86 সমাবেশে লেখা আছে এবং আমি নিশ্চিত যে মধ্য স্তরের অংশগুলি সি বা সি ++ এ লেখা হবে in
অ্যান্ড্রু তোমাজোস

9
@ কাইলক্যানোস: আপনি বিভ্রান্ত নেটলিব বিএলএএস হ'ল রেফারেন্স বাস্তবায়ন। রেফারেন্স বাস্তবায়ন অনুকূলিত বাস্তবায়নগুলির তুলনায় অনেক ধীর ( পারফরম্যান্স তুলনা দেখুন )। যখন কেউ বলে যে তারা একটি ক্লাস্টারে নেটলিব বিএলএএস ব্যবহার করছে, তার অর্থ এই নয় যে তারা আসলে নেটলিব রেফারেন্স বাস্তবায়ন ব্যবহার করছে। এটা ঠিক নির্বোধ হবে। এর অর্থ হ'ল তারা নেটলিব ব্লেসের মতো একই ইন্টারফেসের সাথে একটি lib ব্যবহার করছে।
অ্যান্ড্রু তোমাজস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.