এই নিবন্ধটির লক্ষ্য হল কম্পাইলার অপ্টিমাইজেশানের ক্ষমতাকে স্পটলাইট করা, Intel C++ কম্পাইলারগুলির উপর ফোকাস করা — যা তাদের জনপ্রিয়তা এবং ব্যাপক ব্যবহারের জন্য বিখ্যাত।
হাইলাইটস: কম্পাইলার অপটিমাইজেশন কি? | -চালু | আর্কিটেকচার টার্গেটেড | আন্তঃপ্রক্রিয়াগত অপ্টিমাইজেশান | -fno-আলিয়াসিং | কম্পাইলার অপ্টিমাইজেশান রিপোর্ট
যেকোনো কম্পাইলার উচ্চ-স্তরের সোর্স কোডকে নিম্ন-স্তরের মেশিন কোডে রূপান্তর করার জন্য ধাপগুলির একটি সিরিজ সম্পাদন করে। এর মধ্যে আভিধানিক বিশ্লেষণ, সিনট্যাক্স বিশ্লেষণ, শব্দার্থিক বিশ্লেষণ, মধ্যবর্তী কোড জেনারেশন (বা আইআর), অপ্টিমাইজেশান এবং কোড জেনারেশন জড়িত।
অপ্টিমাইজেশান পর্বের সময়, কম্পাইলার সতর্কতার সাথে একটি প্রোগ্রামকে রূপান্তর করার উপায় অনুসন্ধান করে, একটি শব্দার্থকভাবে সমতুল্য আউটপুট যা কম সংস্থান ব্যবহার করে বা আরও দ্রুত কার্যকর করে। এই প্রক্রিয়ায় নিযুক্ত কৌশলগুলি অন্তর্ভুক্ত করে তবে ধ্রুবক ভাঁজ, লুপ অপ্টিমাইজেশান, ফাংশন ইনলাইনিং এবং ডেড কোড নির্মূলের মধ্যে সীমাবদ্ধ নয়।
বিকাশকারীরা সংকলন প্রক্রিয়া চলাকালীন কম্পাইলার ফ্ল্যাগের একটি সেট নির্দিষ্ট করতে পারে, একটি অনুশীলন যারা ডিবাগিং এবং প্রোফাইলিং তথ্যের জন্য GCC এর সাথে " -g" বা "-pg" এর মতো বিকল্পগুলি ব্যবহার করে তাদের কাছে পরিচিত। আমরা যতই এগিয়ে যাব, আমরা একই ধরনের কম্পাইলার ফ্ল্যাগ নিয়ে আলোচনা করব যা আমরা Intel C++ কম্পাইলারের সাথে আমাদের অ্যাপ্লিকেশন কম্পাইল করার সময় ব্যবহার করতে পারি। এগুলি আপনাকে আপনার কোডের দক্ষতা এবং কর্মক্ষমতা উন্নত করতে সাহায্য করতে পারে৷
u(x,y,t) হল বিন্দুতে (x,y) টি সময়ে তাপমাত্রা।
আমাদের কাছে মূলত একটি C++ কোডিং আছে যা পরিবর্তনশীল আকারের গ্রিডে জ্যাকোবি পুনরাবৃত্তি করে (যাকে আমরা রেজোলিউশন বলি)। মূলত, 500 এর একটি গ্রিড আকার মানে 500x500 আকারের একটি ম্যাট্রিক্স সমাধান করা ইত্যাদি।
/* * One Jacobi iteration step */ void jacobi(double *u, double *unew, unsigned sizex, unsigned sizey) { int i, j; for (j = 1; j < sizex - 1; j++) { for (i = 1; i < sizey - 1; i++) { unew[i * sizex + j] = 0.25 * (u[i * sizex + (j - 1)] + // left u[i * sizex + (j + 1)] + // right u[(i - 1) * sizex + j] + // top u[(i + 1) * sizex + j]); // bottom } } for (j = 1; j < sizex - 1; j++) { for (i = 1; i < sizey - 1; i++) { u[i * sizex + j] = unew[i * sizex + j]; } } }
MFLOP/s মানে "মিলিয়ন ফ্লোটিং পয়েন্ট অপারেশন পার সেকেন্ড।" এটি ফ্লোটিং-পয়েন্ট অপারেশনের পরিপ্রেক্ষিতে একটি কম্পিউটার বা প্রসেসরের কর্মক্ষমতা পরিমাপ করতে ব্যবহৃত পরিমাপের একক। ফ্লোটিং-পয়েন্ট ক্রিয়াকলাপগুলি একটি ভাসমান-বিন্দু বিন্যাসে উপস্থাপিত দশমিক বা বাস্তব সংখ্যা সহ গাণিতিক গণনা জড়িত।
দ্রষ্টব্য 1: একটি স্থিতিশীল ফলাফল প্রদান করতে, আমি প্রতিটি রেজোলিউশনের জন্য 5 বার এক্সিকিউটেবল চালাই এবং MFLOP/s মানের গড় মান নিই।
নোট 2: এটা মনে রাখা গুরুত্বপূর্ণ যে Intel C++ কম্পাইলারের ডিফল্ট অপ্টিমাইজেশান হল -O2। সুতরাং, সোর্স কোড কম্পাইল করার সময় -O0 উল্লেখ করা গুরুত্বপূর্ণ।
যখন কেউ কম্পাইলার অপ্টিমাইজেশন দিয়ে শুরু করে তখন এগুলি সবচেয়ে বেশি ব্যবহৃত কিছু কম্পাইলার ফ্ল্যাগ। একটি আদর্শ ক্ষেত্রে, Ofast > O3 > O2 > O1 > O0 এর কর্মক্ষমতা। যাইহোক, এটি অগত্যা ঘটবে না। এই বিকল্পগুলির সমালোচনামূলক পয়েন্টগুলি নিম্নরূপ:
-O1:
-O2:
-O3:
-অফাস্ট:
এটা স্পষ্টভাবে প্রতীয়মান যে এই সমস্ত অপ্টিমাইজেশন আমাদের বেস কোডের ("-O0" সহ) থেকে অনেক দ্রুত। এক্সিকিউশন রান টাইম বেস কেসের চেয়ে 2-3x কম। MFLOP/s সম্পর্কে কি??
সামগ্রিকভাবে, যদিও সামান্য হলেও, “-O3” সেরা পারফর্ম করে।
“- Ofast ” (“ -no-prec-div -fp-model fast=2 ”) দ্বারা ব্যবহৃত অতিরিক্ত ফ্ল্যাগগুলি কোনও অতিরিক্ত গতি দেয় না।
উত্তরটি কৌশলগত কম্পাইলার পতাকাগুলিতে রয়েছে। " -xHost " এবং আরও স্পষ্টভাবে বললে, " -xCORE-AVX512 " এর মতো বিকল্পগুলির সাথে পরীক্ষা করা আমাদেরকে মেশিনের ক্ষমতার সম্পূর্ণ সম্ভাবনা এবং সর্বোত্তম কর্মক্ষমতার জন্য টেইলার অপ্টিমাইজেশানগুলিকে কাজে লাগাতে দেয়৷
-xHost:
-xCORE-AVX512:
লক্ষ্য: ইন্টেল অ্যাডভান্সড ভেক্টর এক্সটেনশন 512 (AVX-512) নির্দেশ সেট ব্যবহার করে এমন কোড তৈরি করতে কম্পাইলারকে স্পষ্টভাবে নির্দেশ দিন।
মূল বৈশিষ্ট্য: AVX-512 হল একটি উন্নত SIMD (একক নির্দেশনা, একাধিক ডেটা) নির্দেশনা সেট যা AVX2 এর মতো পূর্ববর্তী সংস্করণের তুলনায় ব্যাপক ভেক্টর রেজিস্টার এবং অতিরিক্ত ক্রিয়াকলাপ অফার করে। এই ফ্ল্যাগটি সক্রিয় করা কম্পাইলারকে অপ্টিমাইজ করা পারফরম্যান্সের জন্য এই উন্নত বৈশিষ্ট্যগুলিকে লিভারেজ করার অনুমতি দেয়।
বিবেচনা: পোর্টেবিলিটি আবার এখানে অপরাধী। AVX-512 নির্দেশাবলীর সাহায্যে তৈরি করা বাইনারিগুলি এই নির্দেশ সেট সমর্থন করে না এমন প্রসেসরগুলিতে সর্বোত্তমভাবে চলতে পারে না। তারা মোটেও কাজ নাও করতে পারে!
ডিফল্টরূপে, “ -xCORE-AVX512 ” অনুমান করে যে প্রোগ্রামটি zmm রেজিস্টার ব্যবহার থেকে উপকৃত হবে না। কম্পাইলার zmm রেজিস্টার ব্যবহার করা এড়িয়ে যায় যদি না পারফরম্যান্স লাভ নিশ্চিত করা হয়।
যদি কেউ সীমাবদ্ধতা ছাড়াই zmm রেজিস্টার ব্যবহার করার পরিকল্পনা করে, " " উচ্চ সেট করা যেতে পারে। যে আমরা হিসাবে ভাল করা হবে কি.
উহু!
উল্লেখযোগ্য অংশটি হল যে আমরা এই ফলাফলগুলি কোনও উল্লেখযোগ্য ম্যানুয়াল হস্তক্ষেপ ছাড়াই অর্জন করেছি - কেবলমাত্র অ্যাপ্লিকেশন সংকলন প্রক্রিয়া চলাকালীন মুষ্টিমেয় কম্পাইলার ফ্ল্যাগগুলি অন্তর্ভুক্ত করে।
দ্রষ্টব্য: আপনার হার্ডওয়্যার AVX-512 সমর্থন না করলে চিন্তা করবেন না। Intel C++ কম্পাইলার AVX, AVX-2 এমনকি SSE-এর জন্য অপ্টিমাইজেশন সমর্থন করে। আপনার জানা প্রয়োজন সবকিছু আছে!
আইপিও একটি বহু-পদক্ষেপ প্রক্রিয়া যা একটি প্রোগ্রামের মধ্যে বিভিন্ন ফাংশন বা পদ্ধতির মধ্যে মিথস্ক্রিয়াকে কেন্দ্র করে। IPO-তে ফরওয়ার্ড প্রতিস্থাপন, পরোক্ষ কল রূপান্তর এবং ইনলাইনিং সহ বিভিন্ন ধরণের অপ্টিমাইজেশন অন্তর্ভুক্ত থাকতে পারে।
-আইপিও:
লক্ষ্য: আন্তঃপ্রক্রিয়াগত অপ্টিমাইজেশান সক্ষম করে, কম্পাইলারকে কম্পাইলেশনের সময় পৃথক সোর্স ফাইলের বাইরে সমগ্র প্রোগ্রামটি বিশ্লেষণ এবং অপ্টিমাইজ করার অনুমতি দেয়।
মূল বৈশিষ্ট্য:- পুরো প্রোগ্রাম অপ্টিমাইজেশান: “ -ipo ” সমগ্র প্রোগ্রাম জুড়ে ফাংশন এবং পদ্ধতির মধ্যে মিথস্ক্রিয়া বিবেচনা করে সমস্ত উৎস ফাইল জুড়ে বিশ্লেষণ এবং অপ্টিমাইজেশান সঞ্চালন করে।- ক্রস-ফাংশন এবং ক্রস-মডিউল অপ্টিমাইজেশান: ফ্ল্যাগ ইনলাইনিং ফাংশন, সিঙ্ক্রোনাইজেশনকে সহজ করে। অপ্টিমাইজেশন, এবং বিভিন্ন প্রোগ্রাম অংশ জুড়ে ডেটা প্রবাহ বিশ্লেষণ।
বিবেচনা: এটি একটি পৃথক লিঙ্ক পদক্ষেপ প্রয়োজন. “ -ipo ” দিয়ে কম্পাইল করার পর, চূড়ান্ত এক্সিকিউটেবল তৈরি করার জন্য একটি নির্দিষ্ট লিঙ্ক ধাপ প্রয়োজন। কম্পাইলার লিঙ্ক করার সময় পুরো প্রোগ্রাম ভিউ এর উপর ভিত্তি করে অতিরিক্ত অপ্টিমাইজেশান সঞ্চালন করে।
-আইপি:
লক্ষ্য: আন্তঃপ্রক্রিয়াগত বিশ্লেষণ-প্রসারণ সক্ষম করে, কম্পাইলারকে একটি পৃথক লিঙ্ক পদক্ষেপের প্রয়োজন ছাড়াই কিছু আন্তঃপ্রক্রিয়াগত অপ্টিমাইজেশন সঞ্চালনের অনুমতি দেয়।
মূল বৈশিষ্ট্য:- বিশ্লেষণ এবং প্রচার: “ -ip ” কম্পাইলেশনের সময় বিভিন্ন ফাংশন এবং মডিউল জুড়ে গবেষণা এবং ডেটা প্রচার করতে সক্ষম করে। যাইহোক, এটি সমস্ত অপ্টিমাইজেশান সঞ্চালন করে না যার জন্য সম্পূর্ণ প্রোগ্রাম ভিউ প্রয়োজন।- দ্রুত সংকলন: “ -ipo ” এর বিপরীতে, “ -ip ”-এর জন্য আলাদা লিঙ্কিং ধাপের প্রয়োজন হয় না, ফলে দ্রুত সংকলনের সময় হয়। এটি বিকাশের সময় উপকারী হতে পারে যখন দ্রুত প্রতিক্রিয়া অপরিহার্য।
বিবেচনা: ফাংশন ইনলাইনিং সহ শুধুমাত্র কিছু সীমিত আন্তঃপ্রক্রিয়াগত অপ্টিমাইজেশান ঘটে।
-ipo সাধারণত আরও ব্যাপক আন্তঃপ্রক্রিয়াগত অপ্টিমাইজেশান ক্ষমতা প্রদান করে কারণ এটি একটি পৃথক লিঙ্ক পদক্ষেপ জড়িত কিন্তু দীর্ঘ সংকলন সময়ের খরচে আসে। [ ] -ip একটি দ্রুত বিকল্প যা কিছু আন্তঃপ্রক্রিয়াগত অপ্টিমাইজেশান সঞ্চালন একটি পৃথক লিঙ্ক পদক্ষেপের প্রয়োজন ছাড়াই, এটিকে উন্নয়ন এবং পরীক্ষার পর্যায়গুলির জন্য উপযুক্ত করে তোলে।
যেহেতু আমরা শুধুমাত্র পারফরম্যান্স এবং বিভিন্ন অপ্টিমাইজেশান, কম্পাইল টাইম বা এক্সিকিউটেবলের সাইজ নিয়ে কথা বলছি, তাই আমরা " -ipo " এর উপর ফোকাস করব।
/* * One Jacobi iteration step */ void jacobi(double *u, double *unew, unsigned sizex, unsigned sizey) { int i, j; for (j = 1; j < sizex - 1; j++) { for (i = 1; i < sizey - 1; i++) { unew[i * sizex + j] = 0.25 * (u[i * sizex + (j - 1)] + // left u[i * sizex + (j + 1)] + // right u[(i - 1) * sizex + j] + // top u[(i + 1) * sizex + j]); // bottom } } for (j = 1; j < sizex - 1; j++) { for (i = 1; i < sizey - 1; i++) { u[i * sizex + j] = unew[i * sizex + j]; } } }
jacobi() ফাংশন পরামিতি হিসাবে দ্বিগুণ করতে কয়েকটি পয়েন্টার নেয় এবং তারপর লুপগুলির জন্য নেস্টেডের ভিতরে কিছু করে। যেকোন কম্পাইলার যখন সোর্স ফাইলে এই ফাংশনটি দেখে, তখন তাকে খুব সতর্ক থাকতে হয়।
u ব্যবহার করে unew গণনা করার অভিব্যক্তিতে 4টি প্রতিবেশী u মানের গড় জড়িত। যদি u এবং unew উভয়ই একই অবস্থানে নির্দেশ করে? এটি উপনামযুক্ত পয়েন্টারগুলির ক্লাসিক্যাল সমস্যা হয়ে উঠবে [ ]।
আধুনিক কম্পাইলাররা খুব স্মার্ট এবং নিরাপত্তা নিশ্চিত করার জন্য, তারা ধরে নেয় যে অ্যালিয়াসিং সম্ভব হতে পারে। এবং এই ধরনের পরিস্থিতির জন্য, তারা শব্দার্থবিদ্যা এবং কোডের আউটপুটকে প্রভাবিত করতে পারে এমন কোনো অপ্টিমাইজেশন এড়িয়ে চলে।
আমাদের ক্ষেত্রে, আমরা জানি যে u এবং unew বিভিন্ন মেমরি অবস্থান এবং বিভিন্ন মান সঞ্চয় করার উদ্দেশ্যে। সুতরাং, আমরা সহজেই কম্পাইলারকে জানাতে পারি যে এখানে কোনো অ্যালিয়াসিং হবে না।
দুটি পদ্ধতি আছে। প্রথমে সি “ ” কীওয়ার্ড । কিন্তু এটি কোড পরিবর্তন প্রয়োজন. আমরা আপাতত সেটা চাই না।
সহজ কিছু? আসুন " -fno-alias " চেষ্টা করি।
-fno-উনাফে:
লক্ষ্য: কম্পাইলারকে নির্দেশ দিন যাতে প্রোগ্রামে অ্যালিয়াসিং না হয়।
মূল বৈশিষ্ট্য: কোনো অ্যালিয়াসিং না করে অনুমান করে, কম্পাইলার আরও অবাধে কোডটিকে অপ্টিমাইজ করতে পারে, সম্ভাব্য কর্মক্ষমতা উন্নত করতে পারে।
বিবেচ্য বিষয়: বিকাশকারীকে এই পতাকাটি ব্যবহার করার ক্ষেত্রে সতর্ক থাকতে হবে কারণ কোনো অনাকাঙ্ক্ষিত নামকরণের ক্ষেত্রে, প্রোগ্রামটি অপ্রত্যাশিত আউটপুট দিতে পারে।
আচ্ছা, এখন আমাদের কিছু আছে!!!
অ্যাসেম্বলি কোডের (যদিও এখানে শেয়ার করা হয়নি) এবং জেনারেট করা কম্পাইল অপ্টিমাইজেশান রিপোর্টের ( নীচে দেখুন) একটি ঘনিষ্ঠ পরীক্ষা কম্পাইলারের এবং এর বুদ্ধিমান প্রয়োগ প্রকাশ করে। এই রূপান্তরগুলি একটি অত্যন্ত অপ্টিমাইজ করা কর্মক্ষমতাতে অবদান রাখে, কোড দক্ষতার উপর কম্পাইলার নির্দেশাবলীর উল্লেখযোগ্য প্রভাব প্রদর্শন করে।
Intel C++ কম্পাইলার একটি মূল্যবান বৈশিষ্ট্য প্রদান করে যা ব্যবহারকারীদের একটি অপ্টিমাইজেশান রিপোর্ট তৈরি করতে দেয় যা অপ্টিমাইজেশানের উদ্দেশ্যে করা সমস্ত সমন্বয়ের সংক্ষিপ্তসার করে [ ]। এই বিস্তৃত প্রতিবেদনটি YAML ফাইল ফরম্যাটে সংরক্ষিত হয়েছে, কোডের মধ্যে কম্পাইলার দ্বারা প্রয়োগ করা অপ্টিমাইজেশনের একটি বিস্তারিত তালিকা উপস্থাপন করে। একটি বিশদ বিবরণের জন্য, “ ”-এ অফিসিয়াল ডকুমেন্টেশন দেখুন।
একইভাবে, ইন্টেল সি++ কম্পাইলার (এবং সব জনপ্রিয়) প্রাগমা নির্দেশকেও সমর্থন করে, যা খুবই চমৎকার বৈশিষ্ট্য। ivdep, সমান্তরাল, simd, ভেক্টর ইত্যাদির মতো কিছু প্র্যাগমা পরীক্ষা করা মূল্যবান।