دليل عملي إلى soft real-time على Windows - قائمة فحص لخفض latency

· · تطوير Windows, Soft Real-Time, التصميم, القياس

دليل عملي إلى soft real-time على Windows - قائمة فحص لخفض latency

يتناول هذا المقال Windows 10 / 11 العاديّ، لا امتداد real-time خاصّاً. الهدف هو تطبيق user-mode المعتاد الذي يعمل على PC مكتبيّ أو laptop.

ليس الهدف هنا ضمانات hard real-time. حتّى على Windows العاديّ، إذا أحكمت التصميم واستراتيجيّة الانتظار والأولويّة وإعدادات الطاقة والقياس، يمكنك الوصول إلى مستوى soft real-time عمليّ جدّاً.

بدلاً من سرد كلّ بند ممكن، نُظِّم هذا المقال بحيث ترى بسرعة ما الذي ينبغي مراجعته أوّلاً. إذا بدأت بقائمة الفحص في القسم 4، تتّضح نقاط المراجعة الرئيسيّة بسرعة كبيرة.

المحتويات

  1. النسخة المختصرة
  2. ما الذي يعنيه «Windows العاديّ» في هذا المقال
  3. ما الذي يعنيه soft real-time على Windows
  4. قائمة الفحص الأولى للمراجعة
  5. قائمة فحص لإعدادات الطاقة و OS
  6. القياس والتقييم
  7. دليل تقريبيّ للقاعدة العامّة
  8. الخلاصة
  9. المراجع

1. النسخة المختصرة

  • على Windows العاديّ، الهدف ليس ضمانات hard real-time، بل تقليل latency و jitter وتقليل deadline misses
  • أوّل ما يجب مراجعته ليس قيمة الأولويّة بالضبط، بل ما الذي تضعه داخل الـ thread الدوريّ
  • افصل العمل الذي يجب أن يمرّ في كلّ دورة إلى fast path، وانقل عمل التخزين والاتّصال و UI إلى slow path
  • على fast path، تجنّب الانتظار المعتمد على Sleep و blocking I/O والتخصيص في كلّ دورة والطوابير غير المحدودة
  • بالنسبة لتدفّقات الصوت أو الفيديو المستمرّة، غالباً ما يكون MMCSS أوّل ما يجب التفكير فيه
  • في التشغيل الفعليّ، تكون AC power و power mode و timer resolution و power throttling والحمل في الخلفيّة كلّها مؤثّرة
  • يجب أن ينظر التقييم ليس فقط إلى المتوسّطات، بل أيضاً إلى p99 / p99.9 / max / عدد deadlines المفقودة / عمق الطابور / DPC / ISR / page faults

في الممارسة، الترتيب المعتاد للمراجعة هو:

  1. التوقّف عن الاعتماد على Sleep للحلقة الدوريّة
  2. فصل fast path و slow path
  3. جعل الطوابير محدودة وتعريف سياسة الفيضان
  4. إزالة I/O والتخصيص والـ locks الثقيلة من fast path
  5. استخدام تغييرات الأولويّة أو MMCSS فقط حيث يكون ذلك ضروريّاً حقّاً
  6. ضبط إعدادات الطاقة العاديّة في Windows والقياس

2. ما الذي يعنيه «Windows العاديّ» في هذا المقال

هنا يعني «Windows العاديّ» أجهزة Windows 10 / 11 PCs العامّة. ينصبّ التركيز على إلى أيّ مدى يمكن تثبيت الأمور باستخدام واجهات Windows القياسيّة وإعداداته، دون امتدادات RT خاصّة أو RTOS مخصّص.

flowchart TB
    scope["In scope"] --> s1["General Windows 10 / 11 PCs"]
    scope --> s2["Normal user-mode apps"]
    scope --> s3["Mostly standard APIs and standard settings"]
    scope --> s4["Desktop PCs and laptops"]

    out["Out of scope"] --> o1["Dedicated RTOS or RT extensions"]
    out --> o2["Kernel-driver-centered control"]
    out --> o3["Moving all timing-critical work into FPGA or microcontrollers"]

2.1. ما يدخل في النطاق

تشمل الأمثلة:

  • تطبيقات user-mode بـ C++ / C# على Windows 10 / 11
  • البرمجيّات التي يجب أن تكون «صعبة التأخير»، مثل الصوت والفيديو والقياس والتحكّم بالأجهزة أو المعالجة الدوريّة
  • أجهزة الـ desktop PCs والـ workstations والـ laptops العامّة

