জিসিসি কেন কেবলমাত্র বাকি ৯৯ টি পূর্ণসংখ্যার পরিবর্তে পুরো অ্যারে জিরো দিয়ে পূরণ করে? অ-শূন্য শুরুর দিকের অ্যারেগুলির শুরুতে।
void *sink;
void bar() {
int a[100]{1,2,3,4};
sink = a; // a escapes the function
asm("":::"memory"); // and compiler memory barrier
// forces the compiler to materialize a[] in memory instead of optimizing away
}
মিনজিডব্লিউ 8.1 এবং জিসিসি 9.2 উভয়ই এ্যাসএম তৈরি করে ( গডবোল্ট সংকলক এক্সপ্লোরার )।
# gcc9.2 -O3 -m32 -mno-sse
bar():
push edi # save call-preserved EDI which rep stos uses
xor eax, eax # eax=0
mov ecx, 100 # repeat-count = 100
sub esp, 400 # reserve 400 bytes on the stack
mov edi, esp # dst for rep stos
mov DWORD PTR sink, esp # sink = a
rep stosd # memset(a, 0, 400)
mov DWORD PTR [esp], 1 # then store the non-zero initializers
mov DWORD PTR [esp+4], 2 # over the zeroed part of the array
mov DWORD PTR [esp+8], 3
mov DWORD PTR [esp+12], 4
# memory barrier empty asm statement is here.
add esp, 400 # cleanup the stack
pop edi # and restore caller's EDI
ret
(এসএসই সক্ষম করে এটি মুভিডকা লোড / স্টোর সহ সমস্ত 4 টি আরম্ভকারীকে অনুলিপি করবে)
জিসিসি কেন lea edi, [esp+16]
ক্লাংয়ের rep stosd
মতো কেবল সর্বশেষ 96 টি উপাদানকে স্মরণ করে না (দিয়ে )? এটি কি কোনও মিসড অপটিমাইজেশন, না এইভাবে এটি করা কোনওরকম আরও দক্ষ? (ঝাঁকুনি আসলে memset
ইনলাইনিংয়ের পরিবর্তে কল করে rep stos
)
সম্পাদকের দ্রষ্টব্য: প্রশ্নটির মূলত অ-অপটিমাইজড সংকলক আউটপুট ছিল যা একইভাবে কাজ করেছিল, তবে অক্ষম কোডটিতে -O0
কোনও কিছুই প্রমাণিত হয় না। তবে দেখা যাচ্ছে যে এই অপ্টিমাইজেশনটি এমনকি জিসিসি দ্বারা মিস হয়েছে -O3
।
a
একটি অন-ইনলাইন ফাংশনে একটি পয়েন্টার পাস করা সংকলককে বাস্তবায়িত করতে বাধ্য করার অন্য উপায় হতে পারে a[]
, তবে 32-বিট কোডে যা asm এর উল্লেখযোগ্য বিশৃঙ্খলা বাড়ে। (স্ট্যাক আরোগুলির ফলে পুশ হয়, যা স্টোরের সাথে অ্যারের সূচনা করতে স্টোরগুলিতে মিশে যায়))
ব্যবহার করে volatile a[100]{1,2,3,4}
জিসিসি পায় অ্যারে তৈরি এবং তারপরে অনুলিপি , যা উন্মাদ। সাধারণত volatile
কম্পাইলাররা স্থানীয় ভেরিয়েবলগুলি কীভাবে শুরু করে বা স্ট্যাকের উপরে রাখে তা দেখার জন্য সাধারণত ভাল।
.rodata
... আমি বিশ্বাস করতে পারি না 400 বাইট অনুলিপি করা শূন্যের চেয়ে 8 টি আইটেম সেট করার চেয়ে দ্রুত।
-O3
(যা এটি করে)। Godbolt.org/z/rh_TNF
missed-optimization
কীওয়ার্ড সহ এটি জিসিসির বাগজিলায় রিপোর্ট করুন ।
a[0] = 0;
এবং তারপরেa[0] = 1;
।