مقایسه سرعت خوندن/نوشتن RAM و HDD


چکیده


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


چرا میخوایم سرعت رم و هارد دیسک رو مقایسه کنیم؟


RAM vs HDD


چند سال پیش توی یه فرومی توی یه تایپیکی مربوط به برنامه‌نویسی من به این نکته اشاره کردم که سرعت خوندن/نوشتن توی هارددیسک بطور متوسط 100 هزار بار از رم کمتره..!
برای بسیاری از برنامه‌نویسها این حرف عجیب بود، و خیلیا قبولش نمیکردن، برای همین من مجبور شدم تکنولوژی هر دو رو توضیح بدم و با زبان تخصصی بگم که چرا چنین حرفی زدم.
با این مقاله همراه باشین تا ببینیم چرا میگم هارد دیسک بطور متوسط صد هزار بار از رم کند تره.


اولا که واضحه هیچوقت نمیتونیم همچین چیزیو بطور دقیق بگیم، هر کسی ادعا کنه که مثلاً HDD دقیق انقدر از RAM سریع تره ، معلومه که خیلی چیزارو نمیدونه.


دوما ، مقایسه هارد دیسک و رم عمرا توی یک مقاله بگنجه:)
من میتونم یک کتاب چند جلدی راجع به RAM بنویسم و یک کتاب چند جلدی راجع به HDD و توی یک کتاب چند جلدی اینارو با هم مقایسه کنم! نه بخاطر اینکه من خیلی عالم هستم ، بلکه بخاط اینکه متوجه بشین حجم و عمق مطلب خیلی زیاده .
اینجوری نیست که ما بگیم «آره سرعت این موجودیت رو توی اینترنت نوشته انقدر و سرعت اونو نوشته فلانقدر و بقیه‌ش یه تقسیم ساده‌ست،» .....


بلکه این مطلب میتونه بعنوان تز دکتری توی تحصیلات عالیه مطرح بشه، و یک نفر پایانامه دکتراشو صرف این کنه و یه مقاله بنویسه، که بازم نمیتونه کل مطلب رو ادا کنه..!


اینارو صرفا عرض کردم که بدونین چقدر ماجرای عمیقیه...😬❤️
بیشتر مطالبی که راجع به هارددیسک بیان میکنم رو من چندین سال قبل از کتاب استاد آبراهام سیلورچتس خونده بودم. اسم کتاب هست:


بریم سراغ داستان اصلی.


رم چیست؟


رم – RAM – مخفف Random Access Memory هست یعنی حافظه ای با دسترسی تصادفی، خود این اسم تمام ساختاری که لازم هست راجع به رم بدونیم رو توضیح میده. فرض کنید یه تیکه حافظه گنده دارید که سرعتش نسبتا بالاست (نسبت به تکنولوژیهایی مثل دیسک و ای2پیرام) و شمای انتزاعیش همچین چیزیه:


Abstract RAM schema


مدل انتزاعی یک رم


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


اما چرا سرعتش بالاست؟


از لحاظ پیاده‌سازی سخت افزاری، این حافظه روی یه آرایه دو بعدی مدل شده،‌ مثل یه ماتریس. ساختار «Random Access» این امکان رو ایجاد میکنه که ما به تمام خونه های مختلف حافظه در یک زمان یکسان دسترسی داشته باشیم، اما چطور؟
بیاین ساختار بلوک منطقی رم رو نگاه کنیم:


RAM Logical structure


یک رم 8 بیتی - منبع عکس ETSU


امروزه رم ها از خونه‌های کوشولویی که توی یه آرایه دو بعدی هستن تشکیل شدن. هر رم یک واحد Address-Decoder داره که آدرسی انکد شده در مبنای 2 (باینری) رو دریافت میکنه و اون رو دیکد میکنه که ببینه کدوم سلول حافظه باید انتخاب بشه (برای خوندن/نوشتن).
توی همین عکس یه واحد منطقی Read/Write داریم که کارش اینه که خبر بده آیا باید چیزی نوشته بشه یا باید چیزی خونده بشه.
همچنین یه واحد دیگه هم وجود داره به اسم Cheap-Select ، این برای موقعی هست که ما بیش از یک چیپ مموری داریم (در واقعیت اینجوریه).
همچنین ساختاری به نام databus وجود داره که توش 0 با ولتاژ پایین و 1 با ولتاژ بالا نشون داده میشه، این قسمت ورودی/خروجی سلول‌های چیپ رم هست.
همچنین فرض کنید سطرهای رم 8 بیتی یا 1 بایتی هستن.


فرض کنید شما میخواین توی خونه هزارم (1000) رم بنویسین، برای این حداقل یک آدرس دیکودر 10 بیتی لازم دارین ( چون 2 به توان 10 میشه 1024 و با یک آدرس دیکودر 10 بیتی میشه بین 1024 تا خونه رم تمییز قائل شد و آدرسدهی کرد). حالا شما 1000 در مبنای 10 رو میبرید به مبنای 2 که میشه : 1111101000
و این عدد آدرس باینری 1111101000 رو میفرستید به آدرس-دیکودر. آدرس-دیکودر با گیتهای منطقی درونی که داره، با گرفتن 1111101000 به عنوان ورودی، سطر هزارم رم رو انتخاب (select) میکنه و خوندن/نوشتن اتفاق می‌افته.
دقیقاً فرقش با یه تکنلوژی مثل دیسک همینه...، توی دیسک باید یکسری خونه پیمایش بشن تا برسیم به خونه مد نظر، اما اینجا یه مدار منطقی داریم که آدرس-دیکودر مدار خاصیش رو روشن میکنه. صرفاً اون مدار انتخاب میشه و نه تنها حرکت فیزیکی نداریم (در مقایسه با دیسک) بلکه پیمایش خونه به خونه هم نداریم (در مقایسه با دیگر تکنولوژیها)


یک آدرس-دیکودر 3 بیتی توی شکل زیر نشون داده شده، حتماً در جریانید که با 3 بیت میشه 2 به توان 3 یعنی 8 حالت مختلف داشته باشیم. پس یه آدرس دیکودر 3 بیتی میتونه 8 خونه از رم رو آدرسدهی کنه و همرو با یک سرعت یکسان انتخاب کنه.


3-bit Address-Decoder


یک آدرس دیکودر 3بیتی با 8 پایانه- منبع عکس Codestall


یک آدرس-دیکودر 10 بیتی هم عین همین ساخته میشه، و میتونه 1024 تا سطر مختلف رو انتخاب کنه، فقط شکلش توی این مقاله جا نمیشه:))


پس این شد معنی ساختار «دسترسی تصادفی» یا «Random Access»، یعنی زمانی که ما یک طراحی سخت‌افزاری داریم که اوردر زمانی دسترسی به هر سلول حافظه ما با بقیه سلولها برابره، این اتفاق با پیاده‌سازی یه گیت منطقی ممکن میشه که بهش میگیم آدرس-دیکودر و توضیحش دادیم.


اگر سرعت دسترسی اینقدر عالی و خوبه، چرا ما RAM رو جایگذین یچیزی مثل دیسک نمیکنیم و ازش استفاده نمیکنیم؟
رم بخاطر ساختار منطقی و الکترونیکی که داره، با قطع شدن جریان برق، تمام اطلاعات داخلش پاک میشه و اصطلاحاً تمام اطلاعاتش ریست میشه(بیتهاش 0 میشه).
این در مقابل دیسک، نمیتونه یه حافظه استیبل برای ذخیره سازی طولانی مدت باشه...، صرفاً برای ذخیره اطلاعات فعلی محدود به محاسبات کامپیوتر خوبه.


این روزها حافظه هایی مثل SSD که حرکت فیزیکی ندارن دارن به جای چیزهایی مثل HDD در بعضی جاها استفاده میشن – اونا بخاطر نداشتن حرکت فیزیکی بسیار سریع ترن – اما مشکلات خودشونم دارن. شاید در آینده توی یه مقاله جدا اون تکنولوژیهارو هم بررسی کردیم.


برگردیم به رم، از لحاظ تکنولوژی ساخت رم ها به دو دسته استاتیک و داینامیک تقسیم میشن.


رمهای استاتیک اطلاعات رو توی مدارهای ترانزیستوری شبیه D-فلیپ فلاپ ذخیره میکنن، و این اطلاعات مادامی که رم برق داشته باشه اونجا میمونن و از بین نخواهند رفت. نسبت به رم های داینامیک کوشولوتر هستن و سرعتشون بیشتره و دیکودر ساده‌تری دارن. معمولاً توی فرایندهای سرعتی مثل کش کردن و اپلیکیشنهای خیلی سریع استفاده میشن.
بعضی جاها که میخوان اطلاعات مهم رو روی رم نگه دارن، از همین SRAM استفاده میکنن و یه باتری بک‌آپ به مدار اضافه میکنن که حتی اگه به هر دلیلی برق مدار قطع شد، باتری سیستم رو تغذیه کنه و اطلاعات پاک نشه.


رمهای داینامیک اطلاعات رو رو خازنها ذخیره میکنن. این خازنها بخاطر ساختار کوشولوتری که دارن ظرفیت کلی رم رو میرن بالا، اما این خازنها یه مشکل بزرگ دارن، هر خازن طبق طبیعت الکترونیکش بعد از مدت زمانی جریان داخلی خودش رو از دست میده و اصطلاحاً دِشارژ میشه. بعد از دِشارژ شدن یه خازن اطلاعاتی هم که توش ذخیره شده بوده میپره! به این روند میگن leak شدن جریان برق. برای جلوگیری از - از دست رفتن اطلاعات، باید تند-تند اطاعات کل خازنها خونده بشن و دوباره همونجا نوشته بشن که خازنها شارژ بمونن و اطلاعات از دست نره. به این روند میگن refresh کردن مدار. پس توی DRAM ها باید یه مدار ریفرش-کننده باشه که اطلاعات همه خازنهارو هی تند-تند بخونه و هی تند-تند دوباره سر جاشون بنویسه.
ضمناً رمهای داینامیک خیلی از رمهای اساتیک ارزونتر هستن، و رمهایی که روی سیستم شما الان دارن استفاده میشن احتمالاً دینامیک هستن.


بهتون پیشنهاد میکنم مصاحبه استیو ووزنیاک رو حتماً مطالعه کنین، این مصاحبه علیرغم اینکه قرار بوده مصاحبه محاوره ای و معمولی نسبت به خودش شخص ووز باشه، توش بینهایت توضیحات تخصصی الکترونیکی داره..!
یه قسمتش راجع به تکنولوژی رمها حرف میزنه که خیلی جالبه:


«...به اطرافم نگاه کردم، اولین رم دینامیک همون سال معرفی شده بود. 1975 اولین رم دینامیک 4کلیوبایتی به بازار اومده بود. این اولین بار بود که قیمت رم از قیمت حافظه‌های مغناطیسی، که تا امروز در همه جا استفاده میشد کمتر بود. حالا ناگهان دنیا داشت به سمت رم میرفت، حافظه ما از این به بعد روی سیلیکون بود. تقریبا همه در جهان، آلتیر – شفر کامپیوتر – پلیمرفیک کامپیوتر – اینسایت کامپیوتر و ...، با مهندسهایی ناکارآمد و نه بهترین مهندس های موجود طراحی میکردن. اونها تکنسینهایی بودن که میدونستن باید چطور دیتاشیت رمهارو بخونن و بعد توی دیتاشیت ریزپردازنده‌ها دنبال خطی بگردن که توش نوشته شده آدرس، و اونو با آدرس رم تطبیق بدن و سیمکشی کنن. این کار ساده ایه، اما فقط در صورتی کار میکنه که رمهای شما استاتیک باشن. رمهای دینامیک قیمتی برابر نصف یا حتی یک چهارم قبلیا داشتن. معنی رم دینامیک این بود که به جای داشتن 32 تراشه برای ساخت کامپیوتری که زبون بفهمه، میتونستین 8 تراشه رم داشته باشین. اما رم دینامیک به مدارهایی نیاز داشت که در هر ثانیه 2000 بار به تک تک آدرسهاشون سر بزنن و چیزی که اونجاست رو بخونن و دوباره اونارو همونجا بنویسن تا اطلاعات از دست نره! رم دینامیک که امروز هم در کامپیوتر ما وجود داره هر بیتی رو فقط در دوهزارم ثانیه فراموش میکنه مگر اینکه یه نفر اون بیت رو توی این زمان بخونه و دوباره سر جاش بنویسه. میشه اینطور گفت که الکترون ها توی بشقابین که در هر 2هزارم ثانیه ازش میریزن بیرون..!»


ترجمه از استاد جادی، کل مصاحبه به زبان فارسی:
https://jadi.net/2014/02/radiogeek-36-wozniak-and-narenji-90


اصل مصاحبه:
http://www.foundersatwork.com/steve-wozniak.html


و دیگه تقریباً تمام مسائل تکنیکی که میخواستم راجع به رمها بگم رو گفتم، مدیریت یک رم بر عهده سیستم عامله. CPU کامپیوتر با Virtual-Addressing کار میکنه و خود رم با Logical-Addressing.
بعداً یه مقاله جدا راجع به اینکه سیستم عامل چه‌جوری رم رو به پراسسها تخصیص میده مینویسم و یه مقاله جدا هم مینویسم راجع به اینکه چطور میتونیم به کل رم فعلی سیستم دسترسی داشته باشیم.


هارددیسک چیست؟


دیسکها، لوحهای گرد و دایره‌ای شکلی هستن که میتونن بسته به معماریشون اطلاعات رو توی خودشون ذخیره کنن، اولین نوع دیسکهارو میتونیم توی گرامافونها ببینیم، که اونجا صدای ورودی به گرامافون باعث ایجاد لرزه میشد و سوزن روی لوح گردی که میچرخید یه شیاری رو بصورت حلزونی ایجاد میکرد. برای پخش صدا سوزن نرم تری میذاشتن که توی شیار حرکت میکرد و با استفاده از لرزش صدارو بازپخش میکرد.
بعدها دیسکهای سخت مغناطیسی اومدن که ازشون میخوایم حرف بزنیم و همینطور دیسکهای نوری مثل CD ها و DVDهارو داشتیم که با یک لیزر توشون اطلاعات burn میشد.
پس دیسک به طور کلی توی این حوزه،‌ معمولا لوح گردی هست که حول یه محوی میچرخه و اطلاعات توی شعاع های مختلف اون نوشته میشه.


یه هارددیسک، شامل دیسکهای گرد مغناطیسی هست که اطلاعات توش با مغناطیسه شدن هر ذره کوشولو از دیسک، بصورت باینری نوشته میشه. هارددیسک معمولا از چند تا لایه (پلاتر-platter) تشکیل شده، تعداد این پلاتر ها معمولا بین 1 تا 5 تا هست.
اگه بصورت یه برش عرضی ببینیم این شکلی میشه:


HDD Platters


منبع عکس compuclever


همون برش عرضی بصورت انتزاعی:


HDD Abstract Platters


منبع عکس: کتاب Database System Concepts, 6th Edition


حالا این پلاتر ها، یه سطح مغناطیسی هستن که میتونن با مغناطیسه شدن، 0 و 1 هارو توی خودشون ذخیره کنن.
این پلاتر، به شکل منطقی (logical) به یسری شعاع های متفاوت تقسیم میشه، که این شعاعها شامل دایره‌های گردی هستن که دیسک رو میسازن، به هر کدوم از این شعاع ها میگن یه ترک- Track
توی عکس زیر چندین ترک انتزاعی رو میبینید:


HDD Tracks


منبع عکس schoolcoders


خود این ترک به قسمتهای کوچکتری تقسیم میشه، که بهش میگن سکتور- sector
توی عکس زیر قسمت سکتور رو مشاهده میکنید:


HDD Sectors


منبع عکس slideplayer


یه سکتور کوچکترین واحدی توی دیسک هست که نوشته/خونده میشه، معمولا سایز یه سکتور 512 بایت هست...


یه دسته‌ای هم توی یه هارددیسک وجود داره که بهش میگن arm که سرش یه هد (head) داره که عقب جلو میره و خود دسته هه هم میچرخه و این سکتورهارو میخونه یا توشن مینویسه.


منطقا ترکهای بیرونی(شعاع های بزرگتر) تعداد سکتورهای بیشتری از ترکهای درونی(شعاعهای کویچکتر) دارن..


هر نوع اطلاعاتی که بخواد روی دیسک نوشته بشه، باید بصورت 0 و 1 نوشته بشه، یعنی بصورت باینری انکد بشه، و به آرم داده بشه که توسط هد توش نوشته بشه. همین داستان برای خوندن هم بر قراره.
بسته به فرمتهای مختلف نرم افزاری که هارددیسکهارو با اونها فرمت میکنیم، یکسری تکنولوژی نرم‌افزاری وجود دارن که مربوط به بحث ذخیره سازی داده‌ها هستن مثل inode و mft که بعداً توی مقالات دیگه راجع بهشون حرف میزنیم.


مقایسه سرعت هارددیسک و رم


فرض کنید تمام پیچیدگی های پیاده سازی و عملیاتی و سیستم عاملی رم رو نادیده بگیریم ، و یه راست بریم سراغ هارد دیسک:


وقتی سرعت یک هارد دیسک رو میخوایم در نظر بگیریم ، باید سرعت متوسط اعمال I/O رو توی اون در نظر بگیریم یعنی ورودی خروجی های هارد دیسک
*Input/Output
یا به زبان فارسی ساده : خوندنها و نوشتن‌ها


محاسبه این سرعت بشدت کار تخصصی هست و توی این سرعت هزاران فاکتور دخیله، فاکتور هایی که هر کدوم توضیح دادنشون یک کتابه مطلبه و نهایتا اگر تمام فاکتور هارو بتونیم مدلسازی کنیم ، (که خیلی کار سختیه) در سناریو های مختلف ممکنه از 10 هزاربار تا مثلا 500 هزار بار کند تر عمل کنه. که متوسط این سناریو هارو بعنوان آمار بیان میکنن.


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


یک هارد دیسک ، مثل یک CD یه (چند تا) دیسک داره که میچرخه و یک هد داره (مثل اون دسته سیاهای توی گرامافون) که روی یه مداری که روی شعاع دیسک واقع شده میتونه بالا و پایین بره. به این ترتیب میتونه تمام دیسک رو پردازش کنه.


گیف پایین رو مشاهده بفرمائید:


HDD head move


یادم نمیاد منبع گیف کجاست- اگر میدونید خبر بدین!




یک سرعتی برای هارد دیسک بیان میشه بعنوان Transfer time که مجموعه کلی‌ای از چند تا سرعت هست وابسته به فاکتور های زیر :


1- سرعت خوندن هد {سرعت خوندن دیتا توسط هد ، باز خودش وابسته هست به 7-8 تا فاکتور! ما میگیم که متفاوته و ریزتر نمیشیم}
2- سرعت بالا و پایین شدن آرم
3- سرعت چرخش دیسک {در هارد دیسکهای متفاوت‌، این سرعت متفاوت هست}
4- ظرفیت ترک (track)
5- ظرفیت سکتور
6- مقدار دیتای طلب شده
7- تاخیر چرخشی (این با سرعت چرخش فرفق میکنه ) بهش میگن Rotational Latency
(من یکمی توی همین مقاله توضیحش میدم ولی خیلی بیشتر از این مطلب لازم داره، توی کتابی که معرفی کردم خیلی خوب توضیح داده)
8- تاخیر seek کردن هد یا seek time
( اینم جلوتر من یکمی توضیحش میدم )
9- بلاک اینترلیود بودن هارد دیسک (اینو بعدش توضیح میدم و میگم که چه فرقی با رم داره که رم بایت اینترلیود هست - این خیلی جالبه)
10- تکنیک جلو-جلو خوندن هارددیسک یا read ahead
(اینم باید توضیح بدم)
11- ظرفیت اتخاذ شده برای تکنیک بافرینگ Buffering.
(اینم باید توضیح بدم)
12- الگوریتمهای زمانبندی روی هارد دیسک! این مطلب خودش میتونه یه کتاب 12 جلدی باشه! من واقعا نمیدونم چجوری میتونم حق مطلب رو توی این مقاله ساده بیان کنم! زبان من الکن هست از توصیفش - مثلا من اگه میشد الگوریتم آسانسورو برای شما شرح بدم که ببینین اگر نبود هارددیسک یک ملیارد بار کند تر میشد...!
13- نحوه چینش فایلها!!! این دیگه واقعا خیلی خییلی خیلی خیلی توضیح میطلبه!!! شما قطعا از فرگمنت شدن دیسک اسمشو شنیدین ، شاید فقط شنیدین که دیسک دیفرگ بشه سرعتش میره بالا... شایدم میدونین معنیش چیه... حالا توضیحش میدیم😬
14- نحوه ذخیره سازی لاگها روی هارد دیسک - که من راجع بهش چیزی نمیگم
15- کش کردن درخواستها توسط سیستم عامل که از اسکیل بحث ما خارجه
16- بحث دیوایس منیجینگ یا به قول ویندوزی ها درایو منیجینگ که بشدت تخصصیه و کار من نیست توضیحش
17- ... انقدر فاکتور در این سرعت دخیل هست که من اگه بخوام بگم شاید هیچوقت نتونم این مقاله رو ببندم، همه بحثهاشم من بلد نیستم* بسیار بسیار تخصصی هست ، باید مراجعه کنید به خبره های فایل سیستم، من اطلاعات خیلی ناکامل محدود و اندکی دارم.


