تجنب انعكاس الأولوية

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

قد تكون هذه التقنيات مفيدة لمطوري التطبيقات الصوتية عالية الأداء، ومصنعي المعدات الأصلية، وموفري SoC الذين يقومون بتنفيذ طبقة تصديق الأجهزة (HAL) الصوتية. يرجى ملاحظة أن تنفيذ هذه التقنيات ليس مضمونًا لمنع حدوث مواطن الخلل أو حالات الفشل الأخرى، خاصة إذا تم استخدامها خارج سياق الصوت. قد تختلف نتائجك، ويجب عليك إجراء التقييم والاختبار الخاص بك.

خلفية

تتم إعادة تصميم خادم الصوت Android AudioFlinger وتطبيق عميل AudioTrack/AudioRecord لتقليل زمن الوصول. بدأ هذا العمل في Android 4.1، واستمر مع المزيد من التحسينات في 4.2 و4.3 و4.4 و5.0.

ولتحقيق هذا الكمون الأقل، كانت هناك حاجة إلى العديد من التغييرات في جميع أنحاء النظام. أحد التغييرات المهمة هو تخصيص موارد وحدة المعالجة المركزية لسلاسل العمليات ذات الوقت الحرج باستخدام سياسة جدولة أكثر قابلية للتنبؤ. تسمح الجدولة الموثوقة بتقليل أحجام وأعداد المخزن المؤقت للصوت مع تجنب التجاوزات والتجاوزات.

انعكاس الأولوية

انقلاب الأولوية هو وضع فشل كلاسيكي لأنظمة الوقت الفعلي، حيث يتم حظر المهمة ذات الأولوية الأعلى لفترة غير محدودة في انتظار مهمة ذات أولوية أقل لتحرير مورد مثل (الحالة المشتركة المحمية بواسطة) كائن المزامنة ( mutex ).

في النظام الصوتي، عادةً ما يظهر انعكاس الأولوية على شكل خلل (نقر، فرقعة، انقطاع)، أو صوت متكرر عند استخدام مخازن مؤقتة دائرية، أو تأخير في الاستجابة لأمر ما.

الحل الشائع لعكس الأولوية هو زيادة أحجام المخزن المؤقت للصوت. ومع ذلك، تعمل هذه الطريقة على زيادة زمن الوصول وإخفاء المشكلة فقط بدلاً من حلها. من الأفضل فهم ومنع انعكاس الأولوية، كما هو موضح أدناه.

في تطبيق صوت Android، من المرجح أن يحدث انعكاس الأولوية في هذه الأماكن. ولذا يجب أن تركز انتباهك هنا:

  • بين خيط الخلاط العادي وخيط الخلاط السريع في AudioFlinger
  • بين خيط رد اتصال التطبيق لـ AudioTrack السريع وخيط المزج السريع (كلاهما لهما أولوية مرتفعة، لكن أولويات مختلفة قليلاً)
  • بين خيط رد الاتصال للتطبيق للحصول على تسجيل صوتي سريع وخيط الالتقاط السريع (على غرار السابق)
  • ضمن تنفيذ طبقة تجريد الأجهزة الصوتية (HAL)، على سبيل المثال للاتصالات الهاتفية أو إلغاء الصدى
  • داخل برنامج تشغيل الصوت في kernel
  • بين سلسلة رد الاتصال AudioTrack أو AudioRecord وسلاسل التطبيقات الأخرى (هذا خارج عن سيطرتنا)

الحلول المشتركة

تشمل الحلول النموذجية ما يلي:

  • تعطيل المقاطعات
  • كائنات الميراث ذات الأولوية

لا يعد تعطيل المقاطعات ممكنًا في مساحة مستخدم Linux، ولا يعمل مع المعالجات المتعددة المتماثلة (SMP).

لا يتم استخدام فوتكس الوراثة ذات الأولوية (كائنات المزامنة السريعة لمساحة المستخدم) في النظام الصوتي لأنها ثقيلة الوزن نسبيًا، ولأنها تعتمد على عميل موثوق به.

التقنيات التي يستخدمها أندرويد

بدأت التجارب بـ "محاولة القفل" والقفل مع انتهاء المهلة. هذه هي متغيرات الحظر غير المحظورة والمحدودة لعملية قفل كائن المزامنة (mutex lock). لقد عملت تجربة القفل والقفل باستخدام المهلة بشكل جيد إلى حد ما ولكنها كانت عرضة لبعض أوضاع الفشل الغامضة: لم يكن من المضمون أن يتمكن الخادم من الوصول إلى الحالة المشتركة إذا كان العميل مشغولاً، ويمكن أن تكون المهلة التراكمية طويلة جدًا إذا كان هناك تسلسل طويل من الأقفال غير ذات الصلة والتي انتهت مهلة جميعها.

نستخدم أيضًا العمليات الذرية مثل:

  • زيادة راتب
  • بالبت "أو"
  • بالبت "و"

كل هذه العناصر تعيد القيمة السابقة وتتضمن حواجز SMP الضرورية. العيب هو أنها يمكن أن تتطلب عمليات إعادة محاولة غير محدودة. ومن الناحية العملية، وجدنا أن إعادة المحاولة ليست مشكلة.

ملاحظة: من المعروف أن العمليات الذرية وتفاعلاتها مع حواجز الذاكرة يساء فهمها وتستخدم بشكل غير صحيح. قمنا بتضمين هذه الطرق هنا للاكتمال ولكننا ننصحك أيضًا بقراءة مقالة SMP Primer لنظام Android لمزيد من المعلومات.

لا نزال نمتلك ونستخدم معظم الأدوات المذكورة أعلاه، وقمنا مؤخرًا بإضافة هذه التقنيات:

  • استخدم قوائم انتظار FIFO ذات القارئ الواحد والكاتب الفردي غير المحظورة للبيانات.
  • حاول نسخ الحالة بدلاً من مشاركة الحالة بين الوحدات ذات الأولوية العالية والمنخفضة.
  • عندما تكون هناك حاجة إلى مشاركة الحالة، قم بقصر الحالة على الحد الأقصى لحجم الكلمة التي يمكن الوصول إليها تلقائيًا في عملية ناقل واحد دون إعادة المحاولة.
  • بالنسبة للحالة المعقدة متعددة الكلمات، استخدم قائمة انتظار الحالة. قائمة انتظار الحالة هي في الأساس مجرد قائمة انتظار FIFO لقارئ واحد غير محظورة تستخدم للحالة بدلاً من البيانات، باستثناء أن الكاتب يطوي عمليات الدفع المجاورة في دفعة واحدة.
  • انتبه إلى حواجز الذاكرة من أجل صحة SMP.
  • ثق ولكن تحقق . عند مشاركة الحالة بين العمليات، لا تفترض أن الحالة جيدة التكوين. على سبيل المثال، تأكد من أن المؤشرات تقع ضمن الحدود. ليس هناك حاجة إلى هذا التحقق بين سلاسل العمليات في نفس العملية، بين عمليات الثقة المتبادلة (التي عادةً ما يكون لها نفس UID). كما أنه غير ضروري للبيانات المشتركة مثل صوت PCM حيث يكون الفساد غير مهم.

خوارزميات غير محظورة

لقد كانت الخوارزميات غير المحظورة موضوعًا للكثير من الدراسات الحديثة. ولكن باستثناء قوائم انتظار FIFO ذات القارئ الواحد والكاتب الفردي، فقد وجدنا أنها معقدة وعرضة للخطأ.

بدءًا من Android 4.2، يمكنك العثور على فئات القارئ/الكاتب الفردي غير المحظورة في هذه المواقع:

  • أطر العمل/av/تشمل/media/nbaio/
  • الأطر/av/media/libnbaio/
  • الأطر/av/services/audioflinger/StateQueue*

لقد تم تصميمها خصيصًا لـ AudioFlinger وليست للأغراض العامة. تشتهر الخوارزميات غير المحظورة بصعوبة تصحيح أخطائها. يمكنك النظر إلى هذا الرمز كنموذج. لكن انتبه إلى أنه قد تكون هناك أخطاء، ولا نضمن أن تكون الفئات مناسبة لأغراض أخرى.

بالنسبة للمطورين، يجب تحديث بعض نماذج التعليمات البرمجية لتطبيق OpenSL ES لاستخدام خوارزميات غير محظورة أو الرجوع إلى مكتبة مفتوحة المصدر غير تابعة لنظام Android.

لقد قمنا بنشر مثال لتطبيق FIFO غير المحظور والذي تم تصميمه خصيصًا لرمز التطبيق. راجع هذه الملفات الموجودة في دليل مصدر النظام الأساسي frameworks/av/audio_utils :

أدوات

على حد علمنا، لا توجد أدوات تلقائية للعثور على انعكاس الأولوية، خاصة قبل حدوثه. بعض أدوات تحليل التعليمات البرمجية الثابتة البحثية قادرة على العثور على عمليات عكسية ذات أولوية إذا كانت قادرة على الوصول إلى قاعدة التعليمات البرمجية بأكملها. بالطبع، إذا كان هناك كود مستخدم عشوائي (كما هو الحال هنا للتطبيق) أو كان عبارة عن قاعدة تعليمات برمجية كبيرة (كما هو الحال بالنسبة لنواة Linux وبرامج تشغيل الأجهزة)، فقد يكون التحليل الثابت غير عملي. الشيء الأكثر أهمية هو قراءة الكود بعناية شديدة والحصول على فهم جيد للنظام بأكمله والتفاعلات. تعتبر الأدوات مثل systrace و ps -t -p مفيدة لرؤية انعكاس الأولوية بعد حدوثه، ولكنها لا تخبرك بذلك مسبقًا.

كلمة أخيرة

بعد كل هذه المناقشة، لا تخافوا من كائنات المزامنة. تعتبر Mutexes صديقتك للاستخدام العادي، عند استخدامها وتنفيذها بشكل صحيح في حالات الاستخدام العادية غير الحرجة للوقت. ولكن بين المهام ذات الأولوية العالية والمنخفضة وفي الأنظمة الحساسة للوقت، من المرجح أن تسبب كائنات المزامنة مشاكل.