TGViewer
OpenPCB OpenPCB @openpcb · 3.44K subscribers
Post #297 2.91K
شما هم ممکنه مثل پیتر کاولی (@corsix) کد ساده‌ی C خودتون را با GCC کامپایل کنید و خروجی اسمبلی ARM64 را باز کنید و همینطور که دارید کد اسمبلی تولید شده رو میبینید از خودتون بپرسید:
«این دیگه چیه؟ چرا کامپایلر دو بار w4 & w1 رو حساب کرده، بعد هم دو بار w0 & w4 رو تکرار کرده! مگه نمی‌شد یک mov بزنه و خلاص؟»
چیزی که در نگاه اول مثل یک باگ یا تنبلی کامپایلر به نظر می‌رسه، در واقع یکی از بهترین درس‌های بهینه‌سازی CPUهای مدرنه!

قبلش باید ببینیم چرا GCC (و گاهی Clang) همچین کار «عجیبی» می‌کنن و چرا تقریباً همیشه تو این موارد حق با کامپایلره.

کد سی احتمالاً همچین چیزی بوده:
uint32_t lookup(uint32_t index, uint32_t mask, const uint32_t* table) {
uint32_t idx = index & mask;
return table[idx];
}

و در نتیجه کد اسمبلی تولید شده توسط GCC همچین چیزیه!
and   w0, w4, w1        // w0 = w4 & w1
and w2, w4, w1 //! w2 = w4 & w1
and w0, w0, w4 // w0 = w0 & w4
and w0, w0, w4 // !
ldr w0, [x2, w0, uxtw #2]

کدهای تکراری! ولی چرا؟ تو CPUهای مدرن ARM64 (Apple M1/M2/M3/M4، Snapdragon X Elite، Graviton و …) اجرای دوباره‌ی یک دستور ساده‌ی AND تقریباً همیشه از mov سریعتره چون mov وابستگی داده (data dependency) ایجاد می‌کنه و pipeline را متوقف می‌کنه. یعنی وقتی می‌نویسی mov w2, w0،اتفاقی که میفته اینه که CPU باید صبر کنه تا w0 کاملاً آماده بشه، بعد w2 رو پر کنه. اما وقتی دو بار and w2, w4, w1 می‌نویسی، هر دو دستور ورودی یکسان (w4 و w1) داره و هیچ وابستگی‌ای بین‌شون نیست. نکته بعدی اینکه CPUهای out-of-order می‌تونند این دو دستور AND رو همزمان در دو واحد ALU مختلف اجرا کنند و از طرفی مکانیزم Register Renaming باعث می‌شه CPU این دو نتیجه را به‌عنوان دو رجیستر فیزیکی کاملاً جدا ببینه و هزینه‌ی واقعی خیلی خیلی کمه!

جالب اینه که clang خروجی متفاوتی داره و کمی تمیزتره!
and   w0, w1, w2      
and w0, w0, w1
ldr w0, [x3, w0, uxtw #2]

دلیلش اینه که Clang کمی محافظه‌کارتره و بیشتر به «کد تمیز» اهمیت می‌ده، تو بنچمارک‌های واقعی روی M2/M3/M4 معمولاً تفاوت سرعت از ۱٪ کمتره. یعنی GCC با کد «زشت‌تر» گاهی حتی چند صدم درصد سریع‌تره!

پس یادتون نره در بیشتر مواقع «کامپایلر بیشتر از من می‌فهمه»، کد اسمبلی کوتاه‌تر هم نشونه سریعتر بودنش نیست. دفعه‌ی بعدی هم که GCC یا Clang چیزی تولید کرد که در نگاه اول «احمقانه» به نظر رسید، قبل از آه‌کشیدن یه بنچمارک کوچیک بزنین و یه نگاهی به معماری همون CPU بندازید. تو ۹۹٪ مواقع می‌بینین کامپایلر حق داشته. البته چیزهایی که هکرهای ffmpeg دستی بهینه می‌کنن رو هم نمی‌شه نادیده گرفت، ولی اونها قرار نیست به ما ثابت کنن که کامپایلر خنگه و ما ازش باهوش‌تریم. و در نهایت هم یادمون نره که روی آرم، GCC معمولاً یه ذره، خیلی کم اسمبلی بهینه‌تری تولید می‌کنه.


📡openpcb
  • ❤ 48
  • 👍 14
  • 🔥 4
More from @openpcb
  1. Sep 28, 2026خب خب بریم تو کارش. پ‌ن: قرار نیست سریع انجام بشه من خیلی تنبلم و یک سر دارم و هزار سودا!…
  2. Sep 6, 2026یه کاربر چینی به اسم GoFly یه برد فلایت‌کنترلر FPV رو کامل با GPT-6 Astraطراحی کرده. مدل ک…
  3. Aug 11, 2026یه پروژه سخت‌افزاری بگید کلش رو Vibe-Craft کنم و اینجا گزارش بدم. فضایی نباشه فقط. 😅 راست…
  4. Aug 5, 2026Post #350
  5. Aug 2, 2026چیپ مغزی Neuralink، استارتاپ چیپ مغزی ایلان ماسک، حالا به معلولان حرکتی امکان کنترل ویلچره…
  6. Jul 29, 2026وضعیت تولید و قیمت چیپ‌های حافظه چه از نوع RAM چه eMMC بقدری بحرانی و عجیب غریبه که یکی از…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →