Android 8.0 มีการทดสอบประสิทธิภาพ Binder และ Hwbinder สำหรับอัตราการส่งข้อมูลและ เวลาในการตอบสนอง แม้ว่าจะมีหลายสถานการณ์สำหรับการตรวจหาประสิทธิภาพที่รับรู้ได้ การใช้สถานการณ์เช่นนี้ อาจใช้เวลานาน และผลลัพธ์ที่ได้มัก ไม่สามารถใช้งานได้จนกว่าจะผสานรวมระบบ การใช้ประสิทธิภาพที่ระบุ ทำให้สามารถทดสอบระหว่างการพัฒนา ตรวจพบปัญหาร้ายแรงได้ง่ายขึ้น ก่อนหน้านี้และปรับปรุงประสบการณ์ของผู้ใช้
การทดสอบประสิทธิภาพประกอบด้วย 4 หมวดหมู่ต่อไปนี้
- อัตราการส่งข้อมูลของ Binder (ใช้ได้ใน
system/libhwbinder/vts/performance/Benchmark_binder.cpp
) - เวลาในการตอบสนองของ Binder (ใช้ได้ใน
frameworks/native/libs/binder/tests/schd-dbg.cpp
) - อัตราการส่งข้อมูล hwbinder (มีให้บริการใน
system/libhwbinder/vts/performance/Benchmark.cpp
) - เวลาในการตอบสนองของ Hwbinder (ใช้ได้ใน
system/libhwbinder/vts/performance/Latency.cpp
)
เกี่ยวกับ Binder และ hwbinder
Binder และ hwbinder คือการสื่อสารระหว่างโปรเซส (IPC) ของ Android โครงสร้างพื้นฐานที่ใช้ไดรเวอร์ Linux เดียวกัน แต่มีสิ่งต่อไปนี้ ความแตกต่างเชิงคุณภาพ
อัตราส่วน | Binder | Hwbinder |
---|---|---|
วัตถุประสงค์ | ระบุรูปแบบ IPC อเนกประสงค์สำหรับเฟรมเวิร์ก | สื่อสารกับฮาร์ดแวร์ |
พร็อพเพอร์ตี้ | เพิ่มประสิทธิภาพสำหรับการใช้งานเฟรมเวิร์กของ Android | ค่าโสหุ้ยขั้นต่ำเวลาในการตอบสนองต่ำ |
เปลี่ยนนโยบายการตั้งเวลาสำหรับเบื้องหน้า/เบื้องหลัง | ใช่ | ไม่ |
อาร์กิวเมนต์ | ใช้การเรียงอันดับที่ออบเจ็กต์ Parcel รองรับ | ใช้บัฟเฟอร์กระจายและหลีกเลี่ยงส่วนเกินในการคัดลอกข้อมูลที่จำเป็นสำหรับ การเรียงอันดับที่ดิน |
การสืบทอดลำดับความสำคัญ | ไม่ | ใช่ |
กระบวนการ Binder และ Hwbinder
เครื่องมือแสดงข้อมูลผ่านภาพ systrace จะแสดงธุรกรรมดังนี้
ในตัวอย่างด้านบน
- กระบวนการ schd-dbg สี่ (4) คือกระบวนการของไคลเอ็นต์
- กระบวนการในการเชื่อมโยงสี่ (4) กระบวนการคือกระบวนการของเซิร์ฟเวอร์ (ชื่อขึ้นต้นด้วย การเชื่อมโยงและลงท้ายด้วยหมายเลขลำดับ)
- กระบวนการของไคลเอ็นต์จะจับคู่กับกระบวนการของเซิร์ฟเวอร์เสมอ ซึ่งมีไว้สำหรับ ให้ลูกค้าได้
- เคอร์เนลจัดตารางเวลาคู่กระบวนการของไคลเอ็นต์เซิร์ฟเวอร์ทั้งหมดแยกกันแล้ว พร้อมกัน
ใน CPU 1 เคอร์เนลของระบบปฏิบัติการจะดำเนินการกับไคลเอ็นต์เพื่อออกคำขอ แล้ว จะใช้ CPU ตัวเดียวกันเมื่อใดก็ตามที่เป็นไปได้ในการเรียกกระบวนการของเซิร์ฟเวอร์จัดการ แล้วระบบจะเปลี่ยนบริบทกลับมาหลังจากที่คำขอเสร็จสมบูรณ์
อัตราการส่งข้อมูลเทียบกับเวลาในการตอบสนอง
ธุรกรรมที่สมบูรณ์ ซึ่งมีการเปลี่ยนกระบวนการของไคลเอ็นต์และเซิร์ฟเวอร์ อย่างราบรื่น การทดสอบอัตราการส่งข้อมูลและเวลาในการตอบสนองไม่ได้ให้ความแตกต่างอย่างมาก ข้อความ อย่างไรก็ตาม เมื่อเคอร์เนลของระบบปฏิบัติการจัดการคำขอรบกวน (IRQ) จากฮาร์ดแวร์ รอล็อก หรือเพียงแค่เลือกที่จะไม่จัดการกับข้อความ ในทันที ลูกโป่งเวลาในการตอบสนองจึงเกิดขึ้น
การทดสอบอัตราการส่งข้อมูลสร้างธุรกรรมจำนวนมากที่มี ขนาดของเพย์โหลด เป็นการให้ค่าประมาณที่ดีสำหรับเวลาการทำธุรกรรมปกติ (ใน ในสถานการณ์ที่ดีที่สุด) และอัตราการส่งข้อมูลสูงสุดที่ได้รับจาก Binder
ในทางตรงกันข้าม การทดสอบเวลาในการตอบสนองไม่ได้ดำเนินการใดๆ กับเพย์โหลดเพื่อลด เวลาทำธุรกรรมปกติ เราสามารถใช้เวลาในการทำธุรกรรมเพื่อประเมินไฟล์ Binder ในการดำเนินการ สร้างสถิติสำหรับกรณีที่เลวร้ายที่สุด และคำนวณอัตราส่วนของ ธุรกรรมที่มีเวลาในการตอบสนองตรงตามกำหนดเวลาที่ระบุ
จัดการการกลับลำดับความสำคัญ
การกลับลำดับความสำคัญจะเกิดขึ้นเมื่อเทรดที่มีลำดับความสำคัญสูงกว่าเป็นไปตามตรรกะ กำลังรอชุดข้อความที่มีลำดับความสำคัญต่ำกว่า แอปพลิเคชันแบบเรียลไทม์ (RT) มี ปัญหาการกลับลำดับความสำคัญ:
เมื่อใช้การกำหนดเวลา Singlely Fair Scheduler (CFS) สำหรับ Linux ชุดข้อความเสมอ มีโอกาสที่จะทำงานแม้ว่าชุดข้อความอื่นๆ จะมีลำดับความสำคัญสูงกว่า ด้วยเหตุนี้ แอปพลิเคชันที่มีการกำหนดเวลา CFS จะจัดการกับการกลับลำดับความสำคัญตามลักษณะการทำงานที่คาดไว้ และไม่ใช่ปัญหา ในกรณีที่เฟรมเวิร์ก Android จำเป็นต้องกำหนดเวลา RT เพื่อรับประกันสิทธิ์ของชุดข้อความที่มีลำดับความสำคัญสูง แต่การกลับลำดับความสำคัญ ต้องได้รับการแก้ไข
ตัวอย่างการกลับลำดับความสำคัญระหว่างธุรกรรม Binder (เทรด RT คือ บล็อกแบบตรรกะโดยเทรด CFS อื่นๆ เมื่อรอเทรด Binder เพื่อ บริการ):
คุณสามารถใช้การรับช่วงลำดับความสำคัญเพื่อส่งต่อชั่วคราวเพื่อหลีกเลี่ยงการบล็อกได้ เทรด Binder ไปยังเทรด RT เมื่อบริการคำขอจากไคลเอ็นต์ RT โปรดทราบว่าการจัดตารางเวลา RT มีทรัพยากรจํากัดและควรใช้ อย่างรอบคอบ ในระบบที่มี CPU n จำนวนสูงสุดของ RT ในปัจจุบัน ชุดข้อความอาจเป็น n ด้วย เทรด RT เพิ่มเติมอาจต้องรอ (และด้วยเหตุนี้ ไม่ทันกำหนดเวลา) หาก CPU ทั้งหมดใช้เทรด RT อื่นๆ
ในการแก้ปัญหาการกลับลำดับความสำคัญที่เป็นไปได้ทั้งหมด คุณสามารถใช้ลำดับความสำคัญ การสืบทอดค่าสำหรับทั้ง Binder และ hwbinder แต่เนื่องจาก binder เป็นคำที่ใช้กันอย่างแพร่หลาย ทั่วทั้งระบบ การเปิดใช้การสืบทอดลำดับความสำคัญสำหรับธุรกรรม Binder อาจ ส่งสแปมไปยังระบบด้วยชุดข้อความ RT มากกว่าที่จะให้บริการได้
ทำการทดสอบอัตราการส่งข้อมูล
การทดสอบอัตราการส่งข้อมูลจะดำเนินการเทียบกับอัตราการส่งข้อมูลธุรกรรม Binder/hwbinder ใน ระบบที่ไม่โหลดมากเกินไป ลูกโป่งเวลาในการตอบสนองจึงพบไม่บ่อยนักและผลกระทบที่เกิดขึ้น สามารถกำจัดได้ตราบใดที่ จำนวนการทำซ้ำสูงพอ
- การทดสอบอัตราการส่งข้อมูล binder อยู่ใน
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
- เวลาแสดงการหน่วงเวลาไป-กลับซึ่งวัดแบบเรียลไทม์
- CPU ระบุเวลาสะสมเมื่อมีการกำหนดเวลา CPU ในการทดสอบ
- การทำซ้ำแสดงจำนวนครั้งที่ฟังก์ชันทดสอบ ดำเนินการแล้ว
เช่น สำหรับเพย์โหลด 8 ไบต์
BM_sendVec_binderize/8 69974 ns 32700 ns 21296
... อัตราการส่งข้อมูลสูงสุดที่ไฟล์ Binder ทำได้มีวิธีคำนวณดังนี้
อัตราการส่งข้อมูลสูงสุดที่มีเพย์โหลด 8 ไบต์ = (8 * 21296)/69974 ~= 2.423 b/ns ~= 2.268 GB/วินาที
ตัวเลือกการทดสอบ
หากต้องการดูผลลัพธ์เป็นไฟล์ .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"
},
….
}
ทำการทดสอบเวลาในการตอบสนอง
การทดสอบเวลาในการตอบสนองจะวัดเวลาที่ไคลเอ็นต์ใช้ในการเริ่มต้น กำลังเริ่มธุรกรรม สลับไปที่กระบวนการของเซิร์ฟเวอร์ในการจัดการ และ ผลลัพธ์ การทดสอบยังมองหาลักษณะการทำงานของการจัดตารางเวลาที่ไม่ดีที่ทราบ ซึ่ง อาจส่งผลเสียต่อเวลาในการตอบสนองของธุรกรรม เช่น เครื่องจัดตารางเวลาที่ไม่ รองรับการสืบทอดลำดับความสำคัญหรือทำตามแฟล็กการซิงค์
- การทดสอบเวลาในการตอบสนองของ Binder อยู่ใน
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
- สร้างคู่ไคลเอ็นต์และเซิร์ฟเวอร์ 1 คู่
"iterations": 5000
- มีการทำซ้ำ 5,000 ครั้ง
"deadline_us":2500
- กำหนดเวลาคือ 2,500 USD (2.5 มิลลิวินาที) ธุรกรรมส่วนใหญ่ควรเป็นไปตามนี้
"I": 10000
- การทดสอบซ้ำ 1 ครั้งประกอบด้วยธุรกรรม 2 รายการ ได้แก่
- ธุรกรรม 1 รายการตามลำดับความสำคัญปกติ (
CFS other
) - ธุรกรรม 1 รายการตามลำดับความสำคัญแบบเรียลไทม์ (
RT-fifo
)
- ธุรกรรม 1 รายการตามลำดับความสำคัญปกติ (
"S": 9352
- ธุรกรรม 9,352 รายการซิงค์อยู่ใน CPU เดียวกัน
"R": 0.9352
- ระบุอัตราส่วนที่ไคลเอ็นต์และเซิร์ฟเวอร์ซิงค์กัน CPU ตัวเดียวกัน
"other_ms":{ "avg":0.2 , "wst":2.8 , "bst":0.053, "miss":2, "meetR":0.9996}
- ค่าเฉลี่ย (
avg
) แย่ที่สุด (wst
) และดีที่สุด (bst
) สำหรับธุรกรรมทั้งหมดที่ออกโดยผู้โทรที่มีลำดับความสำคัญปกติ ธุรกรรม 2 รายการ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
Tuple ในการทดสอบเวลาในการตอบสนอง เฉพาะ
fifo_ms
อาจแสดงผลลัพธ์ที่คล้ายกันได้ตราบใดที่การโหลดในเบื้องหลัง
ลำดับความสำคัญต่ำกว่า RT-fifo
ระบุค่าคู่
กระบวนการของไคลเอ็นต์แต่ละกระบวนการจะจับคู่กับกระบวนการของเซิร์ฟเวอร์ที่มีไว้สำหรับไคลเอ็นต์โดยเฉพาะ
และอาจตั้งเวลาแต่ละคู่ให้กับ CPU ตัวใดก็ได้แยกกัน อย่างไรก็ตาม CPU
การย้ายข้อมูลไม่ควรเกิดขึ้นระหว่างการทำธุรกรรมตราบใดที่แฟล็กของ SYNC
honor
ตรวจสอบว่าระบบไม่ได้ทำงานหนักเกินไป! ขณะที่เวลาในการตอบสนองสูงในช่วง
ระบบเป็นไปตามที่คาดไว้ ผลการทดสอบสำหรับระบบที่มีการใช้งานมากเกินไปไม่ได้ให้ประโยชน์
หากต้องการทดสอบระบบที่มีแรงดันสูงกว่า โปรดใช้ -pair
#cpu-1
(หรือ -pair #cpu
ด้วยความระมัดระวัง) การทดสอบโดยใช้
-pair n
ที่มี n > #cpu
โอเวอร์โหลด
ระบบและสร้างข้อมูลที่ไม่มีประโยชน์ขึ้นมา
ระบุค่ากำหนดเวลา
หลังการทดสอบสถานการณ์ผู้ใช้ที่ครอบคลุม (การเรียกใช้การทดสอบเวลาในการตอบสนองใน ผลิตภัณฑ์ที่มีคุณสมบัติตามเกณฑ์) เราเห็นว่าเวลา 2.5 มิลลิวินาทีเป็นกำหนดเวลาในการดำเนินการ สำหรับมือใหม่ แอปพลิเคชันที่มีความต้องการสูง (เช่น 1,000 ภาพ/วินาที) ค่ากำหนดเวลาจะเปลี่ยนไป
ระบุเอาต์พุตแบบละเอียด
การใช้ตัวเลือก -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
ทำงานและซิงค์กับ CPU เดียวกันกับไคลเอ็นต์ - ผู้โทรธุรกรรมครั้งที่ 2 มี
ลำดับความสำคัญ
SCHED_OTHER
เซิร์ฟเวอร์จะดาวน์เกรดตัวเองและบริการ ผู้โทรที่มีลำดับความสำคัญSCHED_OTHER
ใช้การติดตามเพื่อแก้ไขข้อบกพร่อง
คุณระบุตัวเลือก -trace
เพื่อแก้ปัญหาเวลาในการตอบสนองได้ วันและเวลา
ที่ใช้ การทดสอบเวลาในการตอบสนองจะหยุดการบันทึก Tracelog ในช่วงเวลาที่ประสิทธิภาพไม่ดี
ตรวจพบเวลาในการตอบสนอง ตัวอย่าง
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
คอมโพเนนต์ต่อไปนี้อาจส่งผลต่อเวลาในการตอบสนอง
- โหมดบิลด์ของ Android โหมด Eng มักจะช้ากว่า โหมด userdebug
- เฟรมเวิร์ก บริการเฟรมเวิร์กใช้อย่างไร
ioctl
เพื่อกำหนดค่าลงในไฟล์ Binder ไหม - ไดรเวอร์ Binder คนขับรองรับแบบละเอียดไหม ล็อกไหม มีการใช้แพตช์สำหรับการเปลี่ยนประสิทธิภาพทั้งหมดไหม
- เวอร์ชันเคอร์เนล เคอร์เนลมีความสามารถแบบเรียลไทม์ที่ดีกว่า ยิ่งมีผลลัพธ์ที่ดีขึ้นเท่านั้น
- การกำหนดค่าเคอร์เนล การกำหนดค่าเคอร์เนลมี
การกำหนดค่า
DEBUG
รายการ เช่นDEBUG_PREEMPT
และDEBUG_SPIN_LOCK
ใช่ไหม - เครื่องจัดตารางเวลาเคอร์เนล เคอร์เนลมี Energy-Aware ไหม
เครื่องจัดตารางเวลา (EAS) หรือเครื่องจัดตารางเวลา Heterogeetic Multi-Processing (HMP) ใช้เคอร์เนลใดก็ได้
คนขับ (คนขับ
cpu-freq
, คนขับcpu-idle
,cpu-hotplug
เป็นต้น) จะส่งผลต่อเครื่องจัดตารางเวลาหรือไม่