আপনি শাখার পূর্বাভাস ব্যর্থতার শিকার ।
শাখার ভবিষ্যদ্বাণী কী?
একটি রেলপথ জংশন বিবেচনা করুন:
উইকিমিডিয়া কমন্সের মাধ্যমে মেকানিজমোর ছবি । সিসি-বাই-এসএ 3.0 লাইসেন্সের আওতায় ব্যবহৃত ।
যুক্তির স্বার্থে, ধরুন এটি দীর্ঘ দূরত্ব বা রেডিও যোগাযোগের আগে - 1800 এর দশকে ফিরে এসেছে।
আপনি কোনও জংশনের অপারেটর এবং আপনি শুনতে পাচ্ছেন একটি ট্রেন আসছে। কোন পথে যাওয়ার কথা তা আপনার কোনও ধারণা নেই। আপনি ড্রাইভারকে কোন দিকে যেতে চান তা জিজ্ঞাসা করার জন্য আপনি ট্রেন থামিয়েছেন। এবং তারপরে আপনি যথাযথভাবে স্যুইচটি সেট করলেন।
ট্রেনগুলি ভারী এবং প্রচুর জড়তা রয়েছে। তাই তারা শুরু করতে এবং ধীর হয়ে যেতে চিরকালের জন্য নেয়।
একটি ভাল উপায় আছে কি? আপনি অনুমান করুন ট্রেনটি কোন দিকে যাবে!
- আপনি যদি সঠিক অনুমান করেন তবে এটি অবিরত থাকবে।
- আপনি যদি ভুল অনুমান করে থাকেন তবে ক্যাপ্টেন থামবেন, ব্যাক আপ করবেন এবং স্যুইচটি সরিয়ে ফেলার জন্য আপনাকে চিৎকার করবেন। তারপরে এটি অন্য পথটি আবার চালু করতে পারে।
আপনি যদি প্রতিবার ঠিক মতো অনুমান করেন তবে ট্রেনটি কখনও থামতে হবে না।
আপনি যদি খুব ঘন ঘন ভুল অনুমান করেন, ট্রেন থামাতে, ব্যাক আপ করতে এবং পুনরায় চালু করতে প্রচুর সময় ব্যয় করবে।
একটি বিবৃতি বিবেচনা করুন: প্রসেসর স্তরে, এটি একটি শাখা নির্দেশ:
আপনি একটি প্রসেসর এবং আপনি একটি শাখা দেখতে। কোন পথে যাবে তা আপনার কোনও ধারণা নেই। আপনি কি করেন? আপনি কার্যকর করা বন্ধ করে দিন এবং পূর্ববর্তী নির্দেশাবলী সম্পূর্ণ না হওয়া পর্যন্ত অপেক্ষা করুন। তারপরে আপনি সঠিক পথে চালিয়ে যান।
আধুনিক প্রসেসরগুলি জটিল এবং দীর্ঘ পাইপলাইন রয়েছে। সুতরাং তারা "উষ্ণতা" এবং "ধীর গতিতে" চিরকাল নিয়ে যায়।
একটি ভাল উপায় আছে কি? আপনি অনুমান করেন যে শাখাটি কোন দিকে যাবে!
- আপনি যদি সঠিক অনুমান করেন তবে আপনি চালিয়ে যান।
- আপনি যদি ভুল অনুমান করেন তবে আপনাকে পাইপলাইনটি ফ্লাশ করে শাখায় ফিরে যেতে হবে। তারপরে আপনি অন্য পথটি আবার চালু করতে পারেন।
আপনি যদি প্রতিবার ঠিক মতো অনুমান করেন , মৃত্যুদণ্ড কার্যকর করা কখনই থামবে না।
যদি আপনি খুব ঘন ঘন ভুল অনুমান করেন তবে আপনি স্টলিং, পিছন ফিরে এবং পুনরায় চালু করতে প্রচুর সময় ব্যয় করেন।
এটি শাখার পূর্বাভাস। আমি স্বীকার করি এটি সর্বোত্তম উপমা নয় কারণ ট্রেনটি কেবল একটি পতাকা দিয়ে দিকটি নির্দেশ করতে পারে। তবে কম্পিউটারগুলিতে প্রসেসর জানে না কোন শাখাটি শেষ মুহুর্ত পর্যন্ত কোন দিকে যাবে।
সুতরাং আপনি কীভাবে কৌশলগতভাবে অনুমান করতে পারবেন যে ট্রেনটি ব্যাক আপ করতে এবং অন্যান্য পথে নামতে হবে তার সংখ্যা কত বার কমাতে হবে? আপনি অতীত ইতিহাস তাকান! যদি ট্রেনটি 99% সময়ের মধ্যে চলে যায় তবে আপনি অনুমান করেন যে বাম। যদি এটি বিকল্প হয়, তবে আপনি আপনার অনুমানগুলি বিকল্প করুন। যদি এটি প্রতি তিনবার একবারে যায়, আপনি একই অনুমান করুন ...
অন্য কথায়, আপনি কোনও প্যাটার্ন সনাক্ত করতে এবং এটি অনুসরণ করার চেষ্টা করেন। এটি শাখার ভবিষ্যদ্বাণীকারীরা কীভাবে কাজ করে তা কমবেশি।
বেশিরভাগ অ্যাপ্লিকেশনগুলিতে ভাল আচরণ করা শাখা রয়েছে। সুতরাং আধুনিক শাখার ভবিষ্যদ্বাণীকারীরা সাধারণত 90% হিট রেট অর্জন করতে পারে। কিন্তু যখন কোন অননুমোদিত শাখাগুলির সাথে কোনও স্বীকৃতিযোগ্য নিদর্শন ছাড়াই सामना করা হয়, তখন শাখার ভবিষ্যদ্বাণীকারীগুলি কার্যত অকেজো।
আরও পঠন: উইকিপিডিয়াতে "ব্রাঞ্চের ভবিষ্যদ্বাণী" নিবন্ধ ।
উপর থেকে ইঙ্গিত হিসাবে, দোষী এই যদি বিবৃতি:
if (data[c] >= 128)
sum += data[c];
লক্ষ্য করুন যে ডেটা 0 এবং 255 এর মধ্যে সমানভাবে বিতরণ করা হয়েছে the এর পরে, তারা সকলেই if-বিবৃতি প্রবেশ করবে।
এটি শাখার ভবিষ্যদ্বাণীকারীর পক্ষে খুব বন্ধুত্বপূর্ণ কারণ শাখাটি ক্রমাগত একই দিকে বহুবার চলে। এমনকি একটি সাধারণ স্যাচুরেটিং কাউন্টার দিকটি স্যুইচ করার পরে কয়েকটি পুনরাবৃত্তি বাদ দিয়ে শাখাকে সঠিকভাবে ভবিষ্যদ্বাণী করবে।
দ্রুত দৃশ্যায়ন:
T = branch taken
N = branch not taken
data[] = 0, 1, 2, 3, 4, ... 126, 127, 128, 129, 130, ... 250, 251, 252, ...
branch = N N N N N ... N N T T T ... T T T ...
= NNNNNNNNNNNN ... NNNNNNNTTTTTTTTT ... TTTTTTTTTT (easy to predict)
যাইহোক, যখন ডেটা সম্পূর্ণরূপে এলোমেলো হয়, তখন শাখার ভবিষ্যদ্বাণীটি অকেজো হয়ে যায়, কারণ এটি এলোমেলো ডেটা পূর্বাভাস দিতে পারে না। সুতরাং সম্ভবত প্রায় 50% ভুল ধারণা করা হবে (এলোমেলো অনুমানের চেয়ে ভাল)।
data[] = 226, 185, 125, 158, 198, 144, 217, 79, 202, 118, 14, 150, 177, 182, 133, ...
branch = T, T, N, T, T, T, T, N, T, N, N, T, T, T, N ...
= TTNTTTTNTNNTTTN ... (completely random - hard to predict)
তাহলে কি করা উচিত?
যদি সংকলক শর্তাধীন পদক্ষেপে শাখাটিকে অনুকূল করতে সক্ষম না হয়, আপনি যদি পারফরম্যান্সের জন্য পাঠযোগ্যতার ত্যাগ করতে চান তবে আপনি কিছু হ্যাক চেষ্টা করতে পারেন।
প্রতিস্থাপন করুন:
if (data[c] >= 128)
sum += data[c];
সঙ্গে:
int t = (data[c] - 128) >> 31;
sum += ~t & data[c];
এটি শাখাটি অপসারণ করে এবং কিছু বিটওয়াইজ অপারেশন দিয়ে এটি প্রতিস্থাপন করে।
(দ্রষ্টব্য যে এই হ্যাকটি কঠোরভাবে যদি ইফ-স্টেটমেন্টের সাথে সমান হয় না তবে তবে এই ক্ষেত্রে এটি সমস্ত ইনপুট মানের জন্য বৈধ data[]
))
বেঞ্চমার্কস: কোর আই 7920 @ 3.5 গিগাহার্টজ
সি ++ - ভিজ্যুয়াল স্টুডিও 2010 - এক্স 64 প্রকাশ
// Branch - Random
seconds = 11.777
// Branch - Sorted
seconds = 2.352
// Branchless - Random
seconds = 2.564
// Branchless - Sorted
seconds = 2.587
জাভা - নেটবিয়ানস 7.1.1 জেডিকে 7 - এক্স 64
// Branch - Random
seconds = 10.93293813
// Branch - Sorted
seconds = 5.643797077
// Branchless - Random
seconds = 3.113581453
// Branchless - Sorted
seconds = 3.186068823
পর্যবেক্ষণ:
- ব্রাঞ্চের সাথে: বাছাই করা এবং অরসোর্ট করা ডেটার মধ্যে একটি বিশাল পার্থক্য রয়েছে।
- হ্যাক সহ: বাছাই করা এবং অরসেটেড ডেটার মধ্যে কোনও পার্থক্য নেই।
- সি ++ ক্ষেত্রে, হ্যাকটি আসলে ড্যাটা বাছাই করার সময় শাখার চেয়ে তুলনামূলকভাবে ধীরে ধীরে হয়।
থাম্বের একটি সাধারণ নিয়ম হ'ল সমালোচনামূলক লুপগুলিতে ডেটা-নির্ভর ব্রাঞ্চিং এড়ানো (যেমন এই উদাহরণ হিসাবে)।
হালনাগাদ:
এক্সস with৪ এর সাথে -O3
বা এর সাথে জিসিসি 6..1.১ -ftree-vectorize
শর্তযুক্ত পদক্ষেপ উত্পন্ন করতে সক্ষম। সুতরাং বাছাই করা এবং অরসোর্ট করা ডেটার মধ্যে কোনও পার্থক্য নেই - উভয়ই দ্রুত।
(বা কিছুটা দ্রুত: ইতিমধ্যে সাজানো কেসটির জন্য, ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে নামিয়ে আনতেcmov
পারে যদি জিসিসি এটিকে ন্যায়বিচারের পরিবর্তে সমালোচনামূলক পথে ফেলে add
, বিশেষত ব্রডওয়েলের আগে যেখানে cmov
2 সাইকেল বিন্যাস রয়েছে : জিসিসি অপ্টিমাইজেশান পতাকা -O3 কোড -O2 এর চেয়ে ধীর করে তোলে )
ভিসি ++ ২০১০ এমনকি এই শাখার অধীনে থাকা শর্তাধীন শর্তাদি তৈরি করতে অক্ষম /Ox
।
ইন্টেল সি ++ কম্পাইলার (আইসিসি) 11 অলৌকিক কিছু করে। এটি দুটি লুপকে আন্তঃসংযোগ করে , এর ফলে বাইরের লুপে অবিশ্বাস্য শাখা উত্তোলন করা হয়। সুতরাং এটি শুধুমাত্র ভুল অনুমানের প্রতিরোধী নয়, এটি ভিসি ++ এবং জিসিসি যা কিছু উত্পন্ন করতে পারে তার দ্বিগুণও দ্রুত! অন্য কথায়, আইসিসি বেঞ্চমার্ককে পরাস্ত করতে টেস্ট-লুপের সুযোগ নিয়েছে ...
যদি আপনি ইন্টেলটি শাখাবিহীন কোডটি সংকলন করেন তবে এটি কেবল ডানদিকের সাথে এটি ভেক্টরাইজ করে ... এবং শাখার সাথে ঠিক তত দ্রুত (লুপ ইন্টারচেঞ্জের সাথে) is
এটি দেখাতে সক্ষম হয় যে এমনকি পরিপক্ক আধুনিক সংকলকরা কোড অপ্টিমাইজ করার ক্ষমতাকে বিভিন্নভাবে বদলে যেতে পারে ...