حالا زمان اتقال یا ترنسفر تایم، - که اول گفتم - میشه جمعِ تمــــــام این تاخیر ها و زمانهای موجود!




حالا بریم سراغ توضیح قسمتهایی که گفتم، شروع کنیم از توضیح دو مورد اول که خیییلی باحال و مهمه:


رم مستقل از حرکات فیزیکیه اما هارددیسکها اتلاف زمان/انرژی توی حرکت فیزیکی دارن.


دو اتلاف وقت مشهور فیزیکی در هارددیسک:


1 - هارد دیسکها یه اتلاف دارن موقع چرخیدن خود دیسک 💿
مثلا یه داده ای که میخوای بخونی یا بنویسی ، توی این درجه از دیسک نیست(درجه ای که هد روی اون قرار داره) و مثلاً دیسک باید 260 درجه بچرخه تا توی اون درجه بخصوص بیفتته!
بهش میگن:


2 - یک اتلاف وقت دیگه دارن اینکه اون سیخسیخک هارد که بهش میگن هد (head) باید بالا و پایین بره و دقیق روی شعاع مربوطه بیفته تا بتونه سکتورو پیدا کنه ، بهش میکن زمان بالا پایین شدن برای جستجو یا


همین دوتا حرکت فیزیکی کافیه تا هارد دیسک بشدت کند باشه و نشه ازش بجای یچیزی مثل رم جهت ذخیره‌سازی سریع اطلاعات محاسبات فعلی استفاده کرد، ولی خوبیش اینه که اطلاعات با قطع شدن برق از بین نمیرن:3


عکس زیرو ببینین:


seek-time vs rotational-latency-time


یادم نمیاد منبع این عکس هم کجاست- اگر میدونید خبر بدین!


راستیه روتیشنال لیتنسی تایمه،
زمانی که دیسک باید بیکار وایسته تا دیسک بچرخه و اول سکتور مورد نظر بیاد.


چپیه سیک-تایمه،
زمانی که باید هد حرکت کنه بره روی شعاعی که سکتور مورد نظر هست.




بلاک اینترلیود بودن هارد دیسک:


ما چند نوع اینترلیوینگ (معماری کار با بخشی از داده) داریم :


حالا فرقش چیه؟
قدیما اون اوایل که کامپیوتر ساخته شده بود میومدن یه بیت یه بیت میخوندن اطلاعاتو ، طبیعیه که خیلی کار بیخودیه ، چون تمام اطلاعاتی که ما باهاشون کار میکنیم حداقل یه بایت میطلبن
پس معماری بایت اینترلیود مطرحش شد و به کار گرفته شد…


امروزه شما نمیتونی یه بیت اطلاعات بنویسی توی دیسک یا روی رم یا تقریبا هر حافظه ای، باید حد اقل یک بایت بنویسی،
مثلا واسه یه متغیر بولین (TRUE/FALSE) فقط یه بیت کافیه ، اما همیشه 8 بیت میگیرن ، چونکه جنس حافظه بایت اینترلیود هست:)


حالا توی هارد دیسکها اومدن بلاک اینترلیود بودنو مطرح کردن ، وقتی طرف یه سیستم-کال میزنه به هارد دیسک و میگه که فلان بایت رو به من بده ، هارد دیسک میگه که من این همه دیسک بچرخونم هد بالا پایین کنم واسه یه بایت ؟! خب اگه بر فرض تو بعدش بگی بایت بعدیشم بده ، من دوباره باید برم هی دیسکو بچرخونم بایت بعدیشو پیدا کنم؟!
من مسخره تو نیستم! یه بلاک داده بهت میدم ، تو هر چقدرشو نیاز داری واکشی کن ، اگه بیشترم میخوای که بوگو!
مثلا 1024 بایت میده به سیستم عامل ، حالا سیستم عامل خودش فقط بایت اولشو میخواد ، میکشه بیرون و بقیه رو میریزه دور...
این قضیه الکی نیست ، روش 20 سال فکر شده و هزاران نفر آزمایش کردن و فهمیدن بلاک اینترلیود بودن بهتره از بایت اینتر لیود بودن برای HDD ها


حالا قضیه اینطوریه که رم byte-interleaved هست و هارددیسک block-interleaved


این قضیه خودش یک دنیا سرعتو HDD رو از رم کندتر میکنه در مقایسه.




تکنیک جلو-جلو خوندن هارددیسک یا read ahead :


این تقریبا یه مفهومی شبیه چیزی که الان قبلش توضیح دادم داره ولی یه دنیا متفاوته!


مثلا هارد دیسک بر اساس رفتار میفهمه که سکتور هایی که پیاپی هستن، ممکنه نیازمند کاربر (سیستم عامل ) بشن، پس درسته که سیستم عامل نگفته که اون عداد بلاک رو به من برسون، ولی هارد دیسک میرسونه، که اگه به کارش اومد، دوباره نخواد سیستم کال بزنه و دستوراتش بره واسه درایور سخت افزار، و موتور هارد دیسک روشن بشه ، و بره جدول ذخیره سازیو دوباره بخونه، شماره سکتورو بفهمه بچرخونه و هد رو بالا پایین کنه ، و بطور مغناطیسی بخونه و برگردونه و......🥴
این الگوریتمهاش پیچیده هستن، میشه راجع بهش هزاران آزمایش کرد و هزاران الگوریتم ارائه داد...




ظرفیت اتخاذ شده برای تکنیک بافرینگ Buffering:


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




الگوریتمهای زمانبندی روی هارددیسک:


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


هارد دیسکها فقط یه هد دارن و یه دیسک ( اون سه لایه ها مد نظر ما نیست - اونا هر کدوم یه هارد دیسک حساب میشن ) وقتی یه هد داریم و یک دیسک طبیعیه که باید اسکجولینگ خیلی خفنی پیاده کنیم، تا بتونیم درخواست های داده شده رو کاملا ارضا کنیم.


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


مثلا الگوریتمی وجود داره به اسم الویتور یا آسانسور، که میگه که حالا که دیسک داره میچرخه و روی این سکتور ها هستی، این بلاکم بده مال درخواست سوممونه تا برسیم به سکتور درخواست اول - یا اینکه حالا که داریم اینوری سیک میکنیم روی هد همینو سیسک کن و برنگرد عقب که ادامه رو بخونی ، همونو ادامه بده درخواست پنجم روی اون نواره ، بعدا موقع برگشت دستور اولم میخونیم.


مثل یک اسانسوری که داره میره بالا و طبقه 16 عه داره میره طبقه 20 ، یکی که طبقه 1 باشه دکمه رو بزنه نمیاد پایین سوارش کنه و بعدا بره 20! میره طرف 20 رو سروار میکنه بعدا میاد 1 - اینو وسط یکی طبقه 2 هم باشه سوارش میکنه.
راجع به آسانسور به تنهایی میشه کتاب نوشت …:))


هزاران الگوریتم دیگه وجود دارن!
یک بحث بهینه‌سازی خیلی شاخی داره^_^


که اگه این بحثها نبودن واسه یه I/O زدن روی دیسک باید 70 سال منتظر مینشستیم.




نحوه چینش فایلها (داده ها):


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


یه مقاله هم راجع به ریکاوری مینویسم؛ اونجا فرگمنت شدن دیسک رو توضیح میدم


دیسک فرگمنت شده:


Fragmented HDD


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


وقتی که دیسک میخواد به یه فایل فرگمنت شده دسترسی داشته باشه× باید هی آرم و هدش رو بالا و پایین کنه و بین جاهای مختلف دیسک ببره تا بتونه همه قطعات فایلو واکشی کنه. این حرکات فیزیکی رو چند برابر میکنه و سرعت دسترسی رو میاره پایین تر. در کل فرگمنت شد باعث کند تر شدن کارکرد میشه... خصوصا اگه فالیها بزرگ باشن و قطعات کوچیک.


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


خلاصه که همیشه سرعت هایی که بر آورد میکنید باید بر اساس یک دیسک فرگمنت شده باشه ، که خودش هزاران بار ماجرا رو کندتر میکنه،
توی RAM ما فرگمنت شدن نداریم یعنی داریم؛ ولی روی سرعت به اون شکل تاثیر نداره - اصلا بیس کارش فرگمنت بودنه، رم همونطور که توضیح دادم به تمام خونه های خودش به یک زمان مساوی «دسترسی تصادفی» دسترسی داره.


خوندن اطلاعات و کار کردن با جداول روی هارددیسک (چیزهایی مثل inode یا mft) کار خیــــلی ریسورس-بر و زمان بریه.


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


توی رم معماری با گیت منطقی پیاده شده و سرعتش وابسته به سرعت حرکت جریان (الکترون آزاد) هست.


یه کلیپم دارم که یک کپی پبیست ساده در هارد دیسک رو بصورت اسلوموشن نشون میده،
حرکات فیزیکی هارددیسک، وقتی درش رو باز میکنیم و میبینیم😬:


https://www.youtube.com/watch?v=3owqvmMf6No


حرکتی که با چشم قابل دیدن هست و بار دوربین قابل ظبط، قطعا خیلی کند تر از سرعت حرکت الکترونهاست:)
و در کل، بطور متوسط 100 هزاربار کندتر بودن کاملا منطقی هست، اما بیاین با دانش برنامه‌نویسی که داریم، خودمون هم دست به آچار بشیم و تست کنیم ببینیم در عمل جریان چجوریه!


مقایسه سرعت رم و HDD در عمل


میخوایم یکسری برنامه بنویسیم که ادعایی که کردیم (کند تر بودن هارد دیسک از رم به میزان 100 هزار بار) رو تست کنیم.


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


و از لحاظ ابزار مقایسه، زبان برنامه‌نویسی مورد علاقه من PHP هست، اما وقتی بحث سنجش پیچیدگی زمانی/ریسورسی الگوریتمها میاد وسط و میخوایم آزمایشهایی رو راجع به مقایسه زمان/ریسورس مصرفی متدهای مختلف انجام بدیم، من نظرم اینه که همیشه باید حدالقمدور از زبانهای برنامه‌نویسی نزدیک به سطح پایینتر استفاده کنیم. زبانهایی کامپایلری مثل C و C++ همیشه به ما دسترسی بسیار بیشتر،‌ نزدیکتر و بهینه‌تری به ریسورسهایی مثل رم و دیسک میدن و همچنین بخاطر ساختار کامپایلری‌شون، کدی ترجمه شده به زبان ماشین میدن که صرفاً نقش اجرای الگوریتم رو بر عهده داره و خیلی کمتر درگیر محاسبات پرت میشن. با استفاده از این زبانها، نتیجه آزمایشهای ما متأثر از زمان/ریسورس پرتی که صرف تفسیر کد یا اجرای فرایندهای اجرایی مفسر و مترجم و کامپایلر هست نمیشه. برای همین توی این آزمایشمون از زبان C++ استفاده میکنیم.




فاز اول: مقایسه سرعت رم و هارددیسک در کار با داده‌های بزرگ


کد زیر رو در نظر بگیرید:

#include <iostream>
#include <sys/resource.h>
#include <chrono>

using namespace std;

int main() {

    // Start execution time
    clock_t start_1 = clock();
    auto start_2 = chrono::high_resolution_clock::now();

    // Start memory usage
    struct rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_start = usage.ru_maxrss; // in kilobytes

    // Code ----------------------------------------------------------
    char* arr = new char[1073741824];
    for(int i = 0; i < 1073741824 ; i++)
        arr[i] = 'A';

    // ---------------------------------------------------------------

    // Stop measuring memory usage
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_end = usage.ru_maxrss; // in kilobytes

    // Stop measuring execution time
    clock_t end_1 = clock();
    auto end_2 = chrono::high_resolution_clock::now();
    double execution_time_1 = double(end_1 - start_1) / CLOCKS_PER_SEC;
    chrono::duration<double, milli> execution_time_2 = end_2 - start_2;

    // Printing result
    cout << "Execution Time (Based on ctime): " << execution_time_1 * 1000.0 << " ms" << endl;
    cout << "Execution Time (Based on chrono): " << execution_time_2.count() << " ms" << endl;
    cout << "Memory Usage: " << memory_usage_end - memory_usage_start << " KB" << endl;

    return 0;
}

فایل کد


این قطعه کد زمان اجرا و میزان رم مصرفی مربوط به یک قطعه کد خاص رو اندازه‌گیری میکنه، اون قطعه کد خاص، سگمنت زیر هست که به اندازه دقیقاً 1 گیگابایت (1073741824 بایت) فضای رم رو تخصیص میده به یک آرایه از نوع کرکتر، اگه بخوام به زبان ساده بگم این قطعه کد که میبینید، دقیقاً 1 گیگابایت اطلاعات رو روی رم ذخیره میکنه:

char* arr = new char[1073741824];
for(int i = 0; i < 1073741824 ; i++)
    arr[i] = 'A';

با اجرای این کد، میتونیم با یه تقریب خوبی بسنجیم که ذخیره کردن 1 گیگابایت از اطلاعات روی مموری بصورت دسترسی تصادفی (Random Access) چه مقدار زمانی طول میکشه و اینکه چقدر از مموری (RAM) استفاده میشه (منطقاً دقیقاً باید 1 گیگابایت استفاده بشه). این کد کزمان اجرای اون قطعه سگمنت مذکور رو یک بار با اساتفاده از کلاکها توی کتابخونه ctime میسنجه و بار دیگر با استفاده از کتابخونه chrono. بدین ترتیب ما میتونیم بگیرم زمان خروجی ما نسبتا دقیق هست، یادتون باشه که اینکلود کردن iostream توی این کامپایلر من خودش کتابخونه ctime رو هم به کد اضافه میکنه، اگه توی کامپایلر شما این قضه کار نکرد، حتما کتابخونه رو دستی اینکلود کنین:


#include <ctime>


بیاین کد رو اجرا کنیم تا ببینیم پاسخ چیه، من روی یه ماشین لینوکس هستم، پس کد رو با g++ RAM_test.cpp کامپایل میکنم و با ./a.out اجرا میکنم.


نکته: همیـــشه یادتون باشه که در اینجور آزمایشها و مقایسه ها، انجام آزمایش (اجرای کد) رو حداقل 3 بار در شرایط مختلف تکرار کنید و متوسط کلی رو بعنوان پاسخ در نظر بگیرید، در هر لحظه توی یک ماشین کامپیوتری هزارن پراسس دیگر وجود دارن که با ریسورسها در حال تعامل هستن، رفتار این پراسس ها ممکنه در زمانهای متفاوت، تأثیری روی نتیجه آزمایش شما هم بذاره.


نکته2: یه دستور معروف یونیکسی هست به اسم time که با اون میتونیم یسکری اطلاعات جانبی راجع به کامندی که ران میکنیم داشته باشیم. من از این پکیج استفاده میکنم که زمانها و سی‌پی‌یو مصرفی حین اجرای برنامه رو مانیتور کنم. بعد از اجرا دقیقاً توضیح میدم معنی این اطلاعات چیه.


اجرای کد:

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ RAM_write_test.cpp 

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out 
Execution Time (Based on ctime): 2501.88 ms
Execution Time (Based on chrono): 2501.97 ms
Memory Usage: 1046800 KB

real    2.51s
user    2.36s
sys     0.14s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2440.13 ms
Execution Time (Based on chrono): 2440.23 ms
Memory Usage: 1046864 KB

real    2.45s
user    2.32s
sys     0.13s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2446.16 ms
Execution Time (Based on chrono): 2446.23 ms
Memory Usage: 1046772 KB

real    2.45s
user    2.32s
sys     0.13s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2444.35 ms
Execution Time (Based on chrono): 2444.5 ms
Memory Usage: 1046848 KB

real    2.45s
user    2.29s
sys     0.16s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2515.03 ms
Execution Time (Based on chrono): 2515.09 ms
Memory Usage: 1046832 KB

real    2.52s
user    2.39s
sys     0.13s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2438.22 ms
Execution Time (Based on chrono): 2438.28 ms
Memory Usage: 1046844 KB

real    2.45s
user    2.32s
sys     0.12s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2493.81 ms
Execution Time (Based on chrono): 2493.94 ms
Memory Usage: 1046784 KB

real    2.50s
user    2.35s
sys     0.15s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2501.99 ms
Execution Time (Based on chrono): 2502.09 ms
Memory Usage: 1046852 KB

real    2.51s
user    2.37s
sys     0.14s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2459.47 ms
Execution Time (Based on chrono): 2460.05 ms
Memory Usage: 1046872 KB

real    2.47s
user    2.32s
sys     0.15s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2429.63 ms
Execution Time (Based on chrono): 2429.75 ms
Memory Usage: 1046772 KB

real    2.43s
user    2.32s
sys     0.12s
cpu     99%

من این کد رو توی 10 بازه زمانی مختلف که سیستم من هر بار درگیر محاسبات متفاوتی بود اجرا کردم و خروجی به شرح بالا بود، همونطور که میبینید زمان اجرا با یه تقریب خاصی در یک رنجه، اما هر بار تغییرات جزئی داره که این نتیجه کارکردهای پارلل سیستم عامل ما هست، بعداً راجع به محاسبات موازی سیستم عامل یه مقاله مینویسم، اما مساله جالب دیگه اینه که میزان مموری مصرفی هم توی هر بار اجرا متفاوت بوده و این کمی عجیب بنظر میرسه… اما میشه تخصصی بررسیش کرد و اون موقع میبینیم که کاملاً معقوله. بررسی تخصصیش از حوصله این مقاله خارجه اما، بطور خیلی خلاصه میتونیم بگیم که کارکرد کد به کارکرد کتابخونه‌ها و توابعی که از سیستم اینکلود کردیم وابسته هست، این توابعی که کال کردیم هر بار اون زیر باک سیستم عامل دیتاهای متفاوتی رو وارد رم میکنن، و همین باعث متفاوت شدن میزان دیتای نشسته روی رم میشه، اما در کل روی رنج 1 گیگابایتی هست که سگمنت مذکور ما مصرف میکنه.


و حالا بریم سراغ توضیحات تخصصی کامند تایم که شامل ریپورتهایی از قبیل real و user و sys و cpu هست و ببینیم اینا چه معنی میدن.


زمان Real


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


زمان User


زمانی هست که سی‌پی‌یو صرف محاسبات برنامه میکنه، و به زبان تخصصی زمانی هست که پراسس روی سی‌پی‌یو نشسته و داره اجرا میشه (بهش میگن user-mode)


زمان Sys


زمانی هست که سی‌پی‌یو مشغول تسکهایی بوده که کرنل سیستم عامل بخاطر پراسس داشته انجام میداده، مثلاً مموری الوکیشن و I/O ها… (به این قسمت میگن kernel-mode)


cpu


و نهایتا این یکی راجع به میزان CPU هست که توسط این پراسس مصرف شده. این درصد ممکنه بالاتر از صد درصد هم بره (مثلا 650%) در مواقعی که شما دارین بصورت موازی رور هسته های مختلف مالتی-تردینگ یا چندنخی اجرا میکنین.


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


کرنل-مد/Kernel-mode


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


یوزر-مد/User-mode


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


منابع این قسمت:


حالا میتونیم یه تخمینی از متوسط زمان داشته باشیم:

(2501.88+2440.13+2446.16+2444.35+2515.03+2438.22+2493.81+2501.99+2459.47+2429.63) / 10 = 24670.67 / 10 = 2467.067
(2501.97+2440.23+2446.23+2444.5+2515.09+2438.28+2493.94+2502.09+2460.05+2429.75) / 10 = 24672.13 / 10 = 2467.213
(1046800+1046864+1046772+1046848+1046832+1046844+1046784+1046852+1046872+1046772) / 10 = 10468240 / 10 = 1046824
(2.51s+2.45s+2.45s+2.45s+2.52s+2.45s+2.50s+2.51s+2.47s+2.43s) / 10 = 24.74 / 10 = 2.474
(2.36s+2.32s+2.32s+2.29s+2.39s+2.32s+2.35s+2.37s+2.32s+2.32s) / 10 = 23.36 / 10 = 2.336
(0.14s+0.13s+0.13s+0.16s+0.13s+0.12s+0.15s+0.14s+0.15s+0.12s) / 10 = 1.37 / 10 = 0.137
(99%+99%+99%+99%+99%+99%+99%+99%+99%+99%) / 10 = 990 / 10 = 99


Therefore:

* Average Execution Time(Based on ctime): 2467.067 ms
* Average Execution Time(Based on chrono): 2467.213 ms
* Average Memory Usage: 1046824 KB
* Average Real Time: 2.474 s
* Average User Time: 2.336 s
* Average Sys Time: 0.137 s
* Average CPU Usage: 99 %

این نتایج رو در ذهن داشته باشین بعداً برای مقایسه بهش برمیگردیم. همین اوردر زمانی ذخیره سازی دیتا بصورت دسترسی تصادفی روی رم، سرعتی که لازم داریم برای مقایسه رو به ما میده، سرعتش در عمل برابری میکنه با خوندن چیزی از رم بصورت دسترسی تصادفی.




حالا بریم سراغ هارددیسک و ببینیم که خوندن/نوشتن یک گیگابایت از دیتا روی HDD چه مقدار زمان/ریسورس مصرف میکنه. البته در بحث این مقایسه دیگه ریسورسش (میزان رم مصرفیش) مد نظر ما نیست، بلکه زمانش برای ما مهمه. وقتی داریم رم رو با دیسک مقایسه میکنیم، دیگه نباید رمی که خود اعمال I/O مصرف میکنن رو بسنجیم.


کد زیر رو در نظر بگیرید:

#include <iostream>
#include <fstream>
#include <sys/resource.h>
#include <chrono>

using namespace std;

int main() {

    ofstream outfile;
    char character = 'A';

    // Start execution time
    clock_t start_1 = clock();
    auto start_2 = chrono::high_resolution_clock::now();

    // Start memory usage
    struct rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_start = usage.ru_maxrss; // in kilobytes

    // Code ----------------------------------------------------------
    outfile.open("output.txt");
    if (!outfile.is_open()) {
        cout << "Error opening file!" << endl;
        return 1;
    }
    for (int i = 0; i < 1073741824; i++) {
        outfile << character;
    }
    outfile.close();
    // ---------------------------------------------------------------

    // Stop measuring memory usage
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_end = usage.ru_maxrss; // in kilobytes

    // Stop measuring execution time
    clock_t end_1 = clock();
    auto end_2 = chrono::high_resolution_clock::now();
    double execution_time_1 = double(end_1 - start_1) / CLOCKS_PER_SEC;
    chrono::duration<double, milli> execution_time_2 = end_2 - start_2;

    // Printing result
    cout << "Execution Time (Based on ctime): " << execution_time_1 * 1000.0 << " ms" << endl;
    cout << "Execution Time (Based on chrono): " << execution_time_2.count() << " ms" << endl;
    cout << "Memory Usage: " << memory_usage_end - memory_usage_start << " KB" << endl;

    return 0;
}

فایل کد


این کد یه فایل به اسم output.txt باز میکنه (اگر نباشه میسازه و اگر باشه اوررایت میکنه{به اوررایتش برمیگردم}) و توش 1 گیگابایت داده مینویسه. من به رسم آزمایش 10 بار اجراش میکنم:

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ HDD_write_test.cpp

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && time ./a.out 
Execution Time (Based on ctime): 9536.65 ms
Execution Time (Based on chrono): 9538.49 ms
Memory Usage: 0 KB

real    9.54s
user    8.85s
sys     0.68s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && time ./a.out
Execution Time (Based on ctime): 9530.77 ms
Execution Time (Based on chrono): 10150.1 ms
Memory Usage: 0 KB

real    10.15s
user    8.82s
sys     0.72s
cpu     93%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && time ./a.out
Execution Time (Based on ctime): 9625.24 ms
Execution Time (Based on chrono): 10063.4 ms
Memory Usage: 0 KB

real    10.07s
user    8.99s
sys     0.64s
cpu     95%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && time ./a.out
Execution Time (Based on ctime): 9655.58 ms
Execution Time (Based on chrono): 9657.09 ms
Memory Usage: 0 KB

real    9.66s
user    8.96s
sys     0.70s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && time ./a.out
Execution Time (Based on ctime): 9479.76 ms
Execution Time (Based on chrono): 9634.6 ms
Memory Usage: 0 KB

real    9.64s
user    8.89s
sys     0.60s
cpu     98%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && time ./a.out
Execution Time (Based on ctime): 9477.25 ms
Execution Time (Based on chrono): 9641.66 ms
Memory Usage: 0 KB

real    9.65s
user    8.92s
sys     0.56s
cpu     98%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && time ./a.out
Execution Time (Based on ctime): 9468.07 ms
Execution Time (Based on chrono): 9475.96 ms
Memory Usage: 0 KB

real    9.48s
user    8.70s
sys     0.77s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && time ./a.out
Execution Time (Based on ctime): 9761.29 ms
Execution Time (Based on chrono): 10151.8 ms
Memory Usage: 0 KB

real    10.16s
user    9.05s
sys     0.72s
cpu     96%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && time ./a.out
Execution Time (Based on ctime): 9632.74 ms
Execution Time (Based on chrono): 10079 ms
Memory Usage: 0 KB

real    10.08s
user    8.92s
sys     0.72s
cpu     95%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && time ./a.out
Execution Time (Based on ctime): 9536.97 ms
Execution Time (Based on chrono): 9540.68 ms
Memory Usage: 0 KB

real    9.55s
user    8.89s
sys     0.65s
cpu     99%

و متوسط نتایج آزمایش به شرح زیره:

(9536.65+9530.77+9625.24+9655.58+9479.76+9477.25+9468.07+9761.29+9632.74+9536.97) / 10 = 95704.32 / 10 = 9570.432
(9538.49+10150.1+10063.4+9657.09+9634.6+9641.66+9475.96+10151.8+10079+9540.68) / 10 = 97932.78 / 10 = 9793.278
(0+0+0+0+0+0+0+0+0+0) / 10 = 0 / 10 = 0
(9.54s+10.15s+10.07s+9.66s+9.64s+9.65s+9.48s+10.16s+10.08s+9.55s) / 10 = 97.98 / 10 = 9.798
(8.85s+8.82s+8.99s+8.96s+8.89s+8.92s+8.70s+9.05s+8.92s+8.89s) / 10 = 88.99 / 10 = 8.899
(0.68s+0.72s+0.64s+0.70s+0.60s+0.56s+0.77s+0.72s+0.72s+0.65s) / 10 = 6.76 / 10 = 0.676
(99%+93%+95%+99%+98%+98%+99%+96%+95%+99%) / 10 = 971 / 10 = 97.1


Therefore:

* Average Execution Time(Based on ctime): 9570.432 ms
* Average Execution Time(Based on chrono): 9793.278 ms
* Average Memory Usage: 0 KB
* Average Real Time: 9.798 s
* Average User Time: 8.899 s
* Average Sys Time: 0.676 s
* Average CPU Usage: 97.1 %

خب اینکه تقریباً 5 برابر کند تره! پس اون همه خزعبلات و دک و پز که عای 10 هزار برابر بطور متوسط کند تره چیشد؟! عجله نکنید، بیاین یواش یواش فاکتورهای دخیل رو به آزمایش اضافه کنیم.
فرض کنید میخوایم 1 گیگابایت دیتایی که وجود داره رو اوررایت کنیم.




برای سنجش این حرکت داخل رم، من کد رو به این شکل تغییر میدم:

#include <iostream>
#include <sys/resource.h>
#include <chrono>

using namespace std;

int main() {

    char* arr = new char[1073741824];
    for(int i = 0; i < 1073741824 ; i++)
        arr[i] = 'A';

    // Start execution time
    clock_t start_1 = clock();
    auto start_2 = chrono::high_resolution_clock::now();

    // Start memory usage
    struct rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_start = usage.ru_maxrss; // in kilobytes

    // Code ----------------------------------------------------------
    for(int i = 0; i < 1073741824 ; i++)
        arr[i] = 'B';    
    // ---------------------------------------------------------------

    // Stop measuring memory usage
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_end = usage.ru_maxrss; // in kilobytes

    // Stop measuring execution time
    clock_t end_1 = clock();
    auto end_2 = chrono::high_resolution_clock::now();
    double execution_time_1 = double(end_1 - start_1) / CLOCKS_PER_SEC;
    chrono::duration<double, milli> execution_time_2 = end_2 - start_2;

    // Printing result
    cout << "Execution Time (Based on ctime): " << execution_time_1 * 1000.0 << " ms" << endl;
    cout << "Execution Time (Based on chrono): " << execution_time_2.count() << " ms" << endl;
    cout << "Memory Usage: " << memory_usage_end - memory_usage_start << " KB" << endl;

    return 0;
}

فایل کد


و اجرا میکنم:

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ RAM_overwrite_test.cpp

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out              
Execution Time (Based on ctime): 2315.81 ms
Execution Time (Based on chrono): 2315.86 ms
Memory Usage: 0 KB

real    4.76s
user    4.61s
sys     0.14s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2321.07 ms
Execution Time (Based on chrono): 2321.15 ms
Memory Usage: 0 KB

real    4.80s
user    4.66s
sys     0.14s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2305.9 ms
Execution Time (Based on chrono): 2305.95 ms
Memory Usage: 0 KB

real    4.78s
user    4.67s
sys     0.11s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2331.96 ms
Execution Time (Based on chrono): 2332.03 ms
Memory Usage: 0 KB

real    4.79s
user    4.70s
sys     0.09s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2291.69 ms
Execution Time (Based on chrono): 2296.94 ms
Memory Usage: 0 KB

real    4.74s
user    4.57s
sys     0.16s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2336.1 ms
Execution Time (Based on chrono): 2339.92 ms
Memory Usage: 0 KB

real    4.85s
user    4.71s
sys     0.12s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2330.54 ms
Execution Time (Based on chrono): 2330.6 ms
Memory Usage: 0 KB

real    4.82s
user    4.70s
sys     0.12s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2283.55 ms
Execution Time (Based on chrono): 2283.58 ms
Memory Usage: 0 KB

real    4.72s
user    4.59s
sys     0.12s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2328.87 ms
Execution Time (Based on chrono): 2328.91 ms
Memory Usage: 0 KB

real    4.79s
user    4.67s
sys     0.12s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2295.38 ms
Execution Time (Based on chrono): 2296.14 ms
Memory Usage: 0 KB

real    4.75s
user    4.60s
sys     0.15s
cpu     99%

و متوسط نتیجه:

(2315.81+2321.07+2305.9+2331.96+2291.69+2336.1+2330.54+2283.55+2328.87+2295.38) / 10 = 23140.87 / 10 = 2314.087
(2315.86+2321.15+2305.95+2332.03+2296.94+2339.92+2330.6+2283.58+2328.91+2296.14) / 10 = 23151.08 / 10 = 2315.108
(0+0+0+0+0+0+0+0+0+0) / 10 = 0 / 10 = 0
(4.76s+4.80s+4.78s+4.79s+4.74s+4.85s+4.82s+4.72s+4.79s+4.75s) / 10 = 47.8 / 10 = 4.78
(4.61s+4.66s+4.67s+4.70s+4.57s+4.71s+4.70s+4.59s+4.67s+4.60s) / 10 = 46.48 / 10 = 4.648
(0.14s+0.14s+0.11s+0.09s+0.16s+0.12s+0.12s+0.12s+0.12s+0.15s) / 10 = 1.27 / 10 = 0.127
(99%+99%+99%+99%+99%+99%+99%+99%+99%+99%) / 10 = 990 / 10 = 99


Therefore:

* Average Execution Time(Based on ctime): 2314.087 ms
* Average Execution Time(Based on chrono): 2315.108 ms
* Average Memory Usage: 0 KB
* Average Real Time: 4.78 s
* Average User Time: 4.648 s
* Average Sys Time: 0.127 s
* Average CPU Usage: 99 %

همونطور که میبینید زمان اوررایت کردن برابری میکنه با زمان رایت کردن.
نکته1: قسمت مد نظر ما برای مقایسه صرفاً زمانی هست که اون سگمنت بخصوص کد یعنی:

for(int i = 0; i < 1073741824 ; i++)
        arr[i] = 'B'; 

انجام میشده. که در‌واقع میشه:

* Average Execution Time(Based on ctime): 2314.087 ms
* Average Execution Time(Based on chrono): 2315.108 ms

نکته2: میزان مموری مصرفی این سگمنت کد 0 ریپورت شده چون هیچ مموری الوکیشن جدیدی نداشتیم (در حقیقت داشتیم مثلاً برای شمارنده حلقه فور، ولی اینقدر کوشولو هست که توی اوردر کیلوبایت دیده نشده) – وقتی ما حافظه‌ای نیو نکردیم، و صرفاً قبلی رو اوورایت کردیم مموری یوزیج جدیدی ریپورت نشده. ولی در‌واقع ما با 1 گیگابایت مموری کار کردیم.


حالا بریم سراغ هارددیسک، من از همون کد قبلی استفاده میکنم، منتهی این بار دیگه فایلهای 1 گیگی ساخته شده پیشین رو حذف (rm) نمیکنم تا اوررایت بشن:

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ HDD_write_test.cpp    

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out 
Execution Time (Based on ctime): 10162.1 ms
Execution Time (Based on chrono): 16532.7 ms
Memory Usage: 0 KB

real    16.54s
user    9.30s
sys     0.87s
cpu     61%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 9961.45 ms
Execution Time (Based on chrono): 19035.1 ms
Memory Usage: 0 KB

real    19.04s
user    9.10s
sys     0.86s
cpu     52%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 9925.02 ms
Execution Time (Based on chrono): 19885.7 ms
Memory Usage: 0 KB

real    19.89s
user    9.14s
sys     0.79s
cpu     49%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 9927.78 ms
Execution Time (Based on chrono): 20518.4 ms
Memory Usage: 0 KB

real    20.52s
user    9.04s
sys     0.89s
cpu     48%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 9996.59 ms
Execution Time (Based on chrono): 17915.4 ms
Memory Usage: 0 KB

real    17.92s
user    9.16s
sys     0.84s
cpu     55%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 9659.78 ms
Execution Time (Based on chrono): 19085.9 ms
Memory Usage: 0 KB

real    19.09s
user    8.91s
sys     0.76s
cpu     50%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 10051.7 ms
Execution Time (Based on chrono): 19261.9 ms
Memory Usage: 0 KB

real    19.27s
user    9.25s
sys     0.81s
cpu     52%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 10124.3 ms
Execution Time (Based on chrono): 19965.3 ms
Memory Usage: 0 KB

real    19.97s
user    9.31s
sys     0.82s
cpu     50%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 9867.27 ms
Execution Time (Based on chrono): 19433.7 ms
Memory Usage: 0 KB

real    19.44s
user    9.05s
sys     0.82s
cpu     50%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 9850.91 ms
Execution Time (Based on chrono): 18046 ms
Memory Usage: 0 KB

real    18.05s
user    8.96s
sys     0.89s
cpu     54%

متوسط میگیریم:

(10162.1+9961.45+9925.02+9927.78+9996.59+9659.78+10051.7+10124.3+9867.27+9850.91) / 10 = 99526.9 / 10 = 9952.69
(16532.7+19035.1+19885.7+20518.4+17915.4+19085.9+19261.9+19965.3+19433.7+18046) / 10 = 189680.1 / 10 = 18968.01
(0+0+0+0+0+0+0+0+0+0) / 10 = 0 / 10 = 0
(16.54s+19.04s+19.89s+20.52s+17.92s+19.09s+19.27s+19.97s+19.44s+18.05s) / 10 = 189.73 / 10 = 18.973
(9.30s+9.10s+9.14s+9.04s+9.16s+8.91s+9.25s+9.31s+9.05s+8.96s) / 10 = 91.22 / 10 = 9.122
(0.87s+0.86s+0.79s+0.89s+0.84s+0.76s+0.81s+0.82s+0.82s+0.89s) / 10 = 8.35 / 10 = 0.835
(61%+52%+49%+48%+55%+50%+52%+50%+50%+54%) / 10 = 521 / 10 = 52.1


Therefore:

* Average Execution Time(Based on ctime): 9952.69 ms
* Average Execution Time(Based on chrono): 18968.01 ms
* Average Memory Usage: 0 KB
* Average Real Time: 18.973 s
* Average User Time: 9.122 s
* Average Sys Time: 0.835 s
* Average CPU Usage: 52.1 %

اهوع! نتیجه 10 برابر کندتر شد. اما هنوز صبر کنید:)) داستان ادامه داره…


نکته1: به زمان اجرای اولین اوررایت HDD نگاه کنید و به زمان متوسط محاسبه شده نگاه کنید، و متوجه میشین که چرا گفتم هر آزمایش رو باید حداقل چندین بار تکرار کنیم.


نکته2: همونطور که میبینین زمان محاسبه شده توسط chrono خیلی بیشتر (تقریباً دو برابر) زمان محاسبه شده توسط ctime هست و زمان واقعی اجرای اون بلاک کد رو بیان میکنه. اما چرا؟
داستان یچیزی شبیه اون زمانهای real و user و sys هست که توی بحث کامند time گفتم، دلیل علمی اینه که این دو کتابخونه زمان رو به روشهای متفاوتی محاسبه میکنن. Ctime یه کتابخونه مختص زبان سی هست که اینجا با استفاده از فانکشن clock() زمان رو محاسبه میکنه، اما نه زمان دقیق رو، بلکه زمانی رو که CPU صرف محاسبات این پراسس فعلی کرده. اما این گزاره بازم دقیق نیست، یکمی به زبان تخصصی تر میگم، سی‌تایم با استفاده از فانکشن کلاک، تعداد کلاکهایی که CPU حین محاسبات همین برنامه بخصوص زده رو ثبت میکنه، و سپس معادل این کلاکهارو به زمان ثانیه‌ای بیان میکنه. صرفاً یعنی CPU روی این پراسس خاص چند تا کلاک زده، این معنیش اینه که زمانی که ما داشتیم I/O میزدیم و یا منتظر ریسورس یا I/O بلاک بودیم یا منتظر دیگر پراسسها بودیم رو توی محاسباتش دخیل نمیکنه، در صورتی که سنجش میزان زمان I/O اصلاً بخش بزرگی از محاسبات ماست! اما chrono داستانی کاملاً متفاوت داره…
کتابخونه chrono زمانی که روی متد های‌رزولوشن (high_resolution_clock) کال میشه، به اصطلاح زمان دقیق ساعت دیواری رو محاسبه میکنه، از نقطه شروع تا نقطه پایان. این زمان شامل اینتراپتها و I/O های داستان هم هست. پس این زمان دقیقی هست که باهاش مقایسه رو انجام میدیم.




خب حالا بیاین دامنه مقایسه رو کمی گسترش بدیم، فرض کنید میخوایم یه کپی پیست ساده رو توی RAM و توی HDD مقایسه کنیم، برای رم کد زیر رو در نظر بگیرین:

#include <iostream>
#include <sys/resource.h>
#include <chrono>

using namespace std;

