An Inspired Engineer – Telegram
An Inspired Engineer
1.32K subscribers
63 photos
17 videos
4 files
91 links
اینجا در مورد performance, distributed systems و کرنل لینوکس مینویسم

https://aieideas.com/
Download Telegram
https://x.com/_AbolfazlAbbasi/status/1944350638122340466

راستی یادتون نره، لینک استریم رو قبلش اینجا هم میزارم


@knowpow
👍7🔥51🎉1
An Inspired Engineer
ای زیبای خفته ❤️‍🔥 https://www.amd.com/en/products/adaptive-socs-and-fpgas/evaluation-boards/zcu1285.html قیمت ۳۰ ۳۵ هزار دلار یا به عبارتی ۲.۵ میلیارد تومن
🛰️ شما مهندسی رو با همچین پردازنده هایی مشاهده بفرمایید اصلا!

اگه فرض کنیم حین جنگ دشمن بتونه تمامی ماهواره های GPS رو بزنه و یا مختلش کنه، این هواپیماهای گرون با چی مسیر یابی میکنن؟ چند صد سال پیش که GPS نبود با چی مسیریابی میکردن؟ افرین با ستاره ها!

میاییم سراغ ناوبری نجومی (astro-inertial) مثل همون NAS-14V2 “R2-D2” روی SR-71. سیستم اینجوریه که یک تلسکوپ گیمبل‌شده دایره ای رو تو آسمون رو میچرخونه، سه تا ستاره رو از بین ۶۴ ستاره‌ی از پیش نقشه‌ شده قفل می‌کنه و با یک زمان‌سنج دقیق و تقویم جولیان مقایسه می‌کنه و خطای INS رو لحظه‌ای تصحیح می‌کنه و جاشو رو درمیاره، حتی تو سرعت ۳ ماخ و ارتفاع ۸۰,۰۰۰ پایی هم کار میکنه چون هنوز زیر ستاره هاس :)

لینک کاملش

@knowpow
🔥14👍51
اینترنت مثل آبه، نمیتونین بگین بیایین به شما اب بدیم چون شما کارتون مهمتر از بقیه اس...

هر بار با یه اسمی اینترنت طبقاتی رو پرزنت میکنن برای مردم!
👍252
Khoone Khorshid ~ TajMusics.com
Bahram & Ali Sorena
هی آبادی مسموم برج بلند تو اوج تباهی بود
پوچی هر چه بخواهی بود
🔥4
چرا GC زیاد کال میشه؟

عمدتاً به دلیل allocation و آزادسازی سریع و مکرر تعداد زیادی از object هایی با عمر کوتاه توی حافظه اتفاق میوفته، فکر کنید مکرر یه چیزی رو خرید میکنید و یک ثانیه استفاده میکنید و میندازین اشغال.

allocation های کوچک و مکرر:
کدتون به طور مداوم و تو حلقه‌ها یا متدهای پرکاربرد(مثل مسیر استریم، یا شبکه و هرجایی که زیاد کال بشه) ابجکت های جدیدی مثل String، آرایه‌ یا دیتاکلاس(برای ui state) را ایجاد میکنه و از ابجکت هایی که قبلا ساخته استفاده نمیکنه.

تصاویر و Bitmap های بزرگ: لود یا پردازش تصاویری با رزولوشن و سایز بالا و بدون بهینه ‌سازی مناسب یا فرمت مناسب میتونه بخش بزرگی از حافظه رو به سرعت allocate و deallocate کنه. باید حواستون باشه که Bitmap ها به شدت حافظه مصرف میکنن و ساختن و خذف اونا میتونن GC رو تحریک کنن.

#Android

@knowpow
👍9
"Saw-tooth Pattern" (پترن دندان اره‌ای)

یه علامت خطرناک که مصرف باطری رو شدیدا میبره بالا

لبه رو به بالا (افزایش ناگهانی): نمودار مصرف حافظه به سرعت شروع به بالا رفتن می‌کنه. این نشون می‌ده که اپ شما داره به سرعت بجکت ‌های جدیدی رو allocate می‌کنه و حافظه رو پر می‌کنه. تا اینجا مشکلی نداریم، یه صفحه ی جدید باز شده یا یه اتفاقی توی بکگراند افتاده که نیاز بوده الوکیشین داشته باشیم.

لبه رو به پایین (افت ناگهانی): وقتی مصرف حافظه به یه حد مشخصی میرسه، Garbage Collector فعال می‌شه و شروع میکنه به پاکسازی آبجکتهای غیر ضروری و آزاد کردن حافظه. این باعث می‌شه نمودار مصرف حافظه به صورت ناگهانی سقوط کنه و به سمت پایین بیاد.

