আসুন জিসিসি 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)
printf("%d\n", 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 14 jne 24 <main+0x24>
10: ba 01 00 00 00 mov $0x1,%edx
15: be 00 00 00 00 mov $0x0,%esi
16: R_X86_64_32 .rodata.str1.1
1a: bf 01 00 00 00 mov $0x1,%edi
1f: e8 00 00 00 00 callq 24 <main+0x24>
20: R_X86_64_PC32 __printf_chk-0x4
24: bf 00 00 00 00 mov $0x0,%edi
25: R_X86_64_32 .rodata.str1.1+0x4
29: e8 00 00 00 00 callq 2e <main+0x2e>
2a: R_X86_64_PC32 puts-0x4
2e: 31 c0 xor %eax,%eax
30: 48 83 c4 08 add $0x8,%rsp
34: c3 retq
মেমরিতে নির্দেশের আদেশটি অপরিবর্তিত ছিল: প্রথমে printf
এবং তারপরে 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 11 je 21 <main+0x21>
10: bf 00 00 00 00 mov $0x0,%edi
11: R_X86_64_32 .rodata.str1.1+0x4
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
21: ba 01 00 00 00 mov $0x1,%edx
26: be 00 00 00 00 mov $0x0,%esi
27: R_X86_64_32 .rodata.str1.1
2b: bf 01 00 00 00 mov $0x1,%edi
30: e8 00 00 00 00 callq 35 <main+0x35>
31: R_X86_64_PC32 __printf_chk-0x4
35: eb d9 jmp 10 <main+0x10>
printf
(আপনি কম্পাইল __printf_chk
), ফাংশন শেষ সরিয়ে নেওয়া হয়েছে পরে puts
হিসাবে অন্যান্য উত্তর উল্লেখ এবং বিনিময়ে শাখা ভবিষ্যদ্বাণী উন্নত।
সুতরাং এটি মূলত:
int main() {
int i = !time(NULL);
if (i)
goto printf;
puts:
puts("a");
return 0;
printf:
printf("%d\n", i);
goto puts;
}
এই অপ্টিমাইজেশন সঙ্গে করা হয়নি -O0
।
তবে শুভেচ্ছা এমন উদাহরণ লেখার জন্য যা __builtin_expect
বাইরে ছাড়াও দ্রুত চলে , সিপিইউগুলি আজকাল সত্যই স্মার্ট । আমার নিষ্পাপ প্রচেষ্টা এখানে ।
সি ++ 20 [[likely]]
এবং[[unlikely]]
সি ++ ২০ এই সি ++ বিল্ট-ইনগুলিকে মানক করেছে: সি -+ 20 এর সম্ভাব্য / অসম্ভব বৈশিষ্ট্যটি যদি অন্য-বিবৃতিতে ব্যবহার করতে হয় তবে তারা সম্ভবত (পাং!) একই কাজ করবে।