int main() {

    char* arr = new char[1073741824];
    for(int i = 0; i < 1073741824 ; i++)
        arr[i] = 'A';

    // Start execution time
    clock_t start_1 = clock();
    auto start_2 = chrono::high_resolution_clock::now();

    // Start memory usage
    struct rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_start = usage.ru_maxrss; // in kilobytes

    // Code ----------------------------------------------------------
    char* arr_2 = new char[1073741824];
    for(int i = 0; i < 1073741824 ; i++)
        arr_2[i] = arr[i];    
    // ---------------------------------------------------------------

    // Stop measuring memory usage
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_end = usage.ru_maxrss; // in kilobytes

    // Stop measuring execution time
    clock_t end_1 = clock();
    auto end_2 = chrono::high_resolution_clock::now();
    double execution_time_1 = double(end_1 - start_1) / CLOCKS_PER_SEC;
    chrono::duration<double, milli> execution_time_2 = end_2 - start_2;

    // Printing result
    cout << "Execution Time (Based on ctime): " << execution_time_1 * 1000.0 << " ms" << endl;
    cout << "Execution Time (Based on chrono): " << execution_time_2.count() << " ms" << endl;
    cout << "Memory Usage: " << memory_usage_end - memory_usage_start << " KB" << endl;

    return 0;
}

فایل کد


و یه راست بریم سراغ اجرا:

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ RAM_copy_test.cpp     

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2676.01 ms
Execution Time (Based on chrono): 2676.22 ms
Memory Usage: 1048824 KB

real    5.12s
user    4.89s
sys     0.23s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2616.64 ms
Execution Time (Based on chrono): 2616.71 ms
Memory Usage: 1048764 KB

real    5.06s
user    4.85s
sys     0.20s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2618.32 ms
Execution Time (Based on chrono): 2618.4 ms
Memory Usage: 1048712 KB

real    5.02s
user    4.81s
sys     0.20s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2616.12 ms
Execution Time (Based on chrono): 2616.2 ms
Memory Usage: 1048824 KB

real    5.05s
user    4.80s
sys     0.24s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2617.68 ms
Execution Time (Based on chrono): 2617.75 ms
Memory Usage: 1048824 KB

real    5.05s
user    4.88s
sys     0.17s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2620.01 ms
Execution Time (Based on chrono): 2620.11 ms
Memory Usage: 1048824 KB

real    5.06s
user    4.86s
sys     0.20s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2620.11 ms
Execution Time (Based on chrono): 2620.16 ms
Memory Usage: 1048824 KB

real    5.02s
user    4.79s
sys     0.23s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2615.65 ms
Execution Time (Based on chrono): 2615.84 ms
Memory Usage: 1048764 KB

real    5.03s
user    4.78s
sys     0.25s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2623.07 ms
Execution Time (Based on chrono): 2623.13 ms
Memory Usage: 1048780 KB

real    5.03s
user    4.86s
sys     0.17s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 2616.85 ms
Execution Time (Based on chrono): 2616.94 ms
Memory Usage: 1048780 KB

real    5.07s
user    4.87s
sys     0.20s
cpu     99%

و اوریج نتیجه:

(2676.01+2616.64+2618.32+2616.12+2617.68+2620.01+2620.11+2615.65+2623.07+2616.85) / 10 = 26240.46 / 10 = 2624.046
(2676.22+2616.71+2618.4+2616.2+2617.75+2620.11+2620.16+2615.84+2623.13+2616.94) / 10 = 26241.46 / 10 = 2624.146
(1048824+1048764+1048712+1048824+1048824+1048824+1048824+1048764+1048780+1048780) / 10 = 10487920 / 10 = 1048792
(5.12s+5.06s+5.02s+5.05s+5.05s+5.06s+5.02s+5.03s+5.03s+5.07s) / 10 = 50.51 / 10 = 5.051
(4.89s+4.85s+4.81s+4.80s+4.88s+4.86s+4.79s+4.78s+4.86s+4.87s) / 10 = 48.39 / 10 = 4.839
(0.23s+0.20s+0.20s+0.24s+0.17s+0.20s+0.23s+0.25s+0.17s+0.20s) / 10 = 2.09 / 10 = 0.209
(99%+99%+99%+99%+99%+99%+99%+99%+99%+99%) / 10 = 990 / 10 = 99


Therefore:

* Average Execution Time(Based on ctime): 2624.046 ms
* Average Execution Time(Based on chrono): 2624.146 ms
* Average Memory Usage: 1048792 KB
* Average Real Time: 5.051 s
* Average User Time: 4.839 s
* Average Sys Time: 0.209 s
* Average CPU Usage: 99 %



حالا کپی کردن همون 1 گیگابایت دیتا از روی دیسک، روی همون دیسک ولی یه جای دیگه‌ش، مثلاً توی یه پارتیشن دیگه^_^:

#include <iostream>
#include <fstream>
#include <sys/resource.h>
#include <chrono>

using namespace std;

int main() {

    char chunk;
    ifstream infile;
    ofstream outfile;

    // Start execution time
    clock_t start_1 = clock();
    auto start_2 = chrono::high_resolution_clock::now();

    // Start memory usage
    struct rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_start = usage.ru_maxrss; // in kilobytes

    // Code ----------------------------------------------------------
    infile.open("output.txt");
    outfile.open("/media/user/MyDrive1/output_copy.txt");
    if (!outfile.is_open()) {
        cout << "Error opening file!" << endl;
        return 1;
    }
    while (infile.get(chunk))
        outfile.put(chunk);
    infile.close();
    outfile.close();
    // ---------------------------------------------------------------

    // Stop measuring memory usage
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_end = usage.ru_maxrss; // in kilobytes

    // Stop measuring execution time
    clock_t end_1 = clock();
    auto end_2 = chrono::high_resolution_clock::now();
    double execution_time_1 = double(end_1 - start_1) / CLOCKS_PER_SEC;
    chrono::duration<double, milli> execution_time_2 = end_2 - start_2;

    // Printing result
    cout << "Execution Time (Based on ctime): " << execution_time_1 * 1000.0 << " ms" << endl;
    cout << "Execution Time (Based on chrono): " << execution_time_2.count() << " ms" << endl;
    cout << "Memory Usage: " << memory_usage_end - memory_usage_start << " KB" << endl;

    return 0;
}

فایل کد


اجرا:

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ HDD_copy_test.cpp

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
Execution Time (Based on ctime): 18386.5 ms
Execution Time (Based on chrono): 25923.6 ms
Memory Usage: 0 KB

real    25.93s
user    16.58s
sys     1.81s
cpu     70%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm /media/user/MyDrive1/output_copy.txt && !!

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm /media/user/MyDrive1/output_copy.txt && time ./a.out
Execution Time (Based on ctime): 17681.3 ms
Execution Time (Based on chrono): 23741.9 ms
Memory Usage: 0 KB

real    23.74s
user    15.98s
sys     1.70s
cpu     74%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm /media/user/MyDrive1/output_copy.txt && time ./a.out
Execution Time (Based on ctime): 17245.1 ms
Execution Time (Based on chrono): 24897.7 ms
Memory Usage: 0 KB

real    24.90s
user    15.49s
sys     1.76s
cpu     69%


┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && dd if=/dev/random bs=1024 count=1048576 > output.txt      
1048576+0 records in
1048576+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 10.1874 s, 105 MB/s

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm /media/user/MyDrive1/output_copy.txt && time ./a.out              
Execution Time (Based on ctime): 19407.6 ms
Execution Time (Based on chrono): 33033.6 ms
Memory Usage: 0 KB

real    33.04s
user    17.42s
sys     1.99s
cpu     58%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && dd if=/dev/random bs=1024 count=1048576 > output.txt
1048576+0 records in
1048576+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 10.4907 s, 102 MB/s

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm /media/user/MyDrive1/output_copy.txt && time ./a.out              
Execution Time (Based on ctime): 20163.5 ms
Execution Time (Based on chrono): 36565.9 ms
Memory Usage: 0 KB

real    36.57s
user    18.03s
sys     2.13s
cpu     55%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && dd if=/dev/random bs=1024 count=1048576 > output.txt
1048576+0 records in
1048576+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 10.1993 s, 105 MB/s

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm /media/user/MyDrive1/output_copy.txt && time ./a.out              
Execution Time (Based on ctime): 20450.9 ms
Execution Time (Based on chrono): 38170.3 ms
Memory Usage: 0 KB

real    38.17s
user    18.30s
sys     2.15s
cpu     53%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && dd if=/dev/random bs=1024 count=1048576 > output.txt
1048576+0 records in
1048576+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 10.1726 s, 106 MB/s

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm /media/user/MyDrive1/output_copy.txt && time ./a.out              
Execution Time (Based on ctime): 20228.9 ms
Execution Time (Based on chrono): 33791.1 ms
Memory Usage: 0 KB

real    33.79s
user    18.12s
sys     2.11s
cpu     59%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && dd if=/dev/random bs=1024 count=1048576 > output.txt
1048576+0 records in
1048576+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 10.2377 s, 105 MB/s

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm /media/user/MyDrive1/output_copy.txt && time ./a.out              
Execution Time (Based on ctime): 20001.4 ms
Execution Time (Based on chrono): 35478 ms
Memory Usage: 0 KB

real    35.48s
user    17.79s
sys     2.21s
cpu     56%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && dd if=/dev/random bs=1024 count=1048576 > output.txt
1048576+0 records in
1048576+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 10.5428 s, 102 MB/s

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm /media/user/MyDrive1/output_copy.txt && time ./a.out              
Execution Time (Based on ctime): 19954.7 ms
Execution Time (Based on chrono): 34560.4 ms
Memory Usage: 0 KB

real    34.56s
user    17.55s
sys     2.41s
cpu     57%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm output.txt && dd if=/dev/random bs=1024 count=1048576 > output.txt
1048576+0 records in
1048576+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 10.1674 s, 106 MB/s

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ rm /media/user/MyDrive1/output_copy.txt && time ./a.out              
Execution Time (Based on ctime): 21618.5 ms
Execution Time (Based on chrono): 39370.6 ms
Memory Usage: 0 KB

real    39.37s
user    19.18s
sys     2.44s
cpu     54%

متوسط زمان:

(18386.5+17681.3+17245.1+19407.6+20163.5+20450.9+20228.9+20001.4+19954.7+21618.5) / 10 = 195138.4 / 10 = 19513.84
(25923.6+23741.9+24897.7+33033.6+36565.9+38170.3+33791.1+35478+34560.4+39370.6) / 10 = 325533.1 / 10 = 32553.31
(0+0+0+0+0+0+0+0+0+0) / 10 = 0 / 10 = 0
(25.93s+23.74s+24.90s+33.04s+36.57s+38.17s+33.79s+35.48s+34.56s+39.37s) / 10 = 325.55 / 10 = 32.555
(16.58s+15.98s+15.49s+17.42s+18.03s+18.30s+18.12s+17.79s+17.55s+19.18s) / 10 = 174.44 / 10 = 17.444
(1.81s+1.70s+1.76s+1.99s+2.13s+2.15s+2.11s+2.21s+2.41s+2.44s) / 10 = 20.71 / 10 = 2.071
(70%+74%+69%+58%+55%+53%+59%+56%+57%+54%) / 10 = 605 / 10 = 60.5


Therefore:

* Average Execution Time(Based on ctime): 19513.84 ms
* Average Execution Time(Based on chrono): 32553.31 ms
* Average Memory Usage: 0 KB
* Average Real Time: 32.555 s
* Average User Time: 17.444 s
* Average Sys Time: 2.071 s
* Average CPU Usage: 60.5 %

اینجا من یه حقه ظریف پیاده‌سازی کردم:))


فقط به زبان تخصصی توضیحش میدم، با کپی کردن سریع توی رنج 20 ثانیه فهمیدم که یه بهینه‌سازی اون زیر در جریانه، ممکنه فایل توسط یه موجودیتی کش شده باشه – سیستم عامل یا ماژولهای API مربوط به I/O – (و میبینیم که در عمل مسائل تئوریک چطوری جلوی واقعی پیدا میکنن) و از اونجایی که آنتروپی فایل خیـــلی پایینه، (چون همش اسکی «A» هست) شاید آزمایش ما متأثر از بهینگی هایی باشه که قبلتر بصورت تئوریک توضیح دادم، برای همین منظور، با دستورات زیر 1 گیگابایت اطلاعات رندوم از آنتروپی سیستم گرفتم به جای فایل Low-entropyمون گذاشتم و دیدیم که زمان بسیار طولانی‌تر شد (حتی تا 20 برابر طولانی تر).

rm output.txt && dd if=/dev/random bs=1024 count=1048576 > output.txt



میخوام مقایسه آخرو کنم و روند کارو عوض کنم، برای این منظور مقایسه رو به شمایلی انجام میدیم که چندتا پروسس بطور موازی دارن ریسورس رو مصرف میکنن و مثلاً با هارددیسک یا رم تعامل مستقیم دارن… تا ببینیم وقتی دیوایس ذخیره سازی ما تحت دسترسی مشترکه، چه میزان زمان خدمت دهیش میاد پایین، چه در رم چه در دیسک.
از اونچیزایی که توی تئوری گفتیم میدونیم رم براش فرقی نداره و سرعتش خیــــلی متأثر از این موضوع نیست، پس نباید خیلی زیاد کندتر بشه، اما دیسک بخاطر حرکات فیزیکیش، احتمالاً باید بشدت سرعتش نابود بشه، بریم و در عمل ببینیم:


برنامه زیر کارش خوردن رمه! 1 گیگابایت از رمو میگیره و هی پر و خالی میکنه:

#include <iostream>

using namespace std;

int main() {

    cout << "EATING RAM!!!" << endl;
    while( true )
    {
        char* arr = new char[1073741824];
        for(int i = 0; i < 1073741824 ; i++)
            arr[i] = 'A';
        delete arr;
    }

    return 0;
}

فایل کد


من چهارتا پراسس از این برنامه بطور موازی اجرا میکنم:

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ RAM_eater.cpp

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ ./a.out
EATING RAM!!!
┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ ./a.out
EATING RAM!!!
┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ ./a.out
EATING RAM!!!
┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ ./a.out
EATING RAM!!!

Executing RAM-eaters


و خروجی top وقتی چهارتا پراسس رمخور در حال اجرا هستن:


top command result


حالا بطور همزمان با اینها، برنامه اولمون یعنی اینو اجرا میکنم:

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ RAM_write_test.cpp -o test.out

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./test.out                   
Execution Time (Based on ctime): 3638.12 ms
Execution Time (Based on chrono): 3638.24 ms
Memory Usage: 1047004 KB

real    3.67s
user    3.45s
sys     0.22s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./test.out
Execution Time (Based on ctime): 3539.23 ms
Execution Time (Based on chrono): 3539.71 ms
Memory Usage: 1046948 KB

real    3.56s
user    3.36s
sys     0.20s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./test.out
Execution Time (Based on ctime): 3587.88 ms
Execution Time (Based on chrono): 3588.17 ms
Memory Usage: 1046956 KB

real    3.63s
user    3.43s
sys     0.20s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./test.out
Execution Time (Based on ctime): 3629.68 ms
Execution Time (Based on chrono): 3630.07 ms
Memory Usage: 1046968 KB

real    3.67s
user    3.43s
sys     0.24s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./test.out
Execution Time (Based on ctime): 3568.61 ms
Execution Time (Based on chrono): 3568.84 ms
Memory Usage: 1046920 KB

real    3.59s
user    3.39s
sys     0.21s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./test.out
Execution Time (Based on ctime): 3578.81 ms
Execution Time (Based on chrono): 3578.97 ms
Memory Usage: 1046828 KB

real    3.61s
user    3.39s
sys     0.22s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./test.out
Execution Time (Based on ctime): 3585.52 ms
Execution Time (Based on chrono): 3585.62 ms
Memory Usage: 1046760 KB

real    3.61s
user    3.33s
sys     0.28s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./test.out
Execution Time (Based on ctime): 3566.91 ms
Execution Time (Based on chrono): 3567.07 ms
Memory Usage: 1046944 KB

real    3.60s
user    3.37s
sys     0.22s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./test.out
Execution Time (Based on ctime): 3594.36 ms
Execution Time (Based on chrono): 3594.45 ms
Memory Usage: 1046972 KB

real    3.63s
user    3.39s
sys     0.24s
cpu     99%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./test.out
Execution Time (Based on ctime): 3584.68 ms
Execution Time (Based on chrono): 3588.76 ms
Memory Usage: 1046840 KB

real    3.62s
user    3.35s
sys     0.27s
cpu     99%

و متوسط آزمایش:

(3638.12+3539.23+3587.88+3629.68+3568.61+3578.81+3585.52+3566.91+3594.36+3584.68) / 10 = 35873.8 / 10 = 3587.38
(3638.24+3539.71+3588.17+3630.07+3568.84+3578.97+3585.62+3567.07+3594.45+3588.76) / 10 = 35879.9 / 10 = 3587.99
(1047004+1046948+1046956+1046968+1046920+1046828+1046760+1046944+1046972+1046840) / 10 = 10469140 / 10 = 1046914
(3.67s+3.56s+3.63s+3.67s+3.59s+3.61s+3.61s+3.60s+3.63s+3.62s) / 10 = 36.19 / 10 = 3.619
(3.45s+3.36s+3.43s+3.43s+3.39s+3.39s+3.33s+3.37s+3.39s+3.35s) / 10 = 33.89 / 10 = 3.389
(0.22s+0.20s+0.20s+0.24s+0.21s+0.22s+0.28s+0.22s+0.24s+0.27s) / 10 = 2.3 / 10 = 0.23
(99%+99%+99%+99%+99%+99%+99%+99%+99%+99%) / 10 = 990 / 10 = 99


Therefore:

* Average Execution Time(Based on ctime): 3587.38 ms
* Average Execution Time(Based on chrono): 3587.99 ms
* Average Memory Usage: 1046914 KB
* Average Real Time: 3.619 s
* Average User Time: 3.389 s
* Average Sys Time: 0.23 s
* Average CPU Usage: 99 %

میبینیم که متوسط زمان حدوداً 1.5 برابر شده، البته این افزایش زمان لزوماً به معنی کند شدن چیپ رم نیست، ممکنه بخاطر شلوغ شدن باس رم، یا شلوغ شدن ماژول سیستم عاملی رم، یا شلوغ شدن اون API که پراسسا باهاش تعامل میکنن برای تخصیص مموری، یا حتی شلوغ شدن سر پردازنده باشه..!
برای اینکه مطمئن بشیم بخاطر پردازنده نیست، آزمایش بالا رو بصورت مالتی‌تردینگ یا چندنخی تکرار میکنم و هر رم-خور رو روی یه هسته جدا میذارم و همچنین پراسس آزمون هم روی یه هسته جدا میذارم (جمعا 5 هسته)
به زبان ساده، یه برنامه چندنخی محاسبات نخهای متفاوت رو روی هسته های متفاوت میچینه، با این کار ما مطمئن میشیم کندی سرعت صرفاً بخاطر شلوغی پردازنده نیست….(بعداً راجع به چندنخی یا مالتی پراسسینگ توی یه مقاله مفصل حرف میزنیم.)




برنامه زیر رو در نظر بگیرید:

#include <iostream>
#include <sys/resource.h>
#include <chrono>
#include <thread>
#include <vector>

using namespace std;

void ram_eater()
{
    cout << "A ram-eater started eating!" << endl;
    while( true )
    {
        char* arr = new char[1073741824];
        for(int i = 0; i < 1073741824 ; i++)
            arr[i] = 'A';
        delete arr;
    }
}

void test()
{
    for( int i = 0; i < 10; i++ )
    {
        // Start execution time
        clock_t start_1 = clock();
        auto start_2 = chrono::high_resolution_clock::now();

        // Start memory usage
        struct rusage usage;
        getrusage(RUSAGE_SELF, &usage);
        long memory_usage_start = usage.ru_maxrss; // in kilobytes

        // Code ----------------------------------------------------------
        char* arr = new char[1073741824];
        for(int j = 0; j < 1073741824 ; j++)
            arr[j] = 'A';

        // ---------------------------------------------------------------

        // Stop measuring memory usage
        getrusage(RUSAGE_SELF, &usage);
        long memory_usage_end = usage.ru_maxrss; // in kilobytes

        // Stop measuring execution time
        clock_t end_1 = clock();
        auto end_2 = chrono::high_resolution_clock::now();
        double execution_time_1 = double(end_1 - start_1) / CLOCKS_PER_SEC;
        chrono::duration<double, milli> execution_time_2 = end_2 - start_2;

        // Printing result
        cout << "Execution Time (Based on ctime): " << execution_time_1 * 1000.0 << " ms" << endl;
        cout << "Execution Time (Based on chrono): " << execution_time_2.count() << " ms" << endl;
        cout << "Memory Usage: " << memory_usage_end - memory_usage_start << " KB" << endl;

        // Free memory to prevent memory-leak
        delete arr;

        // Sleep for 10 seconds
        this_thread::sleep_for(chrono::milliseconds(10000)); 
    }
}