همه اینا رفتار های شایع توی سیستمه، اصلا کار GC همینه، اینجاست که اینکارو کنه، ولی مشکل وقتی شروع میشه که این رفتار سریع تکرار میشه، دقیقاً شبیه دندانه های اره به نظر میرسه. دیدن این پترن به شما میگه که اپ شما داره بی رویه آبجکت‌ ها رو می‌سازه و ولشون میکنه و GC رو تحریک میکنه تا پاکشون کنه، هر بار که GC اجرا می‌شه، یه PAUSE تو کار اپ ایجاد میکنه که میتونه باعث UI Jank بشه.

#Android

@knowpow
👍154
This media is not supported in your browser
VIEW IN TELEGRAM
چرا #اینترنت_آزاد حق همه مردم ایران هست!؟
مگه برای اب و برق هم همینطوره؟ (البته اگه فردا اونم نشه)
9👍1
جدا از مهندسی پشت تلگرام که بهینه نوشته شده، تلگرام چیزی داره به اسم Update Queue. چیزی که ۱ سال از دوران جوونیم رو صرف مهندسی معکوسش کردم.
تلگرام برای پوش کردن تغییرات مثل پیام جدید، ادیت، ری اکشن، تایپینگ و… به کلاینت‌ها از سرویس Updates تو پروتکل MTProto استفاده میکنه، ایده ی کلی و کلیدی خیلی ساده اس و اینه که کلاینت ها یه state محلی نگه میدارن و آپدیتارو دقیقا با ترتیب درست اعمال میکنن؛ اگه شکافی بینشون افتاد، Difference می‌گیرن و دوباره پرش میکنن.

چرا اینکارو کرده و کلا چالشا چیه؟
• ترتیبش مهمه چون ممکنه یه اپدیت وابسته به چیزی باشه که توی خود همون پچ میاد
• تحویل دقیق باید انجام بشه و هیچی گم نشه
• مقیاسش هم میلیون‌ها کاربر همزمان باید بگیرنش، مثل کانال های بزرگ

از اونجایی که هر پیامرسان منبع عظیمی از اتفاقاتیه که هر لحظه میوفته ما میتونیم اسم این اتفاقات رو event بزاریم. تلگرام هم یه پیامرسان مولتی کلاینته، یعنی هر کاربر میتونه چندین دیوایس برای یه حساب داشته باشه، پس وقتی یه ایونت اتفاق میوفته که باید یه کاربر از اون خبردار بشه باید اون ایونت رو به دیوایس های دیگه ی کاربر هم بفرسته، حدودا با مرتبه زمانی On^2.

مکانیزم اینجوریه که وقتی دیوایسی انلاین باشه و سوکت همون سوکتی باشه که keep alive هست یا اخرین rpc رو کال کرده سرور ایونت رو توی queue برای اون دیوایس نگه نمیداره و مستقیم میفرسته به کلاینت، حالا از اونجایی که کلاینت های دیگه ممکنه افلاین باشن یا حتی توی بکگراند پروسسشون کیل شده باشه عقب میمونن. حالا وقتی اون دیوایسی که عقب مونده بود با باز شدن سوکتش درخواست گرفتن اپدیت هارو وقتی که افلاین بوده رو از سرور میکنه و اطلاعات لوکالش رو میفرسته به سرور و اپدیت هارو درخواست میکنه.
من برای ساده شدنش اینجوری میگم که دیوایس میاد به سرور میگه من تا این زمان t رو داشتم و بعد این رو بهم بده، سرور هم میاد حساب کتابش رو میکنه و جواب رو توی یه پچ میفرسته! حالا چی توی این پچ هست و چی رو میفرسته رو میتونم یه رشته توییت دیگه در موردش بزنم.

حالا اگه اعدادی که توی پچ میاد با اعداد توی کلاینت نخونه عملا میگیم گپ اتفاق افتاده، برای همین هم کلاینت باید رکویست getDiff رو بزنه.
رکویست updates.getDifference به کلاینت اجازه می‌ده بگه:
من الان pts = X و seq = Y هستم و هر چی بین این و حالت جدید هست بهم بده.
• سرور ممکنه جواب بده:
difference: همه ی آپدیت های گمشده
differenceSlice: بخشی از آپدیت ها یعنی هنوز باید به فچ کردن ادامه بدی
differenceEmpty: چیزی تغییر نکرده

جالبترش اینه که توی نسخه های جدیدترش برای کانال ها مکانیسم جدا getChannelDifference هست، چون هر کانال pts مستقل داره و این باعث میشه شما فقط کانال هایی رو بگیری که تغییر کردن! برای سوپر گروه هم مکانیزم همینه.

این باعث می‌شه حتی اگر چند ساعت آفلاین باشی، بعد از اتصال دوباره دقیقاً همه‌چی رو بگیری و هیچ پیامی رو از دست ندی

حتی با packet loss یا reconnect، state کلاینت خراب نمیشه و سرور مجبور نیست برای هر کلاینت همه چی رو دوباره بفرسته. فقط gap ها sync میشن

@knowpow
142👍10🔥8
تاریخ بی خردی

@knowpow
1👍244
حین اینکه منتظر ماشین فرودگاه بودم دوست ترکم “باران” برام یه کلیپ از یه پیج فارسی فرستاد که داشت اموزش کلمات فارسی رو میداد و بهم گفت یه سری کلمات مثل: جنگ، صلح و مذاکره توی ترکی هم استفاده میشدن… دلیلی شد براش شاهنامه رو فرستادم و داستان فردوسی رو توضیح دادم، ناخوداگاه خودم رو وسط ویکیپدیا گردی دیدم و به شخص عجیبی رسیدم:

ابوالحسن بهمنیار بن مرزبان سالاری
ایشون استاد حکیم عمر خیام بوده و خودش از شاگردان برجسته ابن سینا بوده، طوری که ابن سینا فقط برای جواب دادن به پرسش های بهمنیار کتاب نوشته:
از برجسته‌ترین شاگردان ابن سینا یا ابوعلی بود و در درس ابن سینا حضور فعال داشته و پرسش‌های پرسون و مهمی را مطرح می‌کرده کتاب المباحثات ابن سینا بیش‌تر در پاسخ به پرسش‌های او است.


البته در مورد واقعیت شاگردی خیام هم تو نت تحقیق کردم منابعی مثل نظامی عروضی در چهارمقاله تایید کرده ولی بعضی پژوهشگران معاصر تردید دارن و می‌گن شاید این نسبت بیشتر جنبهٔ روایی و سنتی داشته باشه (چون فاصله زمانی کمی بین درگذشت بهمنیار و دوران جوانی خیام هست). اما در منابع کلاسیک، این شاگردی بارها تکرار شده

هر چی که بوده الان کمتر دانشجویی پیدا میشه که استادش رو به چالش بکشه و کمتر استادی پیدا میشه که ابن سینا باشه

بیش باد!

@knowpow
1🔥135👍2
An Inspired Engineer
سورس Seastar رو بریم تو کارش یا چی؟! https://github.com/scylladb/seastar @knowpow
خب رسیدیم به محبوب اینروزای من: Seastar

تو این مجموعه پست ها میخوام تلاش کنم یه دید کلی از پروژه seastar بهتون بدم طوری که بدونین چرا با وجود کتابخونه های async نیاز بوده که برن و چیزی مثل seastar رو بنویسن؟! کاراییش کجاست؟ معماری shared nothing چیه و چرا داره استفاده میکنه؟ معماریش چطور میتونه کمکش کنه که high performance باشه و اصلا چرا باید همچین چیزی وجود داشته باشه؟
7🔥3👍2
پست اول، مقدمه ای بر Seastar

استارت فریمورک Seastar توسط Avi Kivity توی سال ۲۰۱۵ زده شد، هدف اصلی نوشتن الهام و کاربرد اولیه Seastar بازنویسی Cassandra بود و دیتابیس ScyllaDB رو توسعه دادن. حتی توی مقاله ‌ای که درباره ی ScyllaDB نوشتن گفتن که ادعای افزایش ده برابری پرفورمنس(نسبت به کدنویسی جاوا و استفاده از قفل‌ ها و روش‌های معمولی که برای ترد ها استفاده میشد) به کل برگرفته از قدرت استفاده از Seastar عه.

وقتی یه تیم بخواد یه دیتابیس با پرفورمنس خیلی بالا بسازه اگه بره سراغ فریمورکای عمومی و معمول، بخش زیادی از کارایی رو خرج قفل‌ها، همگام‌سازی بین تردها، تاخیرهای اشتراک حافظه و مدیریت تردها می‌کنه. برای همین ساخت یه فریمورک سطح پایین که بتونه I/O رو مستقیم کنترل کنه و بین هسته‌ ها مرزبندی دقیق داشته باشه، یه تصمیم منطقی و لازم بود.

حالا چرا پرفورمنسش بالاست؟!
بخش عمده‌ی افت پرفورمنس زمانی اتفاق می‌افته که CPU به‌جای اجرای دستور(حتی شده یه فورلوپ) تو حالت idle منتظر completion یه عملیات I/O یا آزاد شدن یه قفل بمونه.
هر نوع synchronization بین هسته‌ها چه از طریق mutex و چه cache line sharing باعث stall شدن pipeline و افت کارایی شدید میشه! درسته توی فریمورکای معمول مثل اسپرینگ بوت و... به چشم نمیاد ولی اگه قراره یه سیستم های پرفورمنس بسازیم اینجا اولین نقطه ایه که باید اصلاح بشه!
این تأخیرهای ظاهرا کوچک تو مقیاس بالا به latency بالا و عملکرد پایین ختم میشن.

یعنی فرض کنید ما یه برنامه ی مولتی ترد داریم که دارن روی یه پورت گوش میدن و منتظرن کانکشن جدید بیاد تا accept کنن و بعد شروع کنن به خوندن ازش و جواب دادن بهش! تا اینجا همه چی زیباست و خوب کار میکنه ولی مشکل اینجاست که همشون دارن کانکشن های جدید رو توی یه لیست مشترک نگهداری میکنن، ممکنه دوتا کلاینت توی یه لحظه وصل بشن و دوتا ترد همزمان بخوان لیست رو تغییر بدن پس مجبورن از قفل روی لیست استفاده کنن و بوم! اینجا پرفومنسمون ترکید! درسته این روش کار میکنه و خیلی هم زیباست و خیلی از فریمورکا دارن همین الان همینکارو میکنن ولی ما نمیخواییم که یه فریمورک عمومی باشیم! میخواییم یه فریمورک های پروفومنس بسازیم، پس چیکار کنیم؟ راه حل: معماری Shared Nothing

معماری Shared Nothing
قبلا اینجا صحبت کردم در موردش که چرا نیاز داریم
خب گفتم که هدفم zero context switch هست و باید برای اون معماری رو تغییر میدادم، حالا کاری که کردم اینه که اومدم یه io_context تعریف کردم که هر فید برای خودش، تایمراش و کانکشنایی که داره با این context کار میکنن، یعنی فرض کنین من میخوام با binance_feed وصل بشم به بایننس و مجبورم براش یه io context بسازم، هر io context یه ترد داره که میاد boost::asio::io_context رو روی یه ترد پین میکنه و روی اون اجرا میکنه.

حالا قسمت زیبای ماجرا اینجاست که این io context رو حتما باید به یه هسته ی cpu پین کنیم تا کرنل نیاد با عشق خودش بین هسته ها این ترد رو بازی بده، پس تا اینجا داریم که یه io context میسازیم و به یه هسته پینش میکنیم و بعد پاس میدیم به یه feed.


پس کاری که میکنیم اینه که میاییم جای اینکه یه ترد پول باز کنیم به تعداد هسته های ماشینمون ترد باز میکنیم و اونارو به هر هسته پین میکنیم، بعد روی هر هسته ایونت لوپ رو باز میکنیم و روی هر ترد به یک پورت واحد گوش میدیم(کرنل اینجا خودش هندل میکنه و اجازه میده از چندین ترد روی یه پورت گوش بدم که اینجا در موردش گفتم) و بعد هر کانکشنی که میاد با توجه به کانفیگ کرنل بین کانکشنا توزیع میشه و هر ترد هم لیست کانکشنایی که خودش نگهداشته رو داره، دیگه نیازی به این نیست که ترد ها بین همدیگه لیست کانکشن نگهدارن!
هیچی نباید بینشون رد و بدل بشه، مگر اینکه روی یه مدل از lock-free data structure باشه!

خلاصه اینکه Seastar اومده همه‌ی اون چیزایی که همیشه پرفورمنس رو می‌کشتن مثل قفل، context switch و اشتراک حافظه رو بندازه دور.
هر هسته کار خودشو می‌کنه، بدون اینکه مزاحم بقیه بشه و نتیجه‌اش یه فریمورکه که می‌تونه از هر CPU تا آخرین سیکلش استفاده کنه.

تو پست بعدی می‌رم سراغ این که Seastar دقیقاً چجوری این کارو می‌کنه، با reactor و futureهاش که مغز سیستمن

@knowpow
👍1613