2.2. ما هو خارج النطاق

لا يدور هذا المقال حول:

  • ضمانات hard real-time
  • RTOS مخصّص أو امتدادات real-time تجاريّة
  • التصاميم التي يكون فيها kernel drivers هم الفاعل الرئيسيّ
  • البنى التي تنقل كلّ الأجزاء الحرجة زمنيّاً إلى firmware أو FPGA أو متحكّمات منفصلة

تصبح هذه الخيارات ضروريّة لمتطلّبات أكثر صرامة. لكن قبل اللّجوء إليها، يبقى من القيم الكبيرة تكديس تحسينات قابلة للتكرار على Windows العاديّ.

3. ما الذي يعنيه soft real-time على Windows

3.1. ما الذي نسعى إلى تحقيقه

على Windows العاديّ، الحالة المستهدَفة تشبه ما يلي:

  • latency منخفض في التشغيل العاديّ
  • jitter صغير
  • صمود حتّى عند حدوث latency spikes أحياناً
  • ملاحظة مرئيّة لمدى تكرار فقدان الـ deadlines

لا يعني soft real-time هنا «لا يتأخّر أبداً». بل يعني صعب التأخير، وقابل للملاحظة عند التأخير، وصامد حتّى عند التأخير.

3.2. المصطلحات المستخدمة في هذا المقال

المصطلح المعنى
latency أن تبدأ المعالجة أو تنتهي متأخّرةً عمّا هو مقصود
jitter تفاوت في الفاصل أو زمن التنفيذ؛ عدم العمل في التوقيت نفسه كلّ دورة
deadline miss فشل المعالجة في الاكتمال بحلول الـ deadline المطلوب

3.3. أين تبدأ الأمور بالصعوبة

تصبح تطبيقات user-mode على Windows العاديّ أصعب بكثير عندما تريد أموراً مثل:

  • ضمان صفر deadline misses
  • استقرار دون mille-second لفترات طويلة
  • تعايش GUI الثقيل والشبكة والتخزين والعمل الدوريّ عالي التردّد كلّها معاً
  • توقيت صارم مع تفضيل عمر البطّاريّة وتوفير الطاقة في الوقت نفسه
  • عدم احتمال spikes ناجمة عن drivers أو أجهزة

عند تلك النقطة، يبدأ Windows العاديّ وحده بالتمدّد. عندئذٍ قد يحين وقت نقل الأجزاء الحرجة زمنيّاً حقّاً فقط إلى firmware أو متحكّم مخصّص أو FPGA أو بيئة RT أخرى.

4. قائمة الفحص الأولى للمراجعة

هذا القسم موجود لكي ترى بسرعة ما الذي يجب مراقبته أوّلاً.

4.1. الصورة العامّة

بند المراجعة الإجراء الأوّل النمط السيّئ المعتاد
استراتيجيّة الانتظار تشغيل مقابل deadlines مطلقة؛ تفضيل الانتظار المُحرَّك بالأحداث أو waitable timers عالي الدقّة حلقات دوريّة مبنيّة على Sleep(1)
فصل العمل فصل fast path و slow path وضع التخزين أو الإرسال أو UI في fast path
تصميم الطابور جعل الطوابير محدودة وتعريف سياسة الفيضان إخفاء التأخير خلف طابور غير محدود
محتويات fast path إزالة التخصيص والـ logging الثقيل و blocking I/O والـ locks الثقيلة new / malloc / sync I/O / بناء سلاسل في كلّ دورة
الأولويّة ارفع فقط الـ threads التي تحتاجها؛ فكّر في MMCSS للصوت / الفيديو القفز مباشرةً إلى REALTIME_PRIORITY_CLASS
OS / الطاقة تحقّق من AC power و power mode و timer resolution و power throttling القياس تحت البطّاريّة / وضع توفير الطاقة
القياس سجّل التأخّر وزمن التنفيذ وعدد الـ misses وعمق الطابور النظر إلى المتوسّطات فقط
flowchart TB
    start["Periodic processing is running late"] --> c1["Check the waiting strategy"]
    c1 --> c2["Check whether heavy work sits on the fast path"]
    c2 --> c3["Check queue limits and overflow policy"]
    c3 --> c4["Check priority and MMCSS usage"]
    c4 --> c5["Check power mode and timer / power throttling"]
    c5 --> c6["If it still jitters, measure DPC / ISR / page faults"]

4.2. لا تجعل الحلقات الدوريّة تعتمد على Sleep

عادةً هذا أوّل مكان للفحص. Sleep(1) لا يعني «انتظر بالضبط 1 ms». بل يعني انتظر 1 ms على الأقلّ. بمجرّد إضافة زمن تنفيذ الخطوة نفسها، يتراكم الانحراف بشكل طبيعيّ.

flowchart LR
    a["Sleep(1)"] --> b["May sleep longer than expected"]
    b --> c["Step execution time gets added"]
    c --> d["Periodic drift accumulates"]

عادةً ما يكون العمل الدوريّ أكثر استقراراً عندما يُحرَّك بـ deadlines مطلقة بدلاً من الانتظار النسبيّ.

int64_t next = QpcNow() + periodTicks;

while (running)
{
    WaitUntil(next - wakeMarginTicks);   // event / waitable timer
    while (QpcNow() < next)
    {
        CpuRelax();                      // short final spin only
    }

    int64_t started = QpcNow();
    FastStep();                          // no blocking, no alloc, no heavy lock
    int64_t finished = QpcNow();

    RecordTiming(next, started, finished);

    next += periodTicks;

    while (finished > next)
    {
        ++missedDeadlines;
        next += periodTicks;
    }
}

4.3. افصل بين fast path و slow path

عادةً ما يكون التحسين المعماريّ الأكثر فعّاليّةً هو الفصل بين ما هو حرج زمنيّاً وما يمكن أن يحتمل بعض التأخير.

  • fast path العمل الذي يتمّ في كلّ دورة ويجب أن ينتهي بسرعة
  • slow path التخزين والاتّصال والتنسيق والتجميع و UI والعمل المماثل
flowchart LR
    dev["Device / timer / event"] --> fast["fast path: acquisition / control / minimal copy"]
    fast --> queue["bounded queue"]
    queue --> slow["slow path: formatting / storage / sending / UI"]
    fast --> stat["timestamp / miss recording"]
    stat --> slow

على fast path، حاول أن تقتصر على أمور مثل:

  • اكتساب البيانات
  • حساب قيمة التحكّم
  • النسخ بحدّه الأدنى
  • تسجيل الـ timestamp
  • إدخال في الطابور
  • تسجيل miss / overrun

ذلك الفصل هو الأساس لـ soft real-time عمليّ على Windows العاديّ.

4.4. اجعل الطوابير محدودة وقرّر ماذا يحدث عند الفيضان

من السهل التفكير «إذا تأخّر النظام، ضع المزيد في الطابور فقط». لكن الطوابير غير المحدودة غالباً ما تخفي التأخير فقط.

تريد أن تقرّر مسبقاً:

  • حدّ الطابور
  • سياسة الفيضان
  • كيفيّة تسجيل الفيضان

إذا كانت أحدث قيمة فقط مهمّة، فقد يكون إسقاط البيانات القديمة صحيحاً. إذا كان الفقدان غير مقبول، فمن الأفضل غالباً إثارة خطأ بدلاً من الانحراف بصمت أكثر فأكثر إلى الخلف.

4.5. لا تضع عملاً ثقيلاً على fast path

أمور تريد عموماً إبقاءها بعيدة عن fast path:

  • كتابات الملفّات
  • إرسال الشبكة
  • كتابات قواعد البيانات
  • logging ثقيل
  • new / malloc / List<T>.Add في كلّ دورة
  • ربط السلاسل و ToString() في كلّ دورة
  • locks ثقيلة
  • أيّ شيء من المرجّح أن يُطلِق page faults للمسّ الأوّل

الفكرة الأساسيّة بسيطة: لا تجلب العمل «الذي قد يكون بطيئاً» إلى fast path.

4.6. ارفع الأولويّة فقط للـ threads التي تحتاجها

القاعدة الأساسيّة هي لا ترفع كلّ شيء. ابدأ بـ thread واحد فقط هو فعلاً حرج زمنيّاً.

بالنسبة لتدفّقات الصوت أو الفيديو المستمرّة، غالباً ما يكون MMCSS هو الخيار الأوّل الطبيعيّ. يتبع نموذج التدوين المقصود من Windows بشكل أفضل من مجرّد دفع كلّ شيء نحو أولويّة أعلى.

REALTIME_PRIORITY_CLASS ليس أوّل مفتاح يتمّ قلبه. يمكن أن يساعد في بعض الأنظمة المخصّصة، لكنّ الآثار الجانبيّة كبيرة بما يكفي لأن يُحجَز للحالات التي قمت فيها بالفعل بالقياس بعناية على الجهاز المستهدَف.

4.7. انظر إلى الـ timers ووضع الـ CPU وإعدادات الطاقة معاً

على Windows العاديّ، تغييرات الشيفرة وحدها لا تكفي دائماً. يجب النظر إلى استراتيجيّة الانتظار ووضع الـ CPU وإعدادات الطاقة كمجموعة واحدة.

أمور جديرة بالفحص:

  • استخدم QueryPerformanceCounter / Stopwatch لقياس الزمن المنقضي
  • استخدم أحداث الأجهزة أو waitable timers عالية الدقّة حيث أمكن
  • إذا استخدمت timeBeginPeriod، فأبقه محدوداً للفترة المطلوبة فقط
  • لا تقرّر حول CPU affinity صارم قبل القياس
  • تحقّق من AC power و power mode و process power throttling

4.8. اجعل التأخّر مرئيّاً

النقطة الأخيرة المهمّة هي: لا تخفِ التأخّر. غالباً ما يكون debug مشاكل الـ deadlines أسهل بكثير عندما تعدّها وتسجّلها بدلاً من معاملتها كضوضاء غير مرئيّة.

كحدّ أدنى، هذه مفيدة:

  • زمن البدء المجدوَل
  • زمن البدء الفعليّ
  • زمن الانتهاء الفعليّ
  • التأخّر
  • زمن التنفيذ
  • عدد الـ deadlines المفقودة
  • عدد الـ deadlines المفقودة المتتالية
  • عمق الطابور
  • عدد الإسقاطات

إذا بقيت الـ spikes، فوسّع التحقيق. على Windows العاديّ، يمكن أن تساهم DPC / ISR والـ drivers والـ page faults والحرارة وتغيّرات الساعة كلّها.

5. قائمة فحص لإعدادات الطاقة و OS

تكون الإعدادات التي تساعد أكثر عادةً ما تزال داخل Windows العاديّ نفسه. عادةً ما يكون من الأكثر قابليّة للتكرار فحصها بهذا الترتيب:

  1. شغّل على AC power
    • نادراً ما يعطي القياس تحت وضع البطّاريّة نتائج مستقرّة
  2. تحقّق من Windows power mode
    • بالنسبة للإنتاج والقياس، عادةً ما يكون الوضع الأقرب إلى Best performance أسهل في الاستدلال عليه
  3. إذا لزم الأمر، حضّر power plan مخصّصاً
    • balanced للاستخدام اليوميّ، plan مخصّص للإنتاج أو القياس هو تقسيم عمليّ
  4. راجع الحدّ الأدنى والأعلى لحالة المعالج
    • بالنسبة للأجهزة المخصّصة والقياس، قد يكون من الجدير تجربة 100% / 100% تحت AC
  5. تحقّق من process power throttling / EcoQoS
    • يمكن أن تؤثّر إعدادات توفير الطاقة مباشرةً على الانتظارات القصيرة وسرعة التنفيذ
  6. قلّل الحمل غير الضروريّ في الخلفيّة
    • cloud sync والتحديثات والمتصفّحات الثقيلة والمراقبات المقيمة والفهرسة والمهامّ المماثلة كلّها تهمّ
  7. اختبر أثناء التصغير أو عدم الظهور
    • يمكن أن يختلف سلوك timer-resolution عندما لا يكون التطبيق مرئيّاً
  8. انظر إلى BIOS / UEFI أخيراً
    • يمكن أن تهمّ إعدادات C-state أو إعدادات eco / quiet الخاصّة بالمصنّع، لكنّها أكثر اعتماداً على الجهاز

6. القياس والتقييم

6.1. ما الذي يجب تسجيله

كحدّ أدنى، يساعد تسجيل:

  • زمن الدورة المجدوَل
  • زمن البدء الفعليّ
  • زمن الانتهاء الفعليّ
  • التأخّر
  • زمن التنفيذ
  • عدد الـ deadlines المفقودة
  • عدد الـ deadlines المفقودة المتتالية
  • عمق الطابور
  • عدد الإسقاطات
  • DPC / ISR spikes
  • page faults
  • الحرارة / تغيّرات الساعة

السبب بسيط: على Windows العاديّ، أحد أشكال الفشل المعتادة هو «سريع في المتوسّط، لكن متأخّر جدّاً أحياناً».

6.2. ما الذي تعنيه p99 / p99.9 / max

  • المتوسّط يُظهر مركز التوزيع، لكن غالباً ما يخفي spikes سيّئة نادرة
  • p99 النقطة التي تقع تحتها 99% من العيّنات
  • p99.9 النقطة التي تقع تحتها 99.9% من العيّنات
  • max أسوأ عيّنة واحدة
flowchart LR
    sample["Collect 1000 latency samples"] --> sort["Sort them in ascending order"]
    sort --> p99["p99: around sample 990"]
    sort --> p999["p99.9: around sample 999"]
    sort --> max["max: sample 1000"]

في الممارسة، غالباً ما تتطابق p99 / p99.9 / max مع تجربة المستخدم بشكل أفضل بكثير من المتوسّط وحده.

6.3. ما هي الأدوات التي تُستخدَم

  • القياس داخل التطبيق
    • أوّلاً سجّل بنفسك الدورة والتأخّر وزمن التنفيذ وعمق الطابور
  • ETW / WPR / WPA
    • افحص استخدام الـ CPU و context switches و DPC / ISR و page faults
  • LatencyMon
    • احصل على إحساس أوّليّ بما إذا كان الـ drivers متورّطين
  • مراقبة الحرارة / الساعة
    • افحص thermal throttling وتذبذب الساعة

6.4. شروط الاختبار

لا يكفي اختبار جهاز التطوير الهادئ. كحدّ أدنى، يساعد المقارنة بين:

  • قبل warm-up
  • بعد warm-up
  • التشغيل المستمرّ الطويل
  • UI في المقدّمة
  • UI مصغَّر / قريب من المخفيّ
  • AC power
  • battery power
  • تحت حمل الشبكة أو القرص

7. دليل تقريبيّ للقاعدة العامّة

  • فئة 10 إلى 20 ms، وبعض الـ jitter مقبول
    • فصل fast / slow والطوابير المحدودة والأولويّة العاديّة إلى المرتفعة قليلاً والانتظار المُحرَّك بالأحداث غالباً ما تكون كافية
  • فئة 1 إلى 5 ms، وتريد ضرب deadlines بشكل مستمرّ
    • انظر إلى fast paths خالية من التخصيص والـ threads المخصّصة و MMCSS أو ضبط الأولويّة الدقيق و waitable timers عالية الدقّة و AC power وإعدادات الطاقة الموجَّهة نحو الأداء معاً
  • الاقتراب من توقيت دون mille-second، ولا تريد misses حتّى تحت حمل عالٍ في تشغيل طويل
    • يبدأ Windows العاديّ user-mode وحده بالتوتّر؛ يصبح نقل الجزء الحرج إلى مكان آخر يستحقّ النظر الجادّ
  • تريد GUI و logging والاتّصال ونشاط قاعدة البيانات كلّها في المكان نفسه
    • تجنّب جعل حلقة واحدة تحمل كلّ شيء؛ عادةً ما يكون فصل المسؤوليّات أكثر استقراراً

8. الخلاصة

عند استهداف soft real-time على Windows العاديّ، أوّل الأشياء التي يجب فحصها هي:

  1. ما إذا كانت الحلقة الدوريّة تعتمد على Sleep
  2. ما إذا كان fast path و slow path مفصولَين
  3. ما إذا كانت الطوابير محدودة وسياسة الفيضان معرَّفة
  4. ما إذا كان fast path يحتوي على I/O أو تخصيص أو locks ثقيلة
  5. ما إذا كانت الأولويّة أو MMCSS مستخدَمة فقط للـ threads التي تحتاجها فعلاً
  6. ما إذا كانت إعدادات الطاقة والقياس متوافقة على Windows العاديّ

على Windows العاديّ، نادراً ما تُثبِّت الأولويّة وحدها النظام. عادةً ما تحتاج إلى أن يصطفّ التصميم واستراتيجيّة الانتظار وإعدادات الطاقة وإعداد القياس معاً.

الخبر السارّ هو أنّ بهذا الترتيب من التفكير، يمكن لـ Windows العاديّ أن يصل إلى مستوى soft real-time عمليّ جدّاً.

9. المراجع

مقالات ذات صلة

أحدث المقالات التي تشترك في نفس الوسوم. عمّق فهمك بمواضيع مرتبطة.

العودة إلى المدونة