int main() {
    vector<thread> threads;

    threads.emplace_back(ram_eater);
    threads.emplace_back(ram_eater);
    threads.emplace_back(ram_eater);
    threads.emplace_back(ram_eater);

    threads.emplace_back(test);

    // Wait for test to be over
    threads[4].join();

    return 0;
}

فایل کد


اجرا:


Executing RAM_eating_multithreading_test.cpp

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ RAM_eating_multithreading_test.cpp

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ ./a.out                               
A ram-eater started eating!
A ram-eater started eating!
A ram-eater started eating!
A ram-eater started eating!
Execution Time (Based on ctime): 12877.4 ms
-Execution Time (Based on chrono): 2576.37 ms
Memory Usage: 4595268 KB
Execution Time (Based on ctime): 14381.2 ms
-Execution Time (Based on chrono): 2879.22 ms
Memory Usage: 0 KB
Execution Time (Based on ctime): 18355.6 ms
-Execution Time (Based on chrono): 3672.86 ms
Memory Usage: 0 KB
Execution Time (Based on ctime): 18452.8 ms
-Execution Time (Based on chrono): 3692.51 ms
Memory Usage: 0 KB
Execution Time (Based on ctime): 17189.4 ms
-Execution Time (Based on chrono): 3442.85 ms
Memory Usage: 0 KB
Execution Time (Based on ctime): 18136.1 ms
-Execution Time (Based on chrono): 3625.81 ms
Memory Usage: 0 KB
Execution Time (Based on ctime): 17982.1 ms
-Execution Time (Based on chrono): 3599.67 ms
Memory Usage: 0 KB
Execution Time (Based on ctime): 18238.8 ms
-Execution Time (Based on chrono): 3648.24 ms
Memory Usage: 0 KB
Execution Time (Based on ctime): 18639.8 ms
-Execution Time (Based on chrono): 3729.46 ms
Memory Usage: 0 KB
Execution Time (Based on ctime): 18598.2 ms
-Execution Time (Based on chrono): 3719.59 ms
Memory Usage: 0 KB
terminate called without an active exception
zsh: IOT instruction  ./a.out

میبینین که برنامه داره روی چند هسته اجرا میشه و از اونجایی که همه چی تحت یه پراسس هست، زمان ctime و میزان مموری مصرفی داده‌های پرتی هستن که بدرد آزمایش ما نمیخورن، فقط زمان chrono که به رنگ قرمز (علامت – مارکداون) مشخص کردم زمان درستی هست که باید توی مقایسه دخیل بشه، متوسط زمان به شرح زیره:

(2576.37+2879.22+3672.86+3692.51+3442.85+3625.81+3599.67+3648.24+3729.46+3719.59) / 10 = 34586.58 / 10 = 3458.658

Therefore:

* Average Execution Time(Based on chrono): 3458.658 ms

متوسط زمان بصورت چندنخی بدست اومد 3458.658 میلی‌ثانیه که تقریباً برابر با همون متوسط زمان چندپراسسی یعنی 3587.99 میلی‌ثانیه برابر هست. پس میتونیم ضمن تخصیص 100 میلی ثانیه بطور متوسط به اتلاف وقت پردازنده، با قطعیت بگیم که رم تحت یه سیستم یونیکسی، حین دسترسی مشترک – اونم بصورت مرگبار! - فقط 1.5 برابر کند تر میشه.
اینکه گفتم بصورت مرگبار، هر بار مانیتورینگ رم رو توی لاگ htop که فرستادم بینید که متوجه بشین رم چقدر درگیر بوده.




حالا بریم سراغ همین دسترسی مشترک توی هارددیسک، برای این منظور یه برنامه دیسک-خور مینویسیم!:

#include <iostream>
#include <fstream>
#include <signal.h>
#include <ctime>

using namespace std;

ofstream outfile;

void signalHandler(int signum) {
    outfile.close();
    cout << "Interrupt signal received. File closed." << endl;
    exit(signum);
}

int main() {
    signal(SIGINT, signalHandler);
    srand(time(NULL));
    char character = 'A';
    string filename = to_string(rand()) + ".txt";

    cout << "EATING HDD!!!" << endl;


    while (true) {

        outfile.open(filename);
        if (!outfile.is_open()) {
            cout << "Error opening file: " << filename << endl;
            return 1;
        }

        for (int i = 0; i < 1073741824; i++) {
            outfile << character;
        }

        outfile.close();
    }

    return 0;
}

فایل کد


یه توضیح مختصری بدم، این برنامه یسری فایل با اسم رندوم میسازه و توی هر کدوم 1 گیگابایت دیتا مینویسه و وقتی فرایند نوشتن تموم شد، دوباره شروع میکنه و از اول مینویسه. این فرایند تا بینهایت ادامه پیدا میکنه مگر اینکه یه سیگنال وقفه برای برنامه ارسال بشه. به محض دریافت وقفه، فایل رو میبنده و برنامه به اتمام میرسه.

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ HDD_eater.cpp -o HDD_eater.out

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ ./HDD_eater.out 
EATING HDD!!!
┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ ./HDD_eater.out 
EATING HDD!!!
┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ ./HDD_eater.out 
EATING HDD!!!
┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ ./HDD_eater.out 
EATING HDD!!!

Executing HDD-eaters


و حین همین ماجرا، این برنامه رو اجرا میکنم:

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ HDD_write_test.cpp -o HDD_write.out

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out 
Execution Time (Based on ctime): 11230.8 ms
Execution Time (Based on chrono): 25468.1 ms
Memory Usage: 0 KB

real    25.48s
user    10.30s
sys     0.93s
cpu     44%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 11096.1 ms
Execution Time (Based on chrono): 20764 ms
Memory Usage: 0 KB

real    20.77s
user    10.16s
sys     0.94s
cpu     53%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 13815.2 ms
Execution Time (Based on chrono): 32682 ms
Memory Usage: 0 KB

real    32.68s
user    12.63s
sys     1.18s
cpu     42%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 15544.6 ms
Execution Time (Based on chrono): 47560 ms
Memory Usage: 0 KB

real    47.57s
user    13.91s
sys     1.64s
cpu     32%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 16873.7 ms
Execution Time (Based on chrono): 45354.9 ms
Memory Usage: 0 KB

real    45.36s
user    15.25s
sys     1.63s
cpu     37%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 15391.3 ms
Execution Time (Based on chrono): 39712.6 ms
Memory Usage: 0 KB

real    39.92s
user    13.94s
sys     1.46s
cpu     38%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 14051.7 ms
Execution Time (Based on chrono): 29361.3 ms
Memory Usage: 0 KB

real    29.36s
user    12.61s
sys     1.44s
cpu     47%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 13137.5 ms
Execution Time (Based on chrono): 35374 ms
Memory Usage: 0 KB

real    35.64s
user    11.94s
sys     1.21s
cpu     36%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 13510.7 ms
Execution Time (Based on chrono): 28392.7 ms
Memory Usage: 0 KB

real    28.40s
user    12.42s
sys     1.10s
cpu     47%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 13595 ms
Execution Time (Based on chrono): 44944.2 ms
Memory Usage: 0 KB

real    44.95s
user    12.24s
sys     1.35s
cpu     30%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 18275.6 ms
Execution Time (Based on chrono): 70660.9 ms
Memory Usage: 0 KB

real    70.66s
user    16.16s
sys     2.11s
cpu     25%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 17255 ms
Execution Time (Based on chrono): 49479.4 ms
Memory Usage: 0 KB

real    49.48s
user    15.43s
sys     1.82s
cpu     34%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 15195.9 ms
Execution Time (Based on chrono): 52613.5 ms
Memory Usage: 0 KB

real    52.62s
user    13.64s
sys     1.56s
cpu     28%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 14688.6 ms
Execution Time (Based on chrono): 54965.7 ms
Memory Usage: 0 KB

real    54.97s
user    13.33s
sys     1.36s
cpu     26%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 18287.1 ms
Execution Time (Based on chrono): 61944 ms
Memory Usage: 0 KB

real    61.95s
user    16.30s
sys     1.98s
cpu     29%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 21118.9 ms
Execution Time (Based on chrono): 70709.4 ms
Memory Usage: 0 KB

real    70.71s
user    19.07s
sys     2.05s
cpu     29%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 24345 ms
Execution Time (Based on chrono): 82900.9 ms
Memory Usage: 0 KB

real    82.90s
user    21.94s
sys     2.41s
cpu     29%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 18640.5 ms
Execution Time (Based on chrono): 56225.7 ms
Memory Usage: 0 KB

real    56.23s
user    16.70s
sys     1.94s
cpu     33%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 17671.1 ms
Execution Time (Based on chrono): 68766 ms
Memory Usage: 0 KB

real    68.77s
user    16.09s
sys     1.58s
cpu     25%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./HDD_write.out
Execution Time (Based on ctime): 22847.9 ms
Execution Time (Based on chrono): 88525.2 ms
Memory Usage: 0 KB

real    88.53s
user    20.43s
sys     2.42s
cpu     25%
(11230.8+11096.1+13815.2+15544.6+16873.7+15391.3+14051.7+13137.5+13510.7+13595+18275.6+17255+15195.9+14688.6+18287.1+21118.9+24345+18640.5+17671.1+22847.9) / 20 = 326572.2 / 20 = 16328.61
(25468.1+20764+32682+47560+45354.9+39712.6+29361.3+35374+28392.7+44944.2+70660.9+49479.4+52613.5+54965.7+61944+70709.4+82900.9+56225.7+68766+88525.2) / 20 = 1006404.5 / 20 = 50320.225
(0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0) / 20 = 0 / 20 = 0
(25.48s+20.77s+32.68s+47.57s+45.36s+39.92s+29.36s+35.64s+28.40s+44.95s+70.66s+49.48s+52.62s+54.97s+61.95s+70.71s+82.90s+56.23s+68.77s+88.53s) / 20 = 1006.95 / 20 = 50.3475
(10.30s+10.16s+12.63s+13.91s+15.25s+13.94s+12.61s+11.94s+12.42s+12.24s+16.16s+15.43s+13.64s+13.33s+16.30s+19.07s+21.94s+16.70s+16.09s+20.43s) / 20 = 294.49 / 20 = 14.7245
(0.93s+0.94s+1.18s+1.64s+1.63s+1.46s+1.44s+1.21s+1.10s+1.35s+2.11s+1.82s+1.56s+1.36s+1.98s+2.05s+2.41s+1.94s+1.58s+2.42s) / 20 = 32.11 / 20 = 1.6055
(44%+53%+42%+32%+37%+38%+47%+36%+47%+30%+25%+34%+28%+26%+29%+29%+29%+33%+25%+25%) / 20 = 689 / 20 = 34.45


Therefore:

* Average Execution Time(Based on ctime): 16328.61 ms
* Average Execution Time(Based on chrono): 50320.225 ms
* Average Memory Usage: 0 KB
* Average Real Time: 50.3475 s
* Average User Time: 14.7245 s
* Average Sys Time: 1.6055 s
* Average CPU Usage: 34.45 %

این نمودار رو نگاه کنین، در 20 آزمایش اول، میزان زمان به این شکل کند تر شده:


HDD speed chart in 20 tests

Test# Time
1 25468.1
2 20764
3 32682
4 47560
5 45354.9
6 39712.6
7 29361.3
8 35374
9 28392.7
10 44944.2
11 70660.9
12 49479.4
13 52613.5
14 54965.7
15 61944
16 70709.4
17 82900.9
18 56225.7
19 68766
20 88525.2

نکته: من این نمودارو با استفاده از نرم‌افزار آزاد LibreOffice کشیدم.


اولاً که چیزی که از نمودار مشهوده، با‌گذشت زمان کندی یه I/O ثابت روی دیسک، حین دسترسی مشترک رشد خطی میکنه، پس میتونیم برونیابی کنیم که با گذشت زمان، زمان نوشتن روی دیسک به این صورت هی کندتر و کندتر میشه، بر خلاف رم که سیر ثابتی رو طی میکنه


دوماً که میبینیم دیسک تا 50 برابر کند تر عمل کرده، اما انتظار ما این بود که دیسک خیلی خیلی کند تر بشه، اینجا بحث همون بهینه سازی های سیستم عاملی هست. سیستم عامل اجازه نمیده که یه پراسس انحصار I/O رو روی دیسک بصورت کنترات برداره و بقیه پراسسها نتونن از دیسک استفاده کنن، برای همین به نوبت از روی پردازنده برشون میداره و منابع مشترک رو تقسیم میکنه. برای اطلاعات بیشتر میتونین مساله بن‌بست در کامپیوتر (Deadlock) و انحصار متقابل (Mutual exclusion) رو مطالعه کنین. شاید بعداً ازشون حرف زدیم.


سوماً، بهینگی سیستم عاملی تمام مبحث نیست، دیسک-خورهای ما زیاد استاندارد نیستن، چهارتا پراسس هستن که توی سکتورهای متوالی دیسک دارن یه دیتای محدود و ثابتی (که قابل کش شدنه) رو مینویسین و این حرکت رو تکرار میکنن… چی میشه اگه بجای این دیسک-خورها، از یسری دیسک-خور واقعی استفاده کنیم..!




خب بسه دیگه، من همینجا این شکل از آزمایش رو متوقف میکنم چون نمیخوام دیسکم بسوزه! اما این پرونده باز میمونه:


این مقایسه‌ای که ما انجام دادیم، یک مقایسه تک بعدی بود. صرفاً راجع به یه انباشتی از دیتا بود که به بهینه ترین حالت روی دیسک/رم نوشته میشد و تونستیم ببینیم که در سناریوهای مختلف ممکنه تا 80 برابر دیسک کندتر عمل کنه. اما این شکل آزمایش و مقایسه تمام جوانب ماجرا رو لحاظ نمیکنه. ما نیازمند یه بعد دیگری از مقایسه هستیم.


با مقاله همراه باشین که بریم سراغ فاز دوم مقایسه...




فاز دوم: مقایسه سرعت رم و هارددیسک در کار با داده‌های کوچیک و الوکیشنهای سریع و پیاپی


توی این فاز میزان زمان یه محاسباتی که بطور معمول برای ذخیره سازی از رم استفاده میکنه رو یک بار روی رم و البته یک بار روی هارددیسک (چجوری؟!) اندازه‌گیری و مقایسه میکنیم. به زبان ساده یعنی سرعت یک محاسبات خاص، که معمولاً روی رم انجام میشه رو مقایسه میکنیم با سرعت همون محاسبات به این شرط که بجای رم برای ذخیره سازی از هارددیسک استفاده کنه!!!


کد زیر رو در نظر بگیرید:

#include <iostream>
#include <sys/resource.h>
#include <chrono>
using namespace std;

int main() {

    // Start execution time
    clock_t start_1 = clock();
    auto start_2 = chrono::high_resolution_clock::now();

    // Start memory usage
    struct rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_start = usage.ru_maxrss; // in kilobytes

    // Code ----------------------------------------------------------

    unsigned long long n = 94, t1 = 0, t2 = 1, t3 = 0;

    if(n == 1)
        cout << t1 << endl;
    else if(n == 2)
        cout << t2 << endl;
    else{
        unsigned long long counter = 3;
        while (counter <= n) {
            t3 = t1 + t2;
            t1 = t2;
            t2 = t3;
            ++counter;
        }
        cout << t3 << endl;
    }

    // ---------------------------------------------------------------

    // Stop measuring memory usage
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_end = usage.ru_maxrss; // in kilobytes

    // Stop measuring execution time
    clock_t end_1 = clock();
    auto end_2 = chrono::high_resolution_clock::now();
    double execution_time_1 = double(end_1 - start_1) / CLOCKS_PER_SEC;
    chrono::duration<double, milli> execution_time_2 = end_2 - start_2;

    // Printing result
    cout << "Execution Time (Based on ctime): " << execution_time_1 * 1000.0 << " ms" << endl;
    cout << "Execution Time (Based on chrono): " << execution_time_2.count() << " ms" << endl;
    cout << "Memory Usage: " << memory_usage_end - memory_usage_start << " KB" << endl;

    return 0;
}

فایل کد


این کد جمله nم دنباله معروف فیبوناچی رو برمیگردونه. دنباله فیبوناچی مثال معروف ریاضیاتی هست که خیلی از مفاهیم برنامه نویسی رو برای یادگیری باهاش توضیح میدن. به این صورته که هر جمله جمع دو جمله قبلی هست اگر جمله اول رو 0 و جمله دوم رو 1 فرض کنیم، به این صورته:

0,1,1,2,3,5,8,13,21,34,55,89,…

این کدی که من نوشتم میتونه تا جمله 94م دنبال فیبوناچی رو محاسبه کنه، اما به بعدش بخاطر سایز long long که 8 بایته (یعنی 64 بیت) زمانی که از 2 به توان 64 یعنی 18446744073709551616 بیشتر بشه، اورفلو میکنه و پاسخ اشتباه میده (راجع به اعداد بزرگ مطالعه کنید. هینت: ‌Big-Int)


توی این کد ما تماماً متغیر هارو روی رم ذخیره کردیم، بریم و زمان اجراشو ببینیم:

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ Fibo_RAM.cpp

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out    
12200160415121876738
Execution Time (Based on ctime): 0.066 ms
Execution Time (Based on chrono): 0.035751 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     87%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.127 ms
Execution Time (Based on chrono): 0.094721 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.01s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.122 ms
Execution Time (Based on chrono): 0.08808 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.05 ms
Execution Time (Based on chrono): 0.034632 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.15 ms
Execution Time (Based on chrono): 0.111781 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.14 ms
Execution Time (Based on chrono): 0.101224 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.15 ms
Execution Time (Based on chrono): 0.111455 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.048 ms
Execution Time (Based on chrono): 0.032223 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     86%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.053 ms
Execution Time (Based on chrono): 0.037364 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.046 ms
Execution Time (Based on chrono): 0.030818 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     87%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.125 ms
Execution Time (Based on chrono): 0.09257 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     87%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.12 ms
Execution Time (Based on chrono): 0.088397 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.121 ms
Execution Time (Based on chrono): 0.089428 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     87%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.159 ms
Execution Time (Based on chrono): 0.111137 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.01s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.148 ms
Execution Time (Based on chrono): 0.110892 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.053 ms
Execution Time (Based on chrono): 0.03688 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.129 ms
Execution Time (Based on chrono): 0.096686 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.01s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.044 ms
Execution Time (Based on chrono): 0.029967 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     86%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.045 ms
Execution Time (Based on chrono): 0.029736 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     86%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.128 ms
Execution Time (Based on chrono): 0.094682 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.121 ms
Execution Time (Based on chrono): 0.088579 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     86%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.103 ms
Execution Time (Based on chrono): 0.051734 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.047 ms
Execution Time (Based on chrono): 0.030919 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.145 ms
Execution Time (Based on chrono): 0.106697 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.051 ms
Execution Time (Based on chrono): 0.034342 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.148 ms
Execution Time (Based on chrono): 0.110057 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.126 ms
Execution Time (Based on chrono): 0.094865 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.01s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.051 ms
Execution Time (Based on chrono): 0.035199 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.14 ms
Execution Time (Based on chrono): 0.102388 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.01s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.045 ms
Execution Time (Based on chrono): 0.030435 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     85%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.048 ms
Execution Time (Based on chrono): 0.034097 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     85%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.124 ms
Execution Time (Based on chrono): 0.092128 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     87%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.046 ms
Execution Time (Based on chrono): 0.031791 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.045 ms
Execution Time (Based on chrono): 0.030651 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     86%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.046 ms
Execution Time (Based on chrono): 0.031053 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     86%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.06 ms
Execution Time (Based on chrono): 0.045026 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     87%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.047 ms
Execution Time (Based on chrono): 0.031791 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.129 ms
Execution Time (Based on chrono): 0.095468 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.122 ms
Execution Time (Based on chrono): 0.087091 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.044 ms
Execution Time (Based on chrono): 0.029332 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     86%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out         
12200160415121876738
Execution Time (Based on ctime): 0.13 ms
Execution Time (Based on chrono): 0.096376 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.125 ms
Execution Time (Based on chrono): 0.091047 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.124 ms
Execution Time (Based on chrono): 0.090338 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     87%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.124 ms
Execution Time (Based on chrono): 0.090225 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.121 ms
Execution Time (Based on chrono): 0.0879 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.124 ms
Execution Time (Based on chrono): 0.091002 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     89%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.127 ms
Execution Time (Based on chrono): 0.093424 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     87%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.123 ms
Execution Time (Based on chrono): 0.090351 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.01s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.136 ms
Execution Time (Based on chrono): 0.103215 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     88%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 0.118 ms
Execution Time (Based on chrono): 0.085639 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     88%

بخاطر اینکه رنج بازه های زمان بدست اومده خیلی کوشولو بودن، من تعداد دفعات اجرا رو توی زمانهای مختلف زیادتر کردم (50 بار) که یه تخمین دقیقی از متوسط زمان داشته باشیم:

(0.066+0.127+0.122+0.05+0.15+0.14+0.15+0.048+0.053+0.046+0.125+0.12+0.121+0.159+0.148+0.053+0.129+0.044+0.045+0.128+0.121+0.103+0.047+0.145+0.051+0.148+0.126+0.051+0.14+0.045+0.048+0.124+0.046+0.045+0.046+0.06+0.047+0.129+0.122+0.044+0.13+0.125+0.124+0.124+0.121+0.124+0.127+0.123+0.136+0.118) / 50 = 4.964 / 50 = 0.09928
(0.035751+0.094721+0.08808+0.034632+0.111781+0.101224+0.111455+0.032223+0.037364+0.030818+0.09257+0.088397+0.089428+0.111137+0.110892+0.03688+0.096686+0.029967+0.029736+0.094682+0.088579+0.051734+0.030919+0.106697+0.034342+0.110057+0.094865+0.035199+0.102388+0.030435+0.034097+0.092128+0.031791+0.030651+0.031053+0.045026+0.031791+0.095468+0.087091+0.029332+0.096376+0.091047+0.090338+0.090225+0.0879+0.091002+0.093424+0.090351+0.103215+0.085639) / 50 = 3.571584 / 50 = 0.07143168
(0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0) / 50 = 0 / 50 = 0
(0.00s+0.01s+0.01s+0.00s+0.01s+0.01s+0.01s+0.00s+0.00s+0.00s+0.01s+0.01s+0.01s+0.01s+0.01s+0.00s+0.01s+0.00s+0.00s+0.01s+0.01s+0.00s+0.00s+0.01s+0.00s+0.01s+0.01s+0.00s+0.01s+0.00s+0.00s+0.01s+0.00s+0.00s+0.00s+0.00s+0.00s+0.01s+0.01s+0.00s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s) / 50 = 0.3 / 50 = 0.006
(0.00s+0.00s+0.00s+0.00s+0.01s+0.01s+0.00s+0.00s+0.00s+0.00s+0.01s+0.01s+0.00s+0.00s+0.01s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.01s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.01s+0.00s+0.00s+0.00s) / 50 = 0.07 / 50 = 0.0014
(0.00s+0.01s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.01s+0.00s+0.00s+0.01s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.01s+0.00s+0.01s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.01s+0.00s+0.00s) / 50 = 0.06 / 50 = 0.0012
(87%+88%+88%+89%+88%+88%+89%+86%+88%+87%+87%+88%+87%+88%+88%+89%+88%+86%+86%+89%+86%+89%+88%+89%+88%+89%+88%+89%+89%+85%+85%+87%+88%+86%+86%+87%+88%+89%+89%+86%+88%+89%+87%+88%+88%+89%+87%+88%+88%+88%) / 50 = 4385 / 50 = 87.7


Therefore:

* Average Execution Time(Based on ctime): 0.09928 ms
* Average Execution Time(Based on chrono): 0.07143168 ms
* Average Memory Usage: 0 KB
* Average Real Time: 0.006 s
* Average User Time: 0.0014 s
* Average Sys Time: 0.0012 s
* Average CPU Usage: 87.7 %

حالا بیاین همین برنامه رو به شکلی بنویسیم که متغیرهایی که استفاده میکنه رو بجای رم روی دیسک ذخیره کنه!

#include <iostream>
#include <sys/resource.h>
#include <chrono>
#include <fstream>
#include <string>
using namespace std;

void set_unsigned_long_long_variable(string name, unsigned long long var)
{
    ofstream outfile(name + ".bin"  , ofstream::binary);
    if (outfile)
    {
        outfile.write(reinterpret_cast<const char*>(&var), sizeof(var));
        outfile.close();
    }
    else cerr << "Error opening file: " << name + ".bin" << endl;
}

unsigned long long get_unsigned_long_long_variable(string name)
{
    unsigned long long var = 0;
    ifstream infile(name + ".bin", ifstream::binary);
    if (infile)
    {
        infile.read(reinterpret_cast<char*>(&var), sizeof(var));
        infile.close();
    }
    else cerr << "Error opening file: " << name + ".bin" << endl;

    return var;
}

int main() {

    // Start execution time
    clock_t start_1 = clock();
    auto start_2 = chrono::high_resolution_clock::now();

    // Start memory usage
    struct rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_start = usage.ru_maxrss; // in kilobytes

    // Code ----------------------------------------------------------

    set_unsigned_long_long_variable( "n", 94 );
    set_unsigned_long_long_variable( "t1", 0 );
    set_unsigned_long_long_variable( "t2", 1 );
    set_unsigned_long_long_variable( "t3", 0 );

    if(get_unsigned_long_long_variable("n") == 1)
        cout << get_unsigned_long_long_variable("t1") << endl;
    else if(get_unsigned_long_long_variable("n") == 2)
        cout << get_unsigned_long_long_variable("t2") << endl;
    else{
        set_unsigned_long_long_variable( "counter", 3 );
        while (get_unsigned_long_long_variable("counter") <= get_unsigned_long_long_variable("n")) {
            set_unsigned_long_long_variable ( "t3", get_unsigned_long_long_variable("t1") + get_unsigned_long_long_variable("t2"));
            set_unsigned_long_long_variable ("t1" , get_unsigned_long_long_variable("t2"));
            set_unsigned_long_long_variable ("t2" , get_unsigned_long_long_variable("t3"));
            set_unsigned_long_long_variable ("counter" , get_unsigned_long_long_variable("counter") + 1);
        }
        cout << get_unsigned_long_long_variable("t3") << endl;
    }

    // ---------------------------------------------------------------

    // Stop measuring memory usage
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_end = usage.ru_maxrss; // in kilobytes

    // Stop measuring execution time
    clock_t end_1 = clock();
    auto end_2 = chrono::high_resolution_clock::now();
    double execution_time_1 = double(end_1 - start_1) / CLOCKS_PER_SEC;
    chrono::duration<double, milli> execution_time_2 = end_2 - start_2;

    // Printing result
    cout << "Execution Time (Based on ctime): " << execution_time_1 * 1000.0 << " ms" << endl;
    cout << "Execution Time (Based on chrono): " << execution_time_2.count() << " ms" << endl;
    cout << "Memory Usage: " << memory_usage_end - memory_usage_start << " KB" << endl;

    return 0;
}

فایل کد


این کد معادل همون برنامه هست، با این تفاوت که متغیر هاشو روی دیسک ذخیره میکنه، من این‌ام 50 بار اجرا میکنم ببینیم چی میشه:

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ Fibo_HDD.cpp

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 27.961 ms
Execution Time (Based on chrono): 44.9589 ms
Memory Usage: 0 KB

real    0.05s
user    0.00s
sys     0.03s
cpu     63%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 31.508 ms
Execution Time (Based on chrono): 31.4675 ms
Memory Usage: 0 KB

real    0.04s
user    0.00s
sys     0.03s
cpu     98%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 33.407 ms
Execution Time (Based on chrono): 173.327 ms
Memory Usage: 0 KB

real    0.18s
user    0.01s
sys     0.03s
cpu     21%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 37.039 ms
Execution Time (Based on chrono): 60.1359 ms
Memory Usage: 0 KB

real    0.07s
user    0.00s
sys     0.04s
cpu     63%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 26.895 ms
Execution Time (Based on chrono): 53.0744 ms
Memory Usage: 0 KB

real    0.06s
user    0.00s
sys     0.03s
cpu     53%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 30.281 ms
Execution Time (Based on chrono): 30.9933 ms
Memory Usage: 0 KB

real    0.03s
user    0.00s
sys     0.03s
cpu     97%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 26.92 ms
Execution Time (Based on chrono): 27.194 ms
Memory Usage: 0 KB

real    0.03s
user    0.00s
sys     0.03s
cpu     97%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 28.805 ms
Execution Time (Based on chrono): 45.9833 ms
Memory Usage: 0 KB

real    0.05s
user    0.00s
sys     0.03s
cpu     63%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 35.667 ms
Execution Time (Based on chrono): 94.1039 ms
Memory Usage: 0 KB

real    0.10s
user    0.01s
sys     0.03s
cpu     40%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 28.217 ms
Execution Time (Based on chrono): 40.1542 ms
Memory Usage: 0 KB

real    0.04s
user    0.00s
sys     0.03s
cpu     71%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 52.593 ms
Execution Time (Based on chrono): 68.8812 ms
Memory Usage: 0 KB

real    0.07s
user    0.01s
sys     0.05s
cpu     77%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 74.053 ms
Execution Time (Based on chrono): 335.553 ms
Memory Usage: 0 KB

real    0.34s
user    0.02s
sys     0.06s
cpu     23%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 29.317 ms
Execution Time (Based on chrono): 42.8699 ms
Memory Usage: 0 KB

real    0.05s
user    0.01s
sys     0.02s
cpu     70%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 50.748 ms
Execution Time (Based on chrono): 83.1821 ms
Memory Usage: 0 KB

real    0.09s
user    0.01s
sys     0.05s
cpu     62%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 50.086 ms
Execution Time (Based on chrono): 59.5969 ms
Memory Usage: 0 KB

real    0.06s
user    0.00s
sys     0.05s
cpu     84%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 26.691 ms
Execution Time (Based on chrono): 66.4044 ms
Memory Usage: 0 KB

real    0.07s
user    0.01s
sys     0.02s
cpu     43%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 27.622 ms
Execution Time (Based on chrono): 42.9472 ms
Memory Usage: 0 KB

real    0.05s
user    0.00s
sys     0.03s
cpu     66%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 26.011 ms
Execution Time (Based on chrono): 42.8584 ms
Memory Usage: 0 KB

real    0.05s
user    0.00s
sys     0.03s
cpu     63%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 46.855 ms
Execution Time (Based on chrono): 59.3697 ms
Memory Usage: 0 KB

real    0.06s
user    0.01s
sys     0.04s
cpu     79%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 43.295 ms
Execution Time (Based on chrono): 55.3742 ms
Memory Usage: 0 KB

real    0.06s
user    0.00s
sys     0.04s
cpu     79%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 56.283 ms
Execution Time (Based on chrono): 56.3353 ms
Memory Usage: 0 KB

real    0.06s
user    0.02s
sys     0.04s
cpu     98%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 55.732 ms
Execution Time (Based on chrono): 153.311 ms
Memory Usage: 0 KB

real    0.16s
user    0.02s
sys     0.04s
cpu     37%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 36.473 ms
Execution Time (Based on chrono): 90.0586 ms
Memory Usage: 0 KB

real    0.09s
user    0.01s
sys     0.03s
cpu     42%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 35.634 ms
Execution Time (Based on chrono): 60.2903 ms
Memory Usage: 0 KB

real    0.07s
user    0.01s
sys     0.03s
cpu     61%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 37.919 ms
Execution Time (Based on chrono): 41.4295 ms
Memory Usage: 0 KB

real    0.05s
user    0.00s
sys     0.04s
cpu     90%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 53.446 ms
Execution Time (Based on chrono): 55.0082 ms
Memory Usage: 0 KB

real    0.06s
user    0.02s
sys     0.04s
cpu     96%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 57.878 ms
Execution Time (Based on chrono): 215.491 ms
Memory Usage: 0 KB

real    0.22s
user    0.02s
sys     0.04s
cpu     28%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 51.583 ms
Execution Time (Based on chrono): 79.8935 ms
Memory Usage: 0 KB

real    0.08s
user    0.02s
sys     0.04s
cpu     65%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 66.857 ms
Execution Time (Based on chrono): 318.953 ms
Memory Usage: 0 KB

real    0.32s
user    0.01s
sys     0.06s
cpu     22%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 44.318 ms
Execution Time (Based on chrono): 44.4082 ms
Memory Usage: 0 KB

real    0.05s
user    0.01s
sys     0.04s
cpu     98%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 68.406 ms
Execution Time (Based on chrono): 391.37 ms
Memory Usage: 0 KB

real    0.40s
user    0.00s
sys     0.07s
cpu     18%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 64.93 ms
Execution Time (Based on chrono): 266.554 ms
Memory Usage: 0 KB

real    0.27s
user    0.01s
sys     0.06s
cpu     25%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 53.075 ms
Execution Time (Based on chrono): 95.7015 ms
Memory Usage: 0 KB

real    0.10s
user    0.01s
sys     0.05s
cpu     57%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 48.386 ms
Execution Time (Based on chrono): 51.8912 ms
Memory Usage: 0 KB

real    0.06s
user    0.00s
sys     0.05s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 64.722 ms
Execution Time (Based on chrono): 282.728 ms
Memory Usage: 0 KB

real    0.29s
user    0.00s
sys     0.06s
cpu     24%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 30.692 ms
Execution Time (Based on chrono): 51.0716 ms
Memory Usage: 0 KB

real    0.05s
user    0.01s
sys     0.03s
cpu     61%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 42.179 ms
Execution Time (Based on chrono): 71.7145 ms
Memory Usage: 0 KB

real    0.08s
user    0.00s
sys     0.04s
cpu     60%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 27.902 ms
Execution Time (Based on chrono): 49.6614 ms
Memory Usage: 0 KB

real    0.05s
user    0.01s
sys     0.02s
cpu     57%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 50.868 ms
Execution Time (Based on chrono): 65.8676 ms
Memory Usage: 0 KB

real    0.07s
user    0.00s
sys     0.06s
cpu     77%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 38.906 ms
Execution Time (Based on chrono): 229.074 ms
Memory Usage: 0 KB

real    0.23s
user    0.01s
sys     0.04s
cpu     18%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 45.282 ms
Execution Time (Based on chrono): 95.5347 ms
Memory Usage: 0 KB

real    0.10s
user    0.01s
sys     0.04s
cpu     49%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 32.539 ms
Execution Time (Based on chrono): 37.7129 ms
Memory Usage: 0 KB

real    0.04s
user    0.00s
sys     0.03s
cpu     86%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 47.754 ms
Execution Time (Based on chrono): 60.9285 ms
Memory Usage: 0 KB

real    0.07s
user    0.01s
sys     0.04s
cpu     79%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 34.381 ms
Execution Time (Based on chrono): 41.1787 ms
Memory Usage: 0 KB

real    0.05s
user    0.00s
sys     0.04s
cpu     84%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 52.619 ms
Execution Time (Based on chrono): 291.559 ms
Memory Usage: 0 KB

real    0.30s
user    0.01s
sys     0.05s
cpu     19%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 24.712 ms
Execution Time (Based on chrono): 85.2908 ms
Memory Usage: 0 KB

real    0.09s
user    0.00s
sys     0.02s
cpu     30%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 54.553 ms
Execution Time (Based on chrono): 72.2719 ms
Memory Usage: 0 KB

real    0.08s
user    0.02s
sys     0.04s
cpu     76%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 61.797 ms
Execution Time (Based on chrono): 396.595 ms
Memory Usage: 0 KB

real    0.40s
user    0.01s
sys     0.06s
cpu     16%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 24.581 ms
Execution Time (Based on chrono): 44.3478 ms
Memory Usage: 0 KB

real    0.05s
user    0.00s
sys     0.03s
cpu     58%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
12200160415121876738
Execution Time (Based on ctime): 41.316 ms
Execution Time (Based on chrono): 74.7477 ms
Memory Usage: 0 KB

real    0.08s
user    0.00s
sys     0.04s
cpu     57%

متوسط نتیجه:

(27.961+31.508+33.407+37.039+26.895+30.281+26.92+28.805+35.667+28.217+52.593+74.053+29.317+50.748+50.086+26.691+27.622+26.011+46.855+43.295+56.283+55.732+36.473+35.634+37.919+53.446+57.878+51.583+66.857+44.318+68.406+64.93+53.075+48.386+64.722+30.692+42.179+27.902+50.868+38.906+45.282+32.539+47.754+34.381+52.619+24.712+54.553+61.797+24.581+41.316) / 50 = 2139.694 / 50 = 42.79388
(44.9589+31.4675+173.327+60.1359+53.0744+30.9933+27.194+45.9833+94.1039+40.1542+68.8812+335.553+42.8699+83.1821+59.5969+66.4044+42.9472+42.8584+59.3697+55.3742+56.3353+153.311+90.0586+60.2903+41.4295+55.0082+215.491+79.8935+318.953+44.4082+391.37+266.554+95.7015+51.8912+282.728+51.0716+71.7145+49.6614+65.8676+229.074+95.5347+37.7129+60.9285+41.1787+291.559+85.2908+72.2719+396.595+44.3478+74.7477) / 50 = 5329.4088 / 50 = 106.588176
(0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0) / 50 = 0 / 50 = 0
(0.05s+0.04s+0.18s+0.07s+0.06s+0.03s+0.03s+0.05s+0.10s+0.04s+0.07s+0.34s+0.05s+0.09s+0.06s+0.07s+0.05s+0.05s+0.06s+0.06s+0.06s+0.16s+0.09s+0.07s+0.05s+0.06s+0.22s+0.08s+0.32s+0.05s+0.40s+0.27s+0.10s+0.06s+0.29s+0.05s+0.08s+0.05s+0.07s+0.23s+0.10s+0.04s+0.07s+0.05s+0.30s+0.09s+0.08s+0.40s+0.05s+0.08s) / 50 = 5.57 / 50 = 0.1114
(0.00s+0.00s+0.01s+0.00s+0.00s+0.00s+0.00s+0.00s+0.01s+0.00s+0.01s+0.02s+0.01s+0.01s+0.00s+0.01s+0.00s+0.00s+0.01s+0.00s+0.02s+0.02s+0.01s+0.01s+0.00s+0.02s+0.02s+0.02s+0.01s+0.01s+0.00s+0.01s+0.01s+0.00s+0.00s+0.01s+0.00s+0.01s+0.00s+0.01s+0.01s+0.00s+0.01s+0.00s+0.01s+0.00s+0.02s+0.01s+0.00s+0.00s) / 50 = 0.34 / 50 = 0.0068
(0.03s+0.03s+0.03s+0.04s+0.03s+0.03s+0.03s+0.03s+0.03s+0.03s+0.05s+0.06s+0.02s+0.05s+0.05s+0.02s+0.03s+0.03s+0.04s+0.04s+0.04s+0.04s+0.03s+0.03s+0.04s+0.04s+0.04s+0.04s+0.06s+0.04s+0.07s+0.06s+0.05s+0.05s+0.06s+0.03s+0.04s+0.02s+0.06s+0.04s+0.04s+0.03s+0.04s+0.04s+0.05s+0.02s+0.04s+0.06s+0.03s+0.04s) / 50 = 1.97 / 50 = 0.0394
(63%+98%+21%+63%+53%+97%+97%+63%+40%+71%+77%+23%+70%+62%+84%+43%+66%+63%+79%+79%+98%+37%+42%+61%+90%+96%+28%+65%+22%+98%+18%+25%+57%+92%+24%+61%+60%+57%+77%+18%+49%+86%+79%+84%+19%+30%+76%+16%+58%+57%) / 50 = 2992 / 50 = 59.84


Therefore:

* Average Execution Time(Based on ctime): 42.79388 ms
* Average Execution Time(Based on chrono): 106.588176 ms
* Average Memory Usage: 0 KB
* Average Real Time: 0.1114 s
* Average User Time: 0.0068 s
* Average Sys Time: 0.0394 s
* Average CPU Usage: 59.84 %

و مقایسه:

106.588176 / 0.07143168 = 1492

واو! اینبار دیسک نزدیک 1500 بار کندتر ظاهر شده…


من دارم با خودم فکر میکنم سناریو مقایسه ما زیادی ساده‌ست×ـ× 94 تا پیمایش حلقه که خیلی کمه… بیاین یه کد دیگه بنویسیم و تعداد پیمایشهارو زیاد کنیم و به برنامه‌های واقعی نزدیک ترش کنیم!




کد زیر رو در نظر بگیرید:

#include <iostream>
#include <sys/resource.h>
#include <chrono>
using namespace std;

int main() {

    // Start execution time
    clock_t start_1 = clock();
    auto start_2 = chrono::high_resolution_clock::now();

    // Start memory usage
    struct rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_start = usage.ru_maxrss; // in kilobytes

    // Code ----------------------------------------------------------

    unsigned long long n = 1000, counter = n, sum_divable = 0;

    while (counter > 0) {
        if( n % counter == 0 )
            ++sum_divable;
        --counter;
    }
    cout << sum_divable << endl;

    // ---------------------------------------------------------------

    // Stop measuring memory usage
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_end = usage.ru_maxrss; // in kilobytes

    // Stop measuring execution time
    clock_t end_1 = clock();
    auto end_2 = chrono::high_resolution_clock::now();
    double execution_time_1 = double(end_1 - start_1) / CLOCKS_PER_SEC;
    chrono::duration<double, milli> execution_time_2 = end_2 - start_2;

    // Printing result
    cout << "Execution Time (Based on ctime): " << execution_time_1 * 1000.0 << " ms" << endl;
    cout << "Execution Time (Based on chrono): " << execution_time_2.count() << " ms" << endl;
    cout << "Memory Usage: " << memory_usage_end - memory_usage_start << " KB" << endl;

    return 0;
}

فایل کد


این کد به ازای هر عدد n ، تمام اعداد قبلیشو پیمایش میکنه و تعداد کل مقسوم علیه های اون عدد رو چاپ میکنه، واضحه که به ازای اعداد اول عدد 2 رو چاپ میکنه(خودش و 1). کد ساده‌ای هست، میشه بهینه‌تر نوشت اونو، اما نمیخایم این کارو کنیم… هدف از این کد انجام محاسبات پیمایشیه که بتونیم سرعت رو بسنجیم.

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ Iteration_RAM.cpp

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 1.288 ms
Execution Time (Based on chrono): 1.27333 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     93%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 1.196 ms
Execution Time (Based on chrono): 1.18127 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 1.101 ms
Execution Time (Based on chrono): 1.08655 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     93%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2 ms
Execution Time (Based on chrono): 1.96631 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.01s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2.147 ms
Execution Time (Based on chrono): 2.11425 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 1.894 ms
Execution Time (Based on chrono): 1.86002 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2.371 ms
Execution Time (Based on chrono): 2.33654 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2.297 ms
Execution Time (Based on chrono): 2.26285 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 1.832 ms
Execution Time (Based on chrono): 1.79954 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     91%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2.074 ms
Execution Time (Based on chrono): 2.03888 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2.393 ms
Execution Time (Based on chrono): 2.36894 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     93%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2.423 ms
Execution Time (Based on chrono): 2.38987 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2.164 ms
Execution Time (Based on chrono): 2.13099 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2.153 ms
Execution Time (Based on chrono): 2.12008 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2.221 ms
Execution Time (Based on chrono): 2.18724 ms
Memory Usage: 0 KB

real    0.01s
user    0.01s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 1.274 ms
Execution Time (Based on chrono): 1.25876 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2.239 ms
Execution Time (Based on chrono): 2.20461 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 1.031 ms
Execution Time (Based on chrono): 1.01659 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 2.485 ms
Execution Time (Based on chrono): 2.45185 ms
Memory Usage: 0 KB

real    0.01s
user    0.00s
sys     0.00s
cpu     92%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 1.276 ms
Execution Time (Based on chrono): 1.26014 ms
Memory Usage: 0 KB

real    0.00s
user    0.00s
sys     0.00s
cpu     92%

و متوسط آزمایش:

(1.288+1.196+1.101+2+2.147+1.894+2.371+2.297+1.832+2.074+2.393+2.423+2.164+2.153+2.221+1.274+2.239+1.031+2.485+1.276) / 20 = 37.859 / 20 = 1.89295
(1.27333+1.18127+1.08655+1.96631+2.11425+1.86002+2.33654+2.26285+1.79954+2.03888+2.36894+2.38987+2.13099+2.12008+2.18724+1.25876+2.20461+1.01659+2.45185+1.26014) / 20 = 37.30861 / 20 = 1.8654305
(0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0) / 20 = 0 / 20 = 0
(0.00s+0.00s+0.00s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s+0.01s+0.00s+0.01s+0.00s+0.01s+0.00s) / 20 = 0.14 / 20 = 0.007
(0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.01s+0.00s+0.00s+0.00s+0.00s+0.01s+0.01s+0.01s+0.01s+0.00s+0.00s+0.00s+0.00s+0.00s) / 20 = 0.05 / 20 = 0.0025
(0.00s+0.00s+0.00s+0.01s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s+0.00s) / 20 = 0.01 / 20 = 0.0005
(93%+92%+93%+92%+92%+92%+92%+92%+91%+92%+93%+92%+92%+92%+92%+92%+92%+92%+92%+92%) / 20 = 1842 / 20 = 92.1


Therefore:

* Average Execution Time(Based on ctime): 1.89295 ms
* Average Execution Time(Based on chrono): 1.8654305 ms
* Average Memory Usage: 0 KB
* Average Real Time: 0.007 s
* Average User Time: 0.0025 s
* Average Sys Time: 0.0005 s
* Average CPU Usage: 92.1 %

فرض کنید همین کد رو مثل قسمت قبلی جوری بنویسیم که متغیرهای اصلیشو فقط روی دیسک ذخیره کنه ،فقط هم مثلاً 3 تا متغیر اصلیشو، نه بیشتر. نه آدرسها، نه رجیسترها، نه فانکشنکالها، نه هیچ چیز دیگه… فقط مقدار 3 متغیر اصلیشو روی هارددیسک ذخیره کنه.

#include <iostream>
#include <sys/resource.h>
#include <chrono>
#include <fstream>
#include <string>
using namespace std;

void set_unsigned_long_long_variable(string name, unsigned long long var)
{
    ofstream outfile(name + ".bin"  , ofstream::binary);
    if (outfile)
    {
        outfile.write(reinterpret_cast<const char*>(&var), sizeof(var));
        outfile.close();
    }
    else cerr << "Error opening file: " << name + ".bin" << endl;
}

unsigned long long get_unsigned_long_long_variable(string name)
{
    unsigned long long var = 0;
    ifstream infile(name + ".bin", ifstream::binary);
    if (infile)
    {
        infile.read(reinterpret_cast<char*>(&var), sizeof(var));
        infile.close();
    }
    else cerr << "Error opening file: " << name + ".bin" << endl;

    return var;
}

int main() {

    // Start execution time
    clock_t start_1 = clock();
    auto start_2 = chrono::high_resolution_clock::now();

    // Start memory usage
    struct rusage usage;
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_start = usage.ru_maxrss; // in kilobytes

    // Code ----------------------------------------------------------

    set_unsigned_long_long_variable( "n", 100000);
    set_unsigned_long_long_variable( "counter", get_unsigned_long_long_variable("n"));
    set_unsigned_long_long_variable( "sum_divable", 0);

    while (get_unsigned_long_long_variable("counter") > 0) {
        if( get_unsigned_long_long_variable("n") % get_unsigned_long_long_variable("counter") == 0 )
            set_unsigned_long_long_variable( "sum_divable", get_unsigned_long_long_variable("sum_divable") + 1);
        set_unsigned_long_long_variable( "counter", get_unsigned_long_long_variable("counter") - 1);
    }
    cout << get_unsigned_long_long_variable("sum_divable") << endl;

    // ---------------------------------------------------------------

    // Stop measuring memory usage
    getrusage(RUSAGE_SELF, &usage);
    long memory_usage_end = usage.ru_maxrss; // in kilobytes

    // Stop measuring execution time
    clock_t end_1 = clock();
    auto end_2 = chrono::high_resolution_clock::now();
    double execution_time_1 = double(end_1 - start_1) / CLOCKS_PER_SEC;
    chrono::duration<double, milli> execution_time_2 = end_2 - start_2;

    // Printing result
    cout << "Execution Time (Based on ctime): " << execution_time_1 * 1000.0 << " ms" << endl;
    cout << "Execution Time (Based on chrono): " << execution_time_2.count() << " ms" << endl;
    cout << "Memory Usage: " << memory_usage_end - memory_usage_start << " KB" << endl;

    return 0;
}

فایل کد


بریم اجرا کنیم ببینیم چه فاجعه‌ای رخ میده!

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ g++ Iteration_HDD.cpp 

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 8134.59 ms
Execution Time (Based on chrono): 22359.2 ms
Memory Usage: 0 KB

real    22.36s
user    1.38s
sys     6.75s
cpu     36%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 8427.09 ms
Execution Time (Based on chrono): 22312.2 ms
Memory Usage: 0 KB

real    22.31s
user    1.49s
sys     6.94s
cpu     37%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 8167.64 ms
Execution Time (Based on chrono): 22296.8 ms
Memory Usage: 0 KB

real    22.30s
user    1.45s
sys     6.72s
cpu     36%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 8040.17 ms
Execution Time (Based on chrono): 22315.6 ms
Memory Usage: 0 KB

real    22.32s
user    1.43s
sys     6.61s
cpu     36%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 8921.16 ms
Execution Time (Based on chrono): 30141.7 ms
Memory Usage: 0 KB

real    30.14s
user    1.43s
sys     7.49s
cpu     29%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 7915.38 ms
Execution Time (Based on chrono): 22112.7 ms
Memory Usage: 0 KB

real    22.12s
user    1.35s
sys     6.57s
cpu     35%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 8791.03 ms
Execution Time (Based on chrono): 26041.5 ms
Memory Usage: 0 KB

real    26.04s
user    1.41s
sys     7.38s
cpu     33%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 9897.57 ms
Execution Time (Based on chrono): 29009.1 ms
Memory Usage: 0 KB

real    29.01s
user    1.70s
sys     8.20s
cpu     34%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 8693.6 ms
Execution Time (Based on chrono): 23570.2 ms
Memory Usage: 0 KB

real    23.57s
user    1.43s
sys     7.27s
cpu     36%

┌──(user㉿dhcppc4)-[~/Desktop/Articles/4-RAM-vs-HDD-Pr/Files]
└─$ time ./a.out
36
Execution Time (Based on ctime): 9362.56 ms
Execution Time (Based on chrono): 28498.6 ms
Memory Usage: 0 KB

real    28.50s
user    1.74s
sys     7.62s
cpu     32%

متوسط زمان آزمایش:

(8134.59+8427.09+8167.64+8040.17+8921.16+7915.38+8791.03+9897.57+8693.6+9362.56) / 10 = 86350.79 / 10 = 8635.079
(22359.2+22312.2+22296.8+22315.6+30141.7+22112.7+26041.5+29009.1+23570.2+28498.6) / 10 = 248657.6 / 10 = 24865.76
(0+0+0+0+0+0+0+0+0+0) / 10 = 0 / 10 = 0
(22.36s+22.31s+22.30s+22.32s+30.14s+22.12s+26.04s+29.01s+23.57s+28.50s) / 10 = 248.67 / 10 = 24.867
(1.38s+1.49s+1.45s+1.43s+1.43s+1.35s+1.41s+1.70s+1.43s+1.74s) / 10 = 14.81 / 10 = 1.481
(6.75s+6.94s+6.72s+6.61s+7.49s+6.57s+7.38s+8.20s+7.27s+7.62s) / 10 = 71.55 / 10 = 7.155
(36%+37%+36%+36%+29%+35%+33%+34%+36%+32%) / 10 = 344 / 10 = 34.4


Therefore:

* Average Execution Time(Based on ctime): 8635.079 ms
* Average Execution Time(Based on chrono): 24865.76 ms
* Average Memory Usage: 0 KB
* Average Real Time: 24.867 s
* Average User Time: 1.481 s
* Average Sys Time: 7.155 s
* Average CPU Usage: 34.4 %

و داریم:

24865.76 / 1.8654305 = 13329

یهو رسیدیم به 13 هزار برابر (13329) کندی سرعت!




حدس من اینه که در این نوع محاسبات و I/O زدنهای پیاپی برای داده‌های کوچولو روی دیسک، کند شدن سرعت محاسبات رشد نمایی میکنه، در صورتی که همین محاسبات رو رم رشد خطی میکنن…


بیاین صحت این حدس رو بسنجیم، من مقادیر مختلف n رو توی همین دوتا برنامه آخر، یعنی Iteration_RAM و Iteration_HDD تست میکنم و نتیجه رو گزارش میکنم. و البته اعتراف کنم که ممکنه یه کار خبیثانه کنم و این آزمایش آخر رو ببرم روی یه VPS انجام بدم که دیسک خودم آسیب نبینه… از طرفی خیلی برای نتیجه مقاله هم خوب هست، چون نتایج آزمایش خیلی overfit نمیشه روی ماشین من.


مشخصات ماشین اجرا کننده آزمایشات تا اینجای ماجرا:


تا اینجا کدهای مقاله روی یه ماشین استاندارد لینوکسی با مشخصات زیر آزمایش شدن:

OS: Kali GNU/Linux Rolling x86_64
Kernel: 5.16.0-kali5-amd64
CPU: Intel i5-8250U (8) @ 3.400GHz
Memory: 11857MiB
Shell: zsh 5.8.1

HDD details:

duf
╭───────────────────────────────────────────────────────────────────────────────────────────╮
│ 2 local devices                                                                           │
├────────────┬────────┬────────┬────────┬───────────────────────────────┬──────┬────────────┤
│ MOUNTED ON │   SIZE │   USED │  AVAIL │              USE%             │ TYPE │ FILESYSTEM │
├────────────┼────────┼────────┼────────┼───────────────────────────────┼──────┼────────────┤
│ /          │ 200.2G │ 164.0G │  26.0G │ [################....]  81.9% │ ext4 │ /dev/sda6  │
│ /boot/efi  │ 512.0M │  12.5M │ 499.5M │ [....................]   2.4% │ vfat │ /dev/sda5  │
╰────────────┴────────┴────────┴────────┴───────────────────────────────┴──────┴────────────╯
╭────────────────────────────────────────────────────────────────────────────────────────────────╮
│ 6 special devices                                                                              │
├────────────────┬──────┬────────┬───────┬───────────────────────────────┬──────────┬────────────┤
│ MOUNTED ON     │ SIZE │   USED │ AVAIL │              USE%             │ TYPE     │ FILESYSTEM │
├────────────────┼──────┼────────┼───────┼───────────────────────────────┼──────────┼────────────┤
│ /dev           │ 5.7G │     0B │  5.7G │                               │ devtmpfs │ udev       │
│ /dev/shm       │ 5.8G │  23.5M │  5.8G │ [....................]   0.4% │ tmpfs    │ tmpfs      │
│ /run           │ 1.2G │   1.9M │  1.2G │ [....................]   0.2% │ tmpfs    │ tmpfs      │
│ /run/lock      │ 5.0M │     0B │  5.0M │                               │ tmpfs    │ tmpfs      │
│ /run/snapd/ns  │ 1.2G │   1.9M │  1.2G │ [....................]   0.2% │ tmpfs    │ tmpfs      │
│ /run/user/1000 │ 1.2G │ 192.0K │  1.2G │ [....................]   0.0% │ tmpfs    │ tmpfs      │
╰────────────────┴──────┴────────┴───────┴───────────────────────────────┴──────────┴────────────╯
sudo hdparm -I /dev/sda6
/dev/sda6:

ATA device, with non-removable media
        Model Number:       HGST HTS541010B7E610                    
        Serial Number:      WXF1E673XX4S
        Firmware Revision:  03.01A03
        Transport:          Serial, SATA 1.0a, SATA II Extensions, SATA Rev 2.5, SATA Rev 2.6, SATA Rev 3.0
Standards:
        Used: unknown (minor revision code 0x006d) 
        Supported: 10 9 8 7 6 5 
        Likely used: 10
Configuration:
        Logical         max     current
        cylinders       16383   0
        heads           16      0
        sectors/track   63      0
        --
        LBA    user addressable sectors:   268435455
        LBA48  user addressable sectors:  1953525168
        Logical  Sector size:                   512 bytes
        Physical Sector size:                  4096 bytes
        Logical Sector-0 offset:                  0 bytes
        device size with M = 1024*1024:      953869 MBytes
        device size with M = 1000*1000:     1000204 MBytes (1000 GB)
        cache/buffer size  = unknown
        Form Factor: 2.5 inch
        Nominal Media Rotation Rate: 5400
Capabilities:
        LBA, IORDY(can be disabled)
        Queue depth: 32
        Standby timer values: specd by Standard, with device specific minimum
        R/W multiple sector transfer: Max = 16  Current = 16
        Advanced power management level: 254
        DMA: mdma0 mdma1 mdma2 udma0 udma1 udma2 udma3 udma4 udma5 *udma6 
             Cycle time: min=120ns recommended=120ns
        PIO: pio0 pio1 pio2 pio3 pio4 
             Cycle time: no flow control=120ns  IORDY flow control=120ns
Commands/features:
        Enabled Supported:
           *    SMART feature set
                Security Mode feature set
           *    Power Management feature set
           *    Write cache
           *    Look-ahead
           *    WRITE_BUFFER command
           *    READ_BUFFER command
           *    NOP cmd
           *    DOWNLOAD_MICROCODE
           *    Advanced Power Management feature set
                Power-Up In Standby feature set
           *    SET_FEATURES required to spinup after power up
           *    48-bit Address feature set
           *    Mandatory FLUSH_CACHE
           *    FLUSH_CACHE_EXT
           *    SMART error logging
           *    SMART self-test
           *    General Purpose Logging feature set
           *    64-bit World wide name
           *    IDLE_IMMEDIATE with UNLOAD
           *    {READ,WRITE}_DMA_EXT_GPL commands
           *    Segmented DOWNLOAD_MICROCODE
           *    Gen1 signaling speed (1.5Gb/s)
           *    Gen2 signaling speed (3.0Gb/s)
           *    Gen3 signaling speed (6.0Gb/s)
           *    Native Command Queueing (NCQ)
           *    Host-initiated interface power management
           *    Phy event counters
           *    Idle-Unload when NCQ is active
           *    NCQ priority information
           *    READ_LOG_DMA_EXT equivalent to READ_LOG_EXT
           *    DMA Setup Auto-Activate optimization
           *    Device-initiated interface power management
           *    Software settings preservation
           *    SMART Command Transport (SCT) feature set
           *    SCT Write Same (AC2)
           *    SCT Features Control (AC4)
           *    SCT Data Tables (AC5)
                unknown 206[12] (vendor specific)
                unknown 206[13] (vendor specific)
           *    Extended number of user addressable sectors 
           *    DOWNLOAD MICROCODE DMA command
           *    WRITE BUFFER DMA command
           *    READ BUFFER DMA command
           *    Data Set Management TRIM supported (limit 10 blocks)
           *    Deterministic read data after TRIM
Security: 
        Master password revision code = 65534
                supported
        not     enabled
        not     locked
        not     frozen
        not     expired: security count
                supported: enhanced erase
        180min for SECURITY ERASE UNIT. 180min for ENHANCED SECURITY ERASE UNIT.
Logical Unit WWN Device Identifier: 50014ee608088121
        NAA             : 5
        IEEE OUI        : 0014ee
        Unique ID       : 608088121
Checksum: correct



بریم سراغ قسمت آخر ماجرا که فان ترین قسمت مقاله هم هست از نظر من^_^
توی این قسمت میخوایم ازین کارای باحال علمی بکنیم و ببینیم که پیچیدگی زمانی چه‌جوری رشد میکنه، نمودار بکشیم و مقایسه کنیم و از این دک و پزها…


این کد رو به عنوان آخرین کد مقاله در نظر بگیرید:

#include <iostream>
#include <chrono>
#include <fstream>
#include <cstring>
using namespace std;

void set_unsigned_long_long_variable(string name, unsigned long long var)
{
    ofstream outfile(name + ".bin"  , ofstream::binary);
    if (outfile)
    {
        outfile.write(reinterpret_cast<const char*>(&var), sizeof(var));
        outfile.close();
    }
    else cerr << "Error opening file: " << name + ".bin" << endl;
}

unsigned long long get_unsigned_long_long_variable(string name)
{
    unsigned long long var = 0;
    ifstream infile(name + ".bin", ifstream::binary);
    if (infile)
    {
        infile.read(reinterpret_cast<char*>(&var), sizeof(var));
        infile.close();
    }
    else cerr << "Error opening file: " << name + ".bin" << endl;

    return var;
}

int main(int argc, char** argv)  {

    // Start execution time
    auto start = chrono::high_resolution_clock::now();

    // Code ----------------------------------------------------------

    if( strcmp(argv[1], "RAM") == 0 )
    {
        unsigned long long n = stoull(argv[2]), counter = n, sum_divable = 0;
        while (counter > 0) {
            if( n % counter == 0 )
                ++sum_divable;
            --counter;
        }
        cout << sum_divable << endl;
    }
    else if( strcmp(argv[1], "HDD") == 0 )
    {
        set_unsigned_long_long_variable( "n", stoull(argv[2]) );
        set_unsigned_long_long_variable( "counter", get_unsigned_long_long_variable("n"));
        set_unsigned_long_long_variable( "sum_divable", 0);
        while (get_unsigned_long_long_variable("counter") > 0) {
            if( get_unsigned_long_long_variable("n") % get_unsigned_long_long_variable("counter") == 0 )
                set_unsigned_long_long_variable( "sum_divable", get_unsigned_long_long_variable("sum_divable") + 1);
            set_unsigned_long_long_variable( "counter", get_unsigned_long_long_variable("counter") - 1);
        }
        cout << get_unsigned_long_long_variable("sum_divable") << endl;
    }
    else cout << "ERROR: Wronge input argument." << endl;

    // ---------------------------------------------------------------

    // Stop measuring execution time
    auto end = chrono::high_resolution_clock::now();
    chrono::duration<double, milli> execution_time = end - start;

    // Printing result
    cout << "Execution Time (Based on chrono): " << execution_time.count() << " ms" << endl;

    return 0;
}

فایل کد


این کد دقیقاً کد قبلی هست ولی داینامیک نوشته شده، با توجه به ورودی هایی که بعنوان آرگومان از بافر ورودی استاندارد میگیره، کار رو انجام میده،‌میتونه محاسبات رو به تعداد ورودی n روی رم و یا روی هارددیسک انجام بده.


من با این کد مقادیر زمانی سپری شده برای محاسبات روی رم / هارددیسک رو روی یه ماشین کولب گوگل تست میکنم:

counter=0; while [ $counter -lt 50 ]; do ./a.out RAM 10; echo ""; counter=$((counter+1)); done
(0.05557+0.04354+0.037682+0.055058+0.059299+0.040107+0.044795+0.033862+0.03316+0.030346+0.031631+0.039248+0.031442+0.030144+0.031636+0.030273+0.044436+0.035037+0.032099+0.032844+0.029726+0.031982+0.03101+0.034369+0.033597+0.042123+0.03926+0.037468+0.03927+0.042095+0.039197+0.04276+0.043037+0.058996+0.032882+0.034359+0.032656+0.034285+0.031125+0.029796+0.035702+0.030816+0.03118+0.036636+0.029955+0.029841+0.029912+0.047903+0.038854+0.033695) / 50 = 1.856696 / 50 = 0.03713392

Therefore:
* Average Execution Time(Based on chrono): 0.03713392 ms
counter=0; while [ $counter -lt 50 ]; do ./a.out RAM 100; echo ""; counter=$((counter+1)); done
(0.056729+1.59152+0.048881+0.049231+0.04922+0.043113+0.050367+0.044923+0.042751+0.043592+0.041487+0.039294+0.043805+0.047856+0.040708+0.044756+0.041053+0.040405+0.047841+0.049873+0.040557+0.039935+0.040469+0.042405+0.043633+0.042428+0.040278+0.064401+0.042753+0.049396+0.059291+0.050488+0.045674+0.047207+0.043165+0.041103+0.041197+0.037907+0.0587+0.043548+0.04071+0.04312+0.041312+0.040731+0.041073+0.047526+0.066859+0.057422+0.042882+0.043553) / 50 = 3.837128 / 50 = 0.07674256

Therefore:
* Average Execution Time(Based on chrono): 0.07674256 ms
counter=0; while [ $counter -lt 50 ]; do ./a.out RAM 1000; echo ""; counter=$((counter+1)); done
(0.068803+0.059274+3.0206+0.053834+0.051958+0.051055+0.057953+0.059117+0.042785+0.048859+0.045849+0.042131+0.05188+0.042523+0.049469+0.038819+0.0395+0.041249+0.040282+0.040635+0.037002+0.044957+0.040858+0.038883+0.04276+0.061451+0.042524+0.040479+0.05396+0.041289+0.039723+0.049896+0.041293+0.039501+0.040528+0.049634+0.053361+0.041704+0.044657+0.041357+0.040148+0.045694+0.058381+0.041357+0.040849+0.036245+0.044352+0.043624+0.040995+0.036902) / 50 = 5.260939 / 50 = 0.10521878

Therefore:
* Average Execution Time(Based on chrono): 0.10521878 ms
counter=0; while [ $counter -lt 50 ]; do ./a.out RAM 10000; echo ""; counter=$((counter+1)); done
(0.185036+0.154471+0.165113+0.157347+0.18171+0.132968+0.115558+0.121692+0.121769+0.113374+0.116244+0.149405+0.150177+0.125981+0.123877+0.128397+0.132772+0.172368+0.127196+0.126897+0.12715+0.115237+0.126738+0.133597+0.123583+0.124886+0.118664+0.125119+0.129162+0.115475+0.15031+0.15324+0.128633+0.158191+0.209703+0.123722+0.128189+0.135494+0.127625+0.167394+0.126804+0.124159+0.154155+0.116885+0.14578+0.119057+0.123312+0.11629+0.143316+0.114863) / 50 = 6.809085 / 50 = 0.1361817

Therefore:
* Average Execution Time(Based on chrono): 0.1361817 ms
counter=0; while [ $counter -lt 50 ]; do ./a.out RAM 100000; echo ""; counter=$((counter+1)); done
(2.8513+1.01647+0.976667+0.970932+0.97964+0.995396+0.982495+0.97912+0.966483+0.970715+0.934009+0.950327+0.974002+0.975446+0.986908+0.980763+1.1284+0.982268+0.983068+0.987813+0.993953+1.02334+1.01758+1.11104+0.987194+1.04501+0.979295+0.995212+0.987408+1.01927+1.01664+0.987328+0.973787+0.975659+0.973153+0.978747+0.952589+1.09384+1.37752+1.01558+0.982577+1.0207+0.974533+1.11337+0.985381+1.01944+1.04177+1.0397+1.02442+1.04134) / 50 = 52.319598 / 50 = 1.04639196

Therefore:
* Average Execution Time(Based on chrono): 1.04639196 ms
counter=0; while [ $counter -lt 50 ]; do ./a.out RAM 1000000; echo ""; counter=$((counter+1)); done
(11.7602+11.6177+11.6259+9.55161+9.84909+9.6777+9.83686+9.87394+10.1924+9.75504+9.56854+9.53915+10.2645+9.75044+9.52632+9.57528+10.5565+9.7492+9.98362+13.526+11.1387+11.8642+11.5241+12.129+13.6267+11.4817+10.573+11.2104+11.0466+11.0755+10.6779+12.0456+10.9347+11.2068+11.2398+11.4614+11.3066+10.9896+11.3568+10.9231+10.6759+16.8868+14.999+16.2878+12.3337+12.8563+12.1443+10.4334+10.7875+10.6904) / 50 = 561.68729 / 50 = 11.2337458

Therefore:
* Average Execution Time(Based on chrono): 11.2337458 ms
counter=0; while [ $counter -lt 50 ]; do ./a.out RAM 10000000; echo ""; counter=$((counter+1)); done
(122.437+111.11+116.911+111.118+114.321+112.377+117.222+110.622+110.967+107.209+119.983+117.109+113.132+112.927+117.166+112.409+110.612+121.124+115.648+99.2176+100.546+96.6624+97.9584+95.4014+98.3823+98.5019+98.32+98.3984+95.9734+96.6039+97.2092+98.2006+96.5731+92.4531+93.6754+96.8256+97.0719+92.4971+93.3109+93.8384+92.9399+99.6457+96.2368+90.9912+90.5309+94.4321+97.6597+93.3925+94.4273+97.0904) / 50 = 5149.3715 / 50 = 102.98743

Therefore:
* Average Execution Time(Based on chrono): 102.98743 ms
counter=0; while [ $counter -lt 50 ]; do ./a.out RAM 100000000; echo ""; counter=$((counter+1)); done
(1153.99+1090+927.97+950.748+952.153+934.874+951.585+934.285+931.199+935.237+951.123+946.343+1044.16+1104.66+1060.29+933.39+932.839+943.719+944.238+936.994+952.082+938.932+921.093+929.203+930.171+1018.32+1079.7+1059.41+936.524+948.65+950.927+956.4+955.033+944.512+943.176+933.907+939.347+950.281+1052.11+1087.17+1069.19+952.72+921.658+921.936+932.571+954.542+931.82+944.327+943.054+937.911) / 50 = 48496.474 / 50 = 969.92948

Therefore:
* Average Execution Time(Based on chrono): 969.92948 ms
counter=0; while [ $counter -lt 50 ]; do ./a.out RAM 1000000000; echo ""; counter=$((counter+1)); done
(9929.45+9894.97+9401.29+9779.2+9740.14+9711.45+9411.57+9575.79+9740.8+9762.82+10157.3+9470.99+9807.61+9827.57+9903.24+9546.48+9817.56+9914.88+9835.63+9757.12+9494.87+9768.5+9804.84+9879.44+9978.79+10010.1+9716.13+9654.43+9452.93+9741.28+9716.39+9671.29+9534.45+9422.55+9740.14+9631.31+9571.77+9396.79+9789.33+10178.4+9683.12+9338.5+9541.9+9655.58+9713.08+9510.57+9530.52+9780.9+9780.28+9769.28) / 50 = 485443.32 / 50 = 9708.8664

Therefore:
* Average Execution Time(Based on chrono): 9708.8664 ms
counter=0; while [ $counter -lt 5 ]; do ./a.out RAM 10000000000; echo ""; counter=$((counter+1)); done
(98059.1+98639.7+99670.5+99134.6+99792.6) / 5 = 495296.5 / 5 = 99059.3

Therefore:
* Average Execution Time(Based on chrono): 99059.3 ms
counter=0; while [ $counter -lt 1 ]; do ./a.out RAM 100000000000; echo ""; counter=$((counter+1)); done
144
Execution Time (Based on chrono): 982447 ms
Iterations RAM Time Complexity(ms)
10 0.03713392
100 0.07674256
1000 0.10521878
10000 0.1361817
100000 1.04639196
1000000 11.2337458
10000000 102.98743
100000000 969.92948
1000000000 9708.8664
10000000000 99059.3
100000000000 982447

با این ماشین، 100 ملیارد پیمایش روی رم صرفاً 16 دقیقه طول میکشه.


حالا بریم سراغ هارد دیسک:

counter=0; while [ $counter -lt 50 ]; do ./a.out HDD 10; echo ""; counter=$((counter+1)); done
(3.84055+1.47793+1.36111+1.18943+1.25027+1.06003+1.15582+1.31169+0.988887+1.08511+0.996868+1.02288+1.15027+0.970606+1.30461+1.24018+1.30114+1.01147+1.1003+1.16134+1.05386+1.00953+1.08559+1.09392+1.02795+1.04478+1.11548+1.02791+1.13904+1.43361+1.41642+1.34454+1.04273+1.10764+3.06246+1.34444+1.09299+1.02791+0.98998+1.40493+1.2629+1.37666+1.1086+1.0706+1.67073+1.05198+1.37261+1.31193+1.34244+1.18202) / 50 = 63.596671 / 50 = 1.27193342

Therefore:
* Average Execution Time(Based on chrono): 1.27193342 ms
counter=0; while [ $counter -lt 50 ]; do ./a.out HDD 100; echo ""; counter=$((counter+1)); done
(10.1258+8.54431+8.57312+9.30554+7.19626+8.57967+7.81807+6.76671+8.19687+11.3563+8.76072+8.89945+7.93218+7.15151+9.06521+8.95591+9.04594+8.77245+9.37136+7.49228+8.1699+7.5217+8.37757+8.27919+9.53812+9.14541+8.06788+7.49188+8.24989+10.9161+8.53771+8.61268+6.91477+8.33953+8.44163+6.35417+6.49716+8.86702+8.77506+9.01159+8.56295+6.69499+8.88008+8.89771+9.1845+8.44426+9.3007+9.81496+8.01047+8.43163) / 50 = 424.24087 / 50 = 8.4848174

Therefore:
* Average Execution Time(Based on chrono): 8.4848174 ms
counter=0; while [ $counter -lt 50 ]; do ./a.out HDD 1000; echo ""; counter=$((counter+1)); done
(83.7239+89.2962+87.393+86.0499+82.4329+92.4111+83.0183+93.2184+98.6888+88.1423+93.149+104.383+94.8324+95.2283+104.694+98.6493+92.5682+91.8928+101.478+95.2763+96.7348+96.7451+95.3717+96.2584+95.0568+104.564+94.3572+92.9837+94.5809+96.7802+95.193+94.719+94.5504+98.0115+104.346+90.0224+89.8571+84.6048+90.1275+89.0622+92.2847+91.2552+89.7745+91.942+90.7563+89.0043+94.7468+89.3705+85.9757+95.2816) / 50 = 4660.8444 / 50 = 93.216888

Therefore:
* Average Execution Time(Based on chrono): 93.216888 ms
counter=0; while [ $counter -lt 10 ]; do ./a.out HDD 10000; echo ""; counter=$((counter+1)); done
(878.908+868.796+868.818+868.208+921.707+945.511+940.521+901.627+872.928+876.26) / 10 = 8943.284 / 10 = 894.3284

Therefore:
* Average Execution Time(Based on chrono): 894.3284 ms
counter=0; while [ $counter -lt 5 ]; do ./a.out HDD 100000; echo ""; counter=$((counter+1)); done
(8944.41+9181.89+9291.08+9176.2+9019.04) / 5 = 45612.62 / 5 = 9122.524

Therefore:
* Average Execution Time(Based on chrono): 9122.524 ms
counter=0; while [ $counter -lt 5 ]; do ./a.out HDD 1000000; echo ""; counter=$((counter+1)); done
(93730+92787+91645.4+92535.1+94361.4) / 5 = 465058.9 / 5 = 93011.78

Therefore:
* Average Execution Time(Based on chrono): 93011.78 ms
counter=0; while [ $counter -lt 1 ]; do ./a.out HDD 10000000; echo ""; counter=$((counter+1)); done
64
Execution Time (Based on chrono): 904366 ms
counter=0; while [ $counter -lt 1 ]; do ./a.out HDD 100000000; echo ""; counter=$((counter+1)); done
81
Execution Time (Based on chrono): 9.06014e+06 ms

و میدونیم که:

9.06014e+06 = 9060140
Iterations HDD Time Complexity(ms)
10 1.27193342
100 8.4848174
1000 93.216888
10000 894.3284
100000 9122.524
1000000 93011.78
10000000 904366
100000000 9060140
1000000000 NULL
10000000000 NULL
100000000000 NULL

وقتی که تنها سه متغیرمونو روی دیسک ذخیره کردیم، چه اتفاقی افتاد؟ 100 ملیون پردازشمون حدود 3 ساعت طول کشید و اصلاً نتونستیم به اوردر ملیارد برسیم… این درحالیه که 100 ملیون پردازش روی رم تقریباً 9 ثانیه طول کشیده.


با رفتاری که داریم از رشد زمانی پردازش روی هارددیسک میبینیم، میتونیم برونیابی کنیم که احتمالاً 3 مقداری که نداریم هر بار 10 برابر میشن پس اولی احتمالاً 1 روز و خورده‌ای، دومی 12 روز و سومی باید 125 روز باشه..!


جدول زیر رو مشاهده بفرمائین:

Iterations RAM Time Complexity(ms) HDD Time Complexity(ms) Ratio(HDD/RAM)
10 0.03713392 1.27193342 34.2526030
100 0.07674256 8.4848174 110.5620844
1000 0.10521878 93.216888 885.9339368
10000 0.1361817 894.3284 6567.1701851
100000 1.04639196 9122.524 8718.0753949
1000000 11.2337458 93011.78 8279.6764014
10000000 102.98743 904366 8781.3240897
100000000 969.92948 9060140 9341.0296179
1000000000 9708.8664 NULL NULL
10000000000 99059.3 NULL NULL
100000000000 982447 NULL NULL

و اگر بخوایم نموداری از رشدش بکشیم، من سه مقدار آخر رو بصورت تخمینی برونیابی میکنم و با کد پایتون زیر نموداری میکشم:

import matplotlib.pyplot as plt

iterations = [10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000]
ram_times = [0.03713392, 0.07674256, 0.10521878, 0.1361817, 1.04639196, 11.2337458, 102.98743, 969.92948, 9708.8664, 99059.3, 982447]
# hdd_times = [1.27193342, 8.4848174, 93.216888, 894.3284, 9122.524, 93011.78, 904366, 9060140, None, None, None]
last_hdd_time = 9060140 # Estimate times
hdd_times = [1.27193342, 8.4848174, 93.216888, 894.3284, 9122.524, 93011.78, 904366, 9060140, last_hdd_time*10, last_hdd_time*100, last_hdd_time*1000]


plt.plot(iterations, hdd_times, marker='o', label='HDD Time Complexity')
plt.plot(iterations, ram_times, marker='o', label='RAM Time Complexity')

plt.xlabel('Iterations')
plt.ylabel('Time Complexity (ms)')
plt.title('Points and Lines Plot')

plt.legend()

plt.show()

فایل کد


HDD vs RAM plot small


HDD vs RAM plot


همین نمودارو اگه بخوایم بصورت انتزاعی بکشیم، باید یه همچین چیزی باشه:


Abstract HDD vs RAM plot


و نهایتاً این نکته رو بگم که شما میتونین همزمانی رو وارد این داستان کنین و یهو از چندده هزار برابر کندی، برسین به چندصد هزار برابر کندی! البته اگر دیسک برای آزمایش دارین..، من همینجا آزمایش رو متوقف میکنم چون نمیخوام دیسکهای مردم رو بسوزونم×ـ×




یکی از نتایج جانبی عملی (Practical Side Results) میتونه این باشه که برای انجام تست پیچیدگی های زمانی، اگه رنجه زمانهای نتیجه کوشولو هستن و هر بار تغییر زیادی میکنن، تعداد تست رو باید ببریم بالا تا به یه تخمین خوبی برسیم و برعکس، اگه رنج زمانهای خروجی خیلی زیاده و تغییر کمی میکنن هر بار، یه تعداد بار کمتری به ما تخمین معقولی رو میده✅


یکسری لینک پرسش و پاسخ مرتبط با این موضوع:


و تمام، هارددیسک بطور متوسط 100000 بار از رم کند تره:))


کارهای آینده


شما توی مقاله خودتون میتونین روی سناریوهایی کار کنین که کندی بیشتری رو به تصویر بکشین، میتونین همزمانی رو وارد فاز دوم آزمایش بکنید، میتونین از دیسکهای مختلف استفاده کنین یا حتی از کلاسترهای مختلف روی RAID های مختلف استفاده کنین، همچنین اگر براتون مقدوره میتونین واقعاً بذارین دیسک 125 روز محاسبات کنه که نتیجه مقایسه واقعی باشه:)


کپی رایت


این یک مقاله آزاد و متن‌باز تحت مجوز GFDL1-3 می‌باشد، بنابراین اجازه کپی، توزیع و/یا تغییر این سند با شرایط مجوز GNU Free Documentation License داده شده است.


نویسنده


منابع


مسائل مرتبط با این مقاله


این مقاله بصورت آزاد و اپن‌سورس در مخزن کتابها/مقالات آزاد در لینک زیر در دسترس است:


https://github.com/TadavomnisT/Free_Books-Documents/tree/main/Articles/4-RAM-vs-HDD-Pr


نسخه انگلیسی این مقاله:


https://github.com/TadavomnisT/Free_Books-Documents/tree/main/Articles/4-RAM-vs-HDD-En


هر نوع اشکال علمی، مساله یا بحث مربوط با این مقاله را میتوانید از طریق Issue در ریپازیتوری یا ایمیل مطرح نمایید: