আসুন জিসিসি 4.8 এটির সাথে কী করে তা দেখতে ডিসমাইল কম্পাইল করি
পাইপলাইন উন্নত করার জন্য ব্লাগোভেষ্ট শাখা বিপরীতের কথা উল্লেখ করেছে, তবে বর্তমান সংকলকরা কি সত্যিই তা করে? খুঁজে বের কর!
ছাড়া __builtin_expect
#include "stdio.h"
#include "time.h"
int main() {
/* Use time to prevent it from being optimized away. */
int i = !time(NULL);
if (i)
puts("a");
return 0;
}
জিসিসি 4.8.2 x86_64 লিনাক্স দিয়ে কম্পাইল এবং ডিসকোপাইল করুন:
gcc -c -O3 -std=gnu11 main.c
objdump -dr main.o
আউটপুট:
0000000000000000 <main>:
0: 48 83 ec 08 sub $0x8,%rsp
4: 31 ff xor %edi,%edi
6: e8 00 00 00 00 callq b <main+0xb>
7: R_X86_64_PC32 time-0x4
b: 48 85 c0 test %rax,%rax
e: 75 0a jne 1a <main+0x1a>
10: bf 00 00 00 00 mov $0x0,%edi
11: R_X86_64_32 .rodata.str1.1
15: e8 00 00 00 00 callq 1a <main+0x1a>
16: R_X86_64_PC32 puts-0x4
1a: 31 c0 xor %eax,%eax
1c: 48 83 c4 08 add $0x8,%rsp
20: c3 retq
মেমরিতে নির্দেশের আদেশটি অপরিবর্তিত ছিল: প্রথমে puts
এবং তারপরে retq
ফিরে আসুন।
সঙ্গে __builtin_expect
এখন এর সাথে প্রতিস্থাপন করুন if (i)
:
if (__builtin_expect(i, 0))
এবং আমরা পেতে:
0000000000000000 <main>:
0: 48 83 ec 08 sub $0x8,%rsp
4: 31 ff xor %edi,%edi
6: e8 00 00 00 00 callq b <main+0xb>
7: R_X86_64_PC32 time-0x4
b: 48 85 c0 test %rax,%rax
e: 74 07 je 17 <main+0x17>
10: 31 c0 xor %eax,%eax
12: 48 83 c4 08 add $0x8,%rsp
16: c3 retq
17: bf 00 00 00 00 mov $0x0,%edi
18: R_X86_64_32 .rodata.str1.1
1c: e8 00 00 00 00 callq 21 <main+0x21>
1d: R_X86_64_PC32 puts-0x4
21: eb ed jmp 10 <main+0x10>
puts
ফাংশন, খুব শেষ সরিয়ে নেওয়া হয়েছে retq
প্রত্যাবর্তন!
নতুন কোডটি মূলত:
int i = !time(NULL);
if (i)
goto puts;
ret:
return 0;
puts:
puts("a");
goto ret;
এই অপ্টিমাইজেশন সঙ্গে করা হয়নি -O0
।
তবে শুভকামনা যে উদাহরণ __builtin_expect
ছাড়াই দ্রুত চালিত একটি উদাহরণ লেখার জন্য , সিপিইউগুলি সে দিনগুলিতে সত্যই স্মার্ট । আমার নিষ্পাপ প্রচেষ্টা এখানে ।
সি ++ 20 [[likely]]
এবং[[unlikely]]
সি ++ ২০ এই সি ++ বিল্ট-ইনগুলি মানক করেছে: সি ++ 20 এর সম্ভাব্য / অসম্ভব বৈশিষ্ট্যটি যদি অন্য-বিবৃতিতে ব্যবহার করতে হয় তবে তারা সম্ভবত (পাং!) একই কাজ করবে।