اختبار الأداء

يتضمن Android 8.0 اختبارات أداء Binder وhwbinder للإنتاجية ووقت الاستجابة. على الرغم من وجود العديد من السيناريوهات لاكتشاف مشاكل الأداء الملحوظة، إلا أن تشغيل مثل هذه السيناريوهات يمكن أن يستغرق وقتًا طويلاً وغالبًا ما تكون النتائج غير متاحة إلا بعد تكامل النظام. يؤدي استخدام اختبارات الأداء المتوفرة إلى تسهيل الاختبار أثناء التطوير واكتشاف المشكلات الخطيرة مبكرًا وتحسين تجربة المستخدم.

تشمل اختبارات الأداء الفئات الأربع التالية:

  • إنتاجية الموثق (متوفر في system/libhwbinder/vts/performance/Benchmark_binder.cpp )
  • زمن انتقال الموثق (متوفر في frameworks/native/libs/binder/tests/schd-dbg.cpp )
  • إنتاجية hwbinder (متوفرة في system/libhwbinder/vts/performance/Benchmark.cpp )
  • زمن استجابة hwbinder (متوفر في system/libhwbinder/vts/performance/Latency.cpp )

حول الموثق وhwbinder

Binder وhwbinder عبارة عن بنيات أساسية للاتصالات بين العمليات (IPC) لنظام التشغيل Android والتي تشترك في نفس برنامج تشغيل Linux ولكنها تحتوي على الاختلافات النوعية التالية:

وجه الموثق com.hwbinder
غاية توفير مخطط IPC للأغراض العامة للإطار التواصل مع الأجهزة
ملكية الأمثل لاستخدام إطار عمل أندرويد الحد الأدنى من الكمون المنخفض الحمل
تغيير سياسة الجدولة للمقدمة/الخلفية نعم لا
الحجج تمر يستخدم التسلسل الذي يدعمه كائن الطرود يستخدم المخازن المؤقتة المبعثرة ويتجنب الحمل الزائد لنسخ البيانات المطلوبة لتسلسل الطرود
الأولوية في الميراث لا نعم

عمليات الموثق و hwbinder

يعرض متخيل systrace المعاملات على النحو التالي:

الشكل 1. تصور Systrace لعمليات الموثق.

في المثال أعلاه:

  • العمليات الأربع (4) schd-dbg هي عمليات العميل.
  • عمليات الموثق الأربع (4) هي عمليات خادم (يبدأ الاسم بـ Binder وينتهي برقم تسلسلي).
  • يتم دائمًا إقران عملية العميل بعملية خادم مخصصة لعميلها.
  • تتم جدولة جميع أزواج عمليات العميل والخادم بشكل مستقل بواسطة kernel بشكل متزامن.

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

الإنتاجية مقابل الكمون

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

الشكل 2. فقاعة الكمون بسبب الاختلافات في الإنتاجية والكمون.

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

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

التعامل مع الانقلابات ذات الأولوية

يحدث انعكاس الأولوية عندما يكون مؤشر الترابط ذو الأولوية الأعلى في انتظار منطقي لمؤشر الترابط ذي الأولوية الأقل. تواجه تطبيقات الوقت الحقيقي (RT) مشكلة انعكاس الأولوية:

الشكل 3. انعكاس الأولوية في تطبيقات الوقت الحقيقي.

عند استخدام جدولة Linux Completely Fair مجدولة (CFS)، يكون لدى سلسلة الرسائل دائمًا فرصة للتشغيل حتى عندما تكون لسلاسل الرسائل الأخرى أولوية أعلى. ونتيجة لذلك، تتعامل التطبيقات ذات جدولة CFS مع انعكاس الأولوية كسلوك متوقع وليس كمشكلة. في الحالات التي يحتاج فيها إطار عمل Android إلى جدولة RT لضمان امتياز سلاسل العمليات ذات الأولوية العالية، يجب حل انعكاس الأولوية.

مثال على انعكاس الأولوية أثناء معاملة الموثق (يتم حظر مؤشر ترابط RT منطقيًا بواسطة مؤشرات ترابط CFS الأخرى عند انتظار خدمة مؤشر ترابط الموثق):

الشكل 4. انعكاس الأولوية، المواضيع المحظورة في الوقت الحقيقي.

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

لحل جميع عمليات عكس الأولوية المحتملة، يمكنك استخدام وراثة الأولوية لكل من Binder وhwbinder. ومع ذلك، نظرًا لاستخدام الموثق على نطاق واسع عبر النظام، فإن تمكين وراثة الأولوية لمعاملات الموثق قد يؤدي إلى إرسال بريد عشوائي إلى النظام باستخدام مؤشرات ترابط RT أكثر مما يمكنه خدمته.

تشغيل اختبارات الإنتاجية

يتم تشغيل اختبار الإنتاجية مقابل إنتاجية معاملات Binder/hwbinder. في النظام غير المثقل، تكون فقاعات الكمون نادرة ويمكن التخلص من تأثيرها طالما كان عدد التكرارات مرتفعًا بدرجة كافية.

  • اختبار إنتاجية الموثق موجود في system/libhwbinder/vts/performance/Benchmark_binder.cpp .
  • اختبار إنتاجية hwbinder موجود في system/libhwbinder/vts/performance/Benchmark.cpp .

نتائج الإختبار

أمثلة على نتائج اختبار الإنتاجية للمعاملات التي تستخدم أحجام حمولة مختلفة:

Benchmark                      Time          CPU           Iterations
---------------------------------------------------------------------
BM_sendVec_binderize/4         70302 ns      32820 ns      21054
BM_sendVec_binderize/8         69974 ns      32700 ns      21296
BM_sendVec_binderize/16        70079 ns      32750 ns      21365
BM_sendVec_binderize/32        69907 ns      32686 ns      21310
BM_sendVec_binderize/64        70338 ns      32810 ns      21398
BM_sendVec_binderize/128       70012 ns      32768 ns      21377
BM_sendVec_binderize/256       69836 ns      32740 ns      21329
BM_sendVec_binderize/512       69986 ns      32830 ns      21296
BM_sendVec_binderize/1024      69714 ns      32757 ns      21319
BM_sendVec_binderize/2k        75002 ns      34520 ns      20305
BM_sendVec_binderize/4k        81955 ns      39116 ns      17895
BM_sendVec_binderize/8k        95316 ns      45710 ns      15350
BM_sendVec_binderize/16k      112751 ns      54417 ns      12679
BM_sendVec_binderize/32k      146642 ns      71339 ns       9901
BM_sendVec_binderize/64k      214796 ns     104665 ns       6495
  • يشير الوقت إلى تأخير الرحلة ذهابًا وإيابًا الذي تم قياسه في الوقت الفعلي.
  • تشير وحدة المعالجة المركزية إلى الوقت المتراكم عند جدولة وحدات المعالجة المركزية للاختبار.
  • تشير التكرارات إلى عدد مرات تنفيذ وظيفة الاختبار.

على سبيل المثال، بالنسبة لحمولة 8 بايت:

BM_sendVec_binderize/8         69974 ns      32700 ns      21296

... يتم حساب الحد الأقصى من الإنتاجية التي يمكن أن يحققها الموثق على النحو التالي:

الحد الأقصى من الإنتاجية مع حمولة 8 بايت = (8 * 21296)/69974 ~= 2.423 b/ns ~= 2.268 جيجابت/ثانية

خيارات الاختبار

للحصول على نتائج بتنسيق .json، قم بإجراء الاختبار باستخدام وسيطة --benchmark_format=json :

libhwbinder_benchmark --benchmark_format=json
{
  "context": {
    "date": "2017-05-17 08:32:47",
    "num_cpus": 4,
    "mhz_per_cpu": 19,
    "cpu_scaling_enabled": true,
    "library_build_type": "release"
  },
  "benchmarks": [
    {
      "name": "BM_sendVec_binderize/4",
      "iterations": 32342,
      "real_time": 47809,
      "cpu_time": 21906,
      "time_unit": "ns"
    },
   ….
}

تشغيل اختبارات الكمون

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

  • اختبار زمن استجابة الموثق موجود في frameworks/native/libs/binder/tests/schd-dbg.cpp .
  • اختبار زمن استجابة hwbinder موجود في system/libhwbinder/vts/performance/Latency.cpp .

نتائج الإختبار

تعرض النتائج (بتنسيق .json) إحصائيات لمتوسط/أفضل/أسوأ وقت استجابة وعدد المواعيد النهائية التي لم يتم الوفاء بها.

خيارات الاختبار

تأخذ اختبارات زمن الوصول الخيارات التالية:

يأمر وصف
-i value تحديد عدد التكرارات.
-pair value حدد عدد أزواج العمليات.
-deadline_us 2500 تحديد الموعد النهائي فينا.
-v احصل على إخراج مطول (تصحيح الأخطاء).
-trace وقف التتبع على ضرب الموعد النهائي.

تعرض الأقسام التالية تفاصيل كل خيار، وتصف الاستخدام، وتقدم أمثلة للنتائج.

تحديد التكرارات

مثال مع عدد كبير من التكرارات والإخراج المطول معطل:

libhwbinder_latency -i 5000 -pair 3
{
"cfg":{"pair":3,"iterations":5000,"deadline_us":2500},
"P0":{"SYNC":"GOOD","S":9352,"I":10000,"R":0.9352,
  "other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2, "meetR":0.9996},
  "fifo_ms": { "avg":0.16, "wst":1.5 , "bst":0.067, "miss":0, "meetR":1}
},
"P1":{"SYNC":"GOOD","S":9334,"I":10000,"R":0.9334,
  "other_ms":{ "avg":0.19, "wst":2.9 , "bst":0.055, "miss":2, "meetR":0.9996},
  "fifo_ms": { "avg":0.16, "wst":3.1 , "bst":0.066, "miss":1, "meetR":0.9998}
},
"P2":{"SYNC":"GOOD","S":9369,"I":10000,"R":0.9369,
  "other_ms":{ "avg":0.19, "wst":4.8 , "bst":0.055, "miss":6, "meetR":0.9988},
  "fifo_ms": { "avg":0.15, "wst":1.8 , "bst":0.067, "miss":0, "meetR":1}
},
"inheritance": "PASS"
}

تظهر نتائج الاختبار ما يلي:

"pair":3
إنشاء زوج واحد من العميل والخادم.
"iterations": 5000
يتضمن 5000 التكرار.
"deadline_us":2500
الموعد النهائي هو 2500us (2.5 مللي ثانية)؛ ومن المتوقع أن تلبي معظم المعاملات هذه القيمة.
"I": 10000
يتضمن تكرار الاختبار الواحد معاملتين (2):
  • معاملة واحدة حسب الأولوية العادية ( CFS other )
  • معاملة واحدة حسب الأولوية في الوقت الفعلي ( RT-fifo )
5000 تكرار يساوي إجمالي 10000 معاملة.
"S": 9352
تتم مزامنة 9352 من المعاملات في نفس وحدة المعالجة المركزية.
"R": 0.9352
يشير إلى النسبة التي تتم بها مزامنة العميل والخادم معًا في نفس وحدة المعالجة المركزية.
"other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2, "meetR":0.9996}
الحالة المتوسطة ( avg ) والأسوأ ( wst ) والأفضل ( bst ) لجميع المعاملات الصادرة عن المتصل ذي الأولوية العادية. معاملتان miss الموعد النهائي، مما يجعل نسبة الوفاء ( meetR ) 0.9996.
"fifo_ms": { "avg":0.16, "wst":1.5 , "bst":0.067, "miss":0, "meetR":1}
مشابه لـ other_ms ، ولكن للمعاملات الصادرة عن العميل بأولوية rt_fifo . من المحتمل (ولكن ليس مطلوبًا) أن يكون لـ fifo_ms نتيجة أفضل من other_ms ، مع قيم avg و wst أقل و meetR أعلى (يمكن أن يكون الفرق أكثر أهمية مع التحميل في الخلفية).

ملاحظة: قد يؤثر التحميل في الخلفية على نتيجة الإنتاجية ومجموع other_ms في اختبار زمن الوصول. قد يُظهر fifo_ms فقط نتائج مماثلة طالما أن تحميل الخلفية له أولوية أقل من RT-fifo .

تحديد القيم الزوجية

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

تأكد من عدم تحميل النظام فوق طاقته! في حين أنه من المتوقع حدوث زمن استجابة مرتفع في الأنظمة المحملة بشكل زائد، إلا أن نتائج الاختبار الخاصة بالأنظمة المحملة بشكل زائد لا توفر معلومات مفيدة. لاختبار نظام ذي ضغط أعلى، استخدم -pair #cpu-1 (أو -pair #cpu بحذر). يؤدي الاختبار باستخدام -pair n مع n > #cpu إلى زيادة تحميل النظام وإنشاء معلومات غير مفيدة.

تحديد قيم الموعد النهائي

بعد اختبار سيناريو المستخدم الشامل (تشغيل اختبار زمن الوصول على منتج مؤهل)، قررنا أن 2.5 مللي ثانية هو الموعد النهائي للوفاء به. بالنسبة للتطبيقات الجديدة ذات المتطلبات الأعلى (مثل 1000 صورة/الثانية)، ستتغير قيمة الموعد النهائي هذا.

تحديد الإخراج المطول

يؤدي استخدام الخيار -v إلى عرض إخراج مطول. مثال:

libhwbinder_latency -i 1 -v

-------------------------------------------------- service pid: 8674 tid: 8674 cpu: 1 SCHED_OTHER 0
-------------------------------------------------- main pid: 8673 tid: 8673 cpu: 1 -------------------------------------------------- client pid: 8677 tid: 8677 cpu: 0 SCHED_OTHER 0
-------------------------------------------------- fifo-caller pid: 8677 tid: 8678 cpu: 0 SCHED_FIFO 99 -------------------------------------------------- hwbinder pid: 8674 tid: 8676 cpu: 0 ??? 99
-------------------------------------------------- other-caller pid: 8677 tid: 8677 cpu: 0 SCHED_OTHER 0 -------------------------------------------------- hwbinder pid: 8674 tid: 8676 cpu: 0 SCHED_OTHER 0
  • يتم إنشاء مؤشر ترابط الخدمة بأولوية SCHED_OTHER ويتم تشغيله في CPU:1 باستخدام pid 8674 .
  • يتم بعد ذلك بدء المعاملة الأولى بواسطة fifo-caller . لخدمة هذه المعاملة، يقوم hwbinder بترقية أولوية الخادم ( pid: 8674 tid: 8676 ) إلى 99 ويميزها أيضًا بفئة جدولة عابرة (مطبوعة كـ ??? ). يقوم المجدول بعد ذلك بوضع عملية الخادم في وحدة المعالجة CPU:0 للتشغيل ومزامنتها مع نفس وحدة المعالجة المركزية مع العميل الخاص به.
  • المتصل بالمعاملة الثانية له أولوية SCHED_OTHER . يقوم الخادم بتخفيض مستوى نفسه ويخدم المتصل بأولوية SCHED_OTHER .

استخدم التتبع لتصحيح الأخطاء

يمكنك تحديد خيار -trace لتصحيح مشكلات زمن الاستجابة. عند استخدامه، يقوم اختبار زمن الوصول بإيقاف تسجيل سجل التتبع في اللحظة التي يتم فيها اكتشاف زمن انتقال سيئ. مثال:

atrace --async_start -b 8000 -c sched idle workq binder_driver sync freq
libhwbinder_latency -deadline_us 50000 -trace -i 50000 -pair 3
deadline triggered: halt ∓ stop trace
log:/sys/kernel/debug/tracing/trace

يمكن أن تؤثر المكونات التالية على زمن الاستجابة:

  • وضع بناء أندرويد . عادةً ما يكون الوضع Eng أبطأ من وضع userdebug.
  • نطاق . كيف تستخدم خدمة إطار العمل ioctl لتكوين الموثق؟
  • سائق الموثق . هل يدعم السائق القفل الدقيق؟ هل يحتوي على جميع تصحيحات تحويل الأداء؟
  • إصدار النواة . كلما كانت قدرة النواة أفضل في الوقت الفعلي، كانت النتائج أفضل.
  • تكوين النواة . هل يحتوي تكوين kernel على تكوينات DEBUG مثل DEBUG_PREEMPT و DEBUG_SPIN_LOCK ؟
  • جدولة النواة . هل تحتوي النواة على برنامج جدولة مدرك للطاقة (EAS) أو برنامج جدولة متعدد المعالجة غير المتجانسة (HMP)؟ هل تؤثر أي برامج تشغيل kernel (برنامج تشغيل cpu-freq ، برنامج تشغيل cpu-idle ، cpu-hotplug ، وما إلى ذلك) على المجدول؟