📌 سری یادداشتهای واحد توسعه محصول آیو (نوراویون):
وقتی قرار است عمل IO انجام بدهیم (با هر نوع دیوایسی از قبیل File System یا Socket یا Pipe یا ...) به هر صورت، سرعت IO نسبت به عملیاتهای محاسباتی دیگر که در بطن پردازندهها انجام میشوند، کندتر است. این مسئله مخصوصا زمانی که در حال طراحی و توسعه یک درایور هستیم، بسیار اهمیت دارد، زیرا ممکنه ترد برنامه برای اینکه یک کار IO به انتها برسد، مدت طولانی دچار Delay در عملکرد خود شود (و کل برنامه اجالتا هالت شود تا آن عمل IO به پایان برسد).
به هر صورت، در برنامهنویسی سطح پایین (مثل نوشتن درایور)، عملیات ورودی/خروجی (IO) به علت ماهیت دیوایسهای فیزیکی کندتر است. این تفاوت سرعت باعث میشود که هنگام اجرای IO، ترد برنامه در حالت انتظار (Blocking) قرار بگیرد یا موجب ایجاد گلوگاه در عملکرد برنامه شود.
به همین دلیل، برنامهنویسان به ویژه در ویندوز از رویکرد Asynchronous یا Overlapped IO استفاده میکنند. در این روش، سیستم بدون توقف ترد اصلی، عملیات IO را در پسزمینه انجام میدهد. به محض اتمام، از طریق فراخوانی یک تابع Callback مثل IoCompletedRoutine، برنامه را مطلع میکند. در آزمایشگاه آیو، این روش یکی از پایههای اصلی توسعه محسوب میشود.
به عنوان مثال، در ویندوز 11، برای اجرای Asynchronous IO، دیوایس باید با فلگ FILE_FLAG_OVERLAPPED باز شود. این فلگ امکان اجرای درخواستها در پسزمینه را فراهم کرده و به برنامه اجازه میدهد ترد اصلی را مشغول به کار نگه دارد. زمانی که IO تمام شد، یا با فراخوانی Callback مشخص، و یا از طریق یک Event، برنامه از اتمام کار آگاه میشود.
علاوه بر ویندوز، سیستمعامل لینوکس نیز از IO غیرهمزمان یا همان Asynchronous IO پشتیبانی میکند، اما از مکانیزم متفاوتی به نام epoll و select یا aio استفاده میکند. با این حال، به منظور حل این چالش، یکی از رایجترین روشها در لینوکس، استفاده از epoll است که برای مدیریت تعداد زیادی از عملیات IO بهطور همزمان طراحی شده است.
شایان ذکر است، ویندوز 11 با تمرکز بیشتر روی Parallelism و کارایی در پردازشهای Asynchronous، ساختار System Message Queue و Thread Queue را بهبود بخشیده است. حالا هر ترد که عملیاتی از نوع GDI/USER32 را آغاز میکند، دارای یک Thread Queue خاص خواهد بود که ارتباطات و پیغامهای سیستمی را پردازش میکند. با این رویکرد، نه تنها امکان اجرای همزمان عملیاتهای متعدد فراهم میشود، بلکه کارایی و سرعت پاسخگویی سیستم نیز بهبود یافته است.
شایان ذکر است، در ویندوز، هر IRP (IO Request Packet) معمولی باید از تمام درایورهای موجود در مسیر عبور کند تا در نهایت توسط یک درایور (معمولاً پایینترین درایور) پردازش شود. اگر درایوری قصد داشته باشد تنها یک IRP را به یک درایور خاص ارسال کند، از Non-queued IRP بهره میبرد. این روش در عملکرد تاثیر بسزایی دارد، زیرا از صفهای سیستمی و صفهای تردها عبور نکرده و مستقیم به پردازش مربوطه میپردازد.
✍️ خلاصه فنی: رویکرد Overlapped IO در ویندوز و مکانیزم epoll در لینوکس، هر دو با هدف بهبود کارایی و کاهش تاخیر عملیات IO طراحی شدهاند. این مکانیزمها در کنار تفاوتهایشان، هدف مشترک افزایش کارایی و بهینهسازی سیستم برای اجرای همزمان درخواستهای IO رادارند. در ویندوز، استفاده از فلگ FILE_FLAG_OVERLAPPED و توابعی مانند ReadFileEx، امکان مدیریت IO غیرهمزمان را به روشی ساده و بهینه فراهم کرده است. در لینوکس، با استفاده از epoll و توابعی مانند read بهصورت غیرهمزمان، این امکان به توسعهدهندگان داده شده تا در برنامههایی که نیازمند کارایی بالا هستند، IO را به شکل موازی مدیریت کنند. با این روشها، نه تنها کارایی سیستم بهبود یافته، بلکه پاسخگویی برنامهها در پردازشهای IO نیز به میزان چشمگیری افزایش پیدا کرده است.
✍️ نویسنده میلاد کهساری الهادی
➖راهبر فنی تیم تحقیقات و توسعه آیو
⏰ یکشنبه - ۶ آبان ۱۴۰۳
@aioooir | #xdr #io #async #sync