تشرح هذه المقالة كيف يحاول نظام Android الصوتي تجنب انعكاس الأولوية ، وتسلط الضوء على التقنيات التي يمكنك استخدامها أيضًا.
قد تكون هذه الأساليب مفيدة لمطوري تطبيقات الصوت عالية الأداء ومصنعي المعدات الأصلية وموفري SoC الذين يقومون بتطبيق HAL الصوتي. يرجى ملاحظة أن تنفيذ هذه الأساليب ليس مضمونًا لمنع الأخطاء أو الإخفاقات الأخرى ، خاصة إذا تم استخدامها خارج سياق الصوت. قد تختلف نتائجك ، ويجب عليك إجراء التقييم والاختبار الخاصين بك.
خلفية
تتم إعادة هيكلة خادم الصوت Android AudioFlinger وتنفيذ عميل AudioTrack / AudioRecord لتقليل زمن الوصول. بدأ هذا العمل في Android 4.1 ، واستمر مع مزيد من التحسينات في 4.2 و 4.3 و 4.4 و 5.0.
لتحقيق هذا الكمون المنخفض ، كانت هناك حاجة إلى العديد من التغييرات في جميع أنحاء النظام. يتمثل أحد التغييرات المهمة في تعيين موارد وحدة المعالجة المركزية إلى مؤشرات الترابط ذات الأهمية الزمنية مع سياسة جدولة أكثر قابلية للتنبؤ. تسمح الجدولة الموثوقة بتقليل أحجام وأعداد المخزن المؤقت للصوت مع تجنب التجاوزات والتجاوزات.
قلب الأولوية
انعكاس الأولوية هو وضع فشل كلاسيكي لأنظمة الوقت الفعلي ، حيث يتم حظر مهمة ذات أولوية أعلى لوقت غير محدود في انتظار مهمة ذات أولوية أقل لتحرير مورد مثل (الحالة المشتركة المحمية بواسطة) كائن المزامنة ( mutex ).
في نظام صوتي ، يظهر انعكاس الأولوية عادةً في صورة خلل (نقرة ، فرقعة ، تسرب) ، صوت متكرر عند استخدام مخازن دائرية ، أو تأخير في الاستجابة لأمر ما.
يتمثل أحد الحلول الشائعة لعكس الأولوية في زيادة أحجام المخزن المؤقت للصوت. ومع ذلك ، فإن هذه الطريقة تزيد من وقت الاستجابة وتخفي المشكلة بدلاً من حلها. من الأفضل فهم ومنع انعكاس الأولوية ، كما هو موضح أدناه.
في تطبيق صوت Android ، من المرجح أن يحدث انعكاس الأولوية في هذه الأماكن. ولذا يجب أن تركز انتباهك هنا:
- بين خيط الخلاط العادي وخيط الخلاط السريع في AudioFlinger
- بين مؤشر ترابط رد الاتصال للتطبيق للحصول على مسار صوتي سريع وخيط خلط سريع (كلاهما لهما أولوية مرتفعة ، ولكنهما يختلفان قليلاً)
- بين مؤشر ترابط رد الاتصال للتطبيق للحصول على تسجيل صوتي سريع وخيط التقاط سريع (مشابه للسابق)
- ضمن تطبيق طبقة تجريد الأجهزة الصوتية (HAL) ، على سبيل المثال لإلغاء الاتصالات الهاتفية أو الصدى
- داخل برنامج تشغيل الصوت في kernel
- بين سلسلة رد اتصال AudioTrack أو AudioRecord وسلاسل التطبيق الأخرى (هذا خارج عن سيطرتنا)
الحلول المشتركة
تشمل الحلول النموذجية ما يلي:
- تعطيل المقاطعات
- كائنات الميراث ذات الأولوية
لا يمكن تعطيل المقاطعات في مساحة مستخدم Linux ، ولا يعمل مع المعالجات المتعددة المتماثلة (SMP).
لا يتم استخدام العقود الآجلة للميراث ذات الأولوية (كائنات المزامنة السريعة لمساحة المستخدم) في نظام الصوت لأنها ثقيلة الوزن نسبيًا ، ولأنها تعتمد على عميل موثوق به.
التقنيات التي يستخدمها Android
بدأت التجارب بـ "تجربة القفل" والقفل مع انتهاء المهلة. هذه هي متغيرات حظر غير محظورة ومحدودة لعملية قفل كائن المزامنة (mutex). جرب القفل والقفل مع انتهاء المهلة بشكل جيد إلى حد ما ولكن كان عرضة لوضعي فشل غامضين: لم يكن الخادم مضمونًا ليكون قادرًا على الوصول إلى الحالة المشتركة إذا كان العميل مشغولاً ، وقد تكون المهلة التراكمية طويلة جدًا إذا كان هناك سلسلة طويلة من الأقفال غير ذات الصلة التي انتهت مهلتها.
نستخدم أيضًا العمليات الذرية مثل:
- زيادة راتب
- أحادي المعامل "أو"
- باتجاه أحادي "و"
كل هذه تعيد القيمة السابقة وتشمل حواجز SMP الضرورية. العيب هو أنها يمكن أن تتطلب عمليات إعادة المحاولة غير المحدودة. من الناحية العملية ، وجدنا أن عمليات إعادة المحاولة لا تمثل مشكلة.
ملحوظة: العمليات الذرية وتفاعلاتها مع حواجز الذاكرة معروفة بإساءة فهمها واستخدامها بشكل غير صحيح. نقوم بتضمين هذه الطرق هنا للتأكد من اكتمالها ولكن نوصيك أيضًا بقراءة المقالة SMP Primer لنظام Android للحصول على مزيد من المعلومات.
ما زلنا نمتلك ونستخدم معظم الأدوات المذكورة أعلاه ، وقد أضفنا هذه التقنيات مؤخرًا:
- استخدم قوائم انتظار للكاتب الفردي للقارئ الفردي غير المحظورة للبيانات.
- حاول نسخ الحالة بدلاً من مشاركة الحالة بين الوحدات النمطية ذات الأولوية العالية والمنخفضة.
- عندما لا تكون هناك حاجة إلى مشاركة الحالة ، حدد الحالة بأقصى حجم للكلمة التي يمكن الوصول إليها تلقائيًا في عملية أحادية الحافلة دون إعادة المحاولة.
- للحالة المعقدة متعددة الكلمات ، استخدم قائمة انتظار الحالة. قائمة انتظار الحالة هي في الأساس مجرد قائمة انتظار لكاتب واحد للقارئ الفردي غير قابلة للحظر تستخدم للحالة بدلاً من البيانات ، باستثناء أن الكاتب ينهار الدفعات المجاورة في دفعة واحدة.
- انتبه إلى حواجز الذاكرة من أجل تصحيح ال SMP.
- ثق ، لكن تحقق . عند مشاركة الحالة بين العمليات ، لا تفترض أن الحالة جيدة التكوين. على سبيل المثال ، تحقق من أن المؤشرات ضمن الحدود. هذا التحقق ليس مطلوبًا بين سلاسل العمليات في نفس العملية ، وبين عمليات الثقة المتبادلة (التي عادةً ما يكون لها نفس UID). كما أنه غير ضروري للبيانات المشتركة مثل صوت PCM حيث يكون التلف غير ضروري.
الخوارزميات غير المحظورة
كانت الخوارزميات غير المحظورة موضوعًا للكثير من الدراسات الحديثة. ولكن باستثناء قوائم انتظار ما يرد أولاً يصدر أولاً لكاتب واحد للقارئ الفردي ، وجدنا أنها معقدة وعرضة للخطأ.
بدءًا من Android 4.2 ، يمكنك العثور على فصولنا للقارئ الفردي / الكاتب غير المحظورة في هذه المواقع:
- الإطارات / AV / include / media / nbaio /
- الإطارات / av / media / libnbaio /
- الأطر / AV / الخدمات / السمع / StateQueue *
تم تصميمها خصيصًا لـ AudioFlinger وليست للأغراض العامة. تشتهر الخوارزميات غير المحظورة بصعوبة تصحيحها. يمكنك النظر إلى هذا الرمز كنموذج. لكن كن على علم بأنه قد يكون هناك أخطاء ، وليس من المضمون أن تكون الفئات مناسبة لأغراض أخرى.
بالنسبة للمطورين ، يجب تحديث بعض نماذج كود تطبيق OpenSL ES لاستخدام خوارزميات غير محظورة أو الرجوع إلى مكتبة مفتوحة المصدر بخلاف Android.
لقد نشرنا مثالاً لتطبيق ما يرد أولاً يصرف أولاً (FIFO) غير المحظور والذي تم تصميمه خصيصًا لرمز التطبيق. انظر إلى هذه الملفات الموجودة في Frameworks directory frameworks/av/audio_utils
:
أدوات
على حد علمنا ، لا توجد أدوات تلقائية لإيجاد انعكاس الأولوية ، خاصة قبل حدوثه. بعض أدوات تحليل الكود الثابت للبحث قادرة على إيجاد الانقلابات ذات الأولوية إذا كانت قادرة على الوصول إلى قاعدة الكود بأكملها. بالطبع ، إذا تم تضمين رمز مستخدم عشوائي (كما هو الحال هنا للتطبيق) أو إذا كانت قاعدة بيانات كبيرة (كما هو الحال بالنسبة لنواة Linux وبرامج تشغيل الجهاز) ، فقد يكون التحليل الثابت غير عملي. أهم شيء هو قراءة الكود بعناية فائقة والحصول على فهم جيد للنظام بأكمله والتفاعلات. أدوات مثل systrace و ps -t -p
مفيدة لرؤية انعكاس الأولوية بعد حدوثه ، لكن لا تخبرك بذلك مسبقًا.
كلمة أخيرة
بعد كل هذا النقاش ، لا تخف من كائنات المزامنة. كائنات المزامنة هي صديقك للاستخدام العادي ، عند استخدامها وتنفيذها بشكل صحيح في حالات الاستخدام العادية غير الحرجة للوقت. ولكن بين المهام ذات الأولوية العالية والمنخفضة وفي الأنظمة الحساسة للوقت ، من المرجح أن تسبب كائنات المزامنة مشاكل.