সংকলকগুলি অনুকূলকরণে সত্যই ভাল switch
। সাম্প্রতিক জিসিসি একটি শর্তের গুচ্ছটি অনুকূলকরণেও ভাল if
।
গডবোল্টে কিছু টেস্ট কেস করেছি ।
case
মানগুলি যখন একত্রে গোষ্ঠীভুক্ত হয়, তখন জিসিসি, ঝনঝন এবং আইসিসি সমস্ত বিটম্যাপ ব্যবহার করার জন্য যথেষ্ট স্মার্ট হয় যে কোনও মানটি বিশেষগুলির মধ্যে একটি কিনা তা পরীক্ষা করতে।
যেমন gcc 5.2 -O3 এর সাথে সংকলন করে switch
(এবং if
খুব অনুরূপ কিছু):
errhandler_switch(errtype): # gcc 5.2 -O3
cmpl $32, %edi
ja .L5
movabsq $4301325442, %rax # highest set bit is bit 32 (the 33rd bit)
btq %rdi, %rax
jc .L10
.L5:
rep ret
.L10:
jmp fire_special_event()
লক্ষ্য করুন যে বিটম্যাপটি তাত্ক্ষণিক ডেটা, সুতরাং এতে কোনও সম্ভাব্য ডেটা-ক্যাশে মিস করা বা কোনও জাম্প টেবিল নেই।
gcc 4.9.2 -O3 switch
বিটম্যাপে সংকলন করে , তবে মুভ 1U<<errNumber
/ শিফট সহ করে। এটি if
শাখাগুলির সিরিজের সংস্করণটি সংকলন করে ।
errhandler_switch(errtype): # gcc 4.9.2 -O3
leal -1(%rdi), %ecx
cmpl $31, %ecx # cmpl $32, %edi wouldn't have to wait an extra cycle for lea's output.
# However, register read ports are limited on pre-SnB Intel
ja .L5
movl $1, %eax
salq %cl, %rax # with -march=haswell, it will use BMI's shlx to avoid moving the shift count into ecx
testl $2150662721, %eax
jne .L10
.L5:
rep ret
.L10:
jmp fire_special_event()
এটি কীভাবে 1 টি থেকে বিয়োগ করে errNumber
( lea
সেই পদক্ষেপের সাথে সেই ক্রিয়াকলাপটি একত্রিত করার জন্য) নোট করুন । এটি বিটম্যাপটিকে তাত্ক্ষণিক 32 বিটের মধ্যে ফিট করতে দেয় 64 64 বিট-তাত্ক্ষণিক এড়ানো movabsq
যা আরও বেশি নির্দেশনা বাইট নেয়।
একটি সংক্ষিপ্ত (মেশিন কোডে) ক্রম হবে:
cmpl $32, %edi
ja .L5
mov $2150662721, %eax
dec %edi # movabsq and btq is fewer instructions / fewer Intel uops, but this saves several bytes
bt %edi, %eax
jc fire_special_event
.L5:
ret
(ব্যবহারে ব্যর্থতা jc fire_special_event
সর্বব্যাপী এবং এটি একটি সংকলক বাগ ।
rep ret
পুরানো এএমডি কে 8 এবং কে 10 (প্রাক-বুলডোজার) এর সুবিধার জন্য শাখা লক্ষ্যমাত্রা এবং নিম্নলিখিত শর্তাধীন শাখাগুলিতে ব্যবহৃত হয়: `rep ret` এর অর্থ কী? । এটি ছাড়া শাখার পূর্বাভাস সেই অপ্রচলিত সিপিইউগুলিতে তেমন কাজ করে না।
bt
(বিট পরীক্ষা) একটি রেজিস্টার আর্গ সঙ্গে দ্রুত হয়। এটা তোলে দ্বারা একটি 1 বাম-নাড়াচাড়া কাজ সম্মিলন errNumber
বিট এবং একটি করছেন test
, কিন্তু এখনও 1 চক্র লেটেন্সি এবং শুধুমাত্র একটি একক ইন্টেল uop হয়। এটি মেমরি আর্গের সাথে ধীরে ধীরে সিআইএসসি শব্দার্থবিজ্ঞানের কারণে ধীরে ধীরে: "বিট স্ট্রিং" এর জন্য একটি মেমোরি অপারেন্ডের সাথে পরীক্ষা করতে হবে বাইটের ঠিকানাটি অন্য আর্গের ভিত্তিতে (8 দ্বারা বিভক্ত) গণনা করা হয়েছে, এবং 1, 2, 4, বা 8 বাইট অংশের মধ্যে সীমাবদ্ধ নয় স্মৃতি অপারেশন দ্বারা নির্দেশিত।
থেকে Agner কুয়াশা নির্দেশনা টেবিল , একটি পরিবর্তনশীল গোনা শিফট নির্দেশ কোন তুলনায় ধীর হয় bt
সাম্প্রতিক ইন্টেল (2 পরিবর্তে uops 1 এবং শিফট অন্য সব কিছুর যে প্রয়োজন করে না) করে।