คุณสามารถกำหนดค่าการติดตามระบบเพื่อบันทึก โปรไฟล์ CPU และเธรดของแอปในช่วงเวลาสั้นๆ จากนั้นคุณสามารถใช้รายงานเอาต์พุตจากการติดตามของระบบเพื่อปรับปรุงประสิทธิภาพของเกมได้
ตั้งค่าการติดตามของระบบที่อิงตามเกม
เครื่องมือ Systrace มีให้ใช้งาน 2 วิธีดังนี้
Systrace เป็นเครื่องมือระดับต่ำที่ทำสิ่งต่อไปนี้
- ให้ข้อมูลที่เป็นความจริง Systrace จะบันทึกเอาต์พุตจากเคอร์เนลโดยตรง ดังนั้นเมตริกที่บันทึกจึงเกือบจะเหมือนกับเมตริกที่ การเรียกใช้ระบบหลายครั้งจะรายงาน
- ใช้ทรัพยากรน้อย Systrace มีค่าใช้จ่ายต่ำมากในอุปกรณ์ โดยปกติจะน้อยกว่า 1% เนื่องจากสตรีมข้อมูลไปยังบัฟเฟอร์ในหน่วยความจำ
การตั้งค่าที่เหมาะสม
คุณควรระบุชุดอาร์กิวเมนต์ที่สมเหตุสมผลให้กับเครื่องมือ
- หมวดหมู่: ชุดหมวดหมู่ที่ดีที่สุดที่ควรเปิดใช้สำหรับระบบที่อิงตามเกม
คือ {
sched,freq,idle,am,wm,gfx,view,sync,binder_driver,hal,dalvik} ขนาดบัฟเฟอร์: กฎทั่วไปคือขนาดบัฟเฟอร์ 10 MB ต่อแกน CPU จะช่วยให้การติดตามมีความยาวประมาณ 20 วินาที ตัวอย่างเช่น หากอุปกรณ์มี CPU แบบ Quad-Core 2 ตัว (รวม 8 คอร์) ค่าที่เหมาะสมในการส่งไปยัง
systraceโปรแกรมคือ 80,000 KB (80 MB)หากเกมของคุณมีการสลับบริบทเป็นจำนวนมาก ให้เพิ่มบัฟเฟอร์เป็น 15 MB ต่อคอร์ CPU
เหตุการณ์ที่กําหนดเอง: หากคุณกําหนดเหตุการณ์ที่กําหนดเองเพื่อบันทึกในเกม ให้เปิดใช้ฟีเจอร์
-aซึ่งจะช่วยให้ Systrace รวมเหตุการณ์ที่กําหนดเองเหล่านี้ไว้ในรายงานเอาต์พุตได้
หากคุณใช้โปรแกรมsystraceบรรทัดคำสั่ง ให้ใช้คำสั่งต่อไปนี้ เพื่อบันทึกการติดตามของระบบที่ใช้แนวทางปฏิบัติแนะนำสำหรับชุดหมวดหมู่ ขนาดบัฟเฟอร์ และเหตุการณ์ที่กำหนดเอง
python systrace.py -a com.example.myapp -b 80000 -o my_systrace_report.html \ sched freq idle am wm gfx view sync binder_driver hal dalvik
หากคุณใช้แอปของระบบ Systrace ใน อุปกรณ์ ให้ทำตามขั้นตอนต่อไปนี้เพื่อ บันทึกการติดตามของระบบที่ใช้แนวทางปฏิบัติแนะนำสำหรับชุดหมวดหมู่ ขนาดบัฟเฟอร์ และเหตุการณ์ที่กำหนดเอง
เปิดใช้ตัวเลือกติดตามแอปพลิเคชันที่แก้ไขข้อบกพร่องได้
หากต้องการใช้การตั้งค่านี้ อุปกรณ์ต้องมีหน่วยความจำว่าง 256 MB หรือ 512 MB (ขึ้นอยู่กับว่า CPU มี 4 หรือ 8 คอร์) และหน่วยความจำแต่ละส่วนขนาด 64 MB ต้องพร้อมใช้งานเป็นก้อนที่ต่อเนื่องกัน
เลือกหมวดหมู่ แล้วเปิดใช้หมวดหมู่ในรายการต่อไปนี้
am: ตัวจัดการกิจกรรมbinder_driver: ไดรเวอร์เคอร์เนลของ Binderdalvik: Dalvik VMfreq: ความถี่ CPUgfx: กราฟิกhal: โมดูลฮาร์ดแวร์idle: CPU ไม่ได้ใช้งานsched: การจัดกำหนดการ CPUsync: การซิงค์view: ดูระบบwm: ตัวจัดการหน้าต่าง
เปิดใช้การบันทึกการติดตาม
โหลดเกม
โต้ตอบในเกมที่สอดคล้องกับการเล่นเกมที่คุณต้องการวัดประสิทธิภาพของอุปกรณ์
ปิดการติดตามระบบหลังจากพบพฤติกรรมที่ไม่พึงประสงค์ในเกมไม่นาน
คุณได้บันทึกสถิติประสิทธิภาพ ที่จำเป็นต่อการวิเคราะห์ปัญหาเพิ่มเติมแล้ว
การติดตามของระบบในอุปกรณ์จะบันทึกไฟล์ในรูปแบบการติดตามที่บีบอัด (*.ctrace) เพื่อประหยัดพื้นที่ในดิสก์ หากต้องการยกเลิกการบีบอัดไฟล์นี้เมื่อสร้างรายงาน ให้ใช้โปรแกรมบรรทัดคำสั่งและรวมตัวเลือก --from-file ดังนี้
python systrace.py --from-file=/data/local/traces/my_game_trace.ctrace \ -o my_systrace_report.html
ปรับปรุงด้านประสิทธิภาพที่เฉพาะเจาะจง
ส่วนนี้จะไฮไลต์ข้อกังวลด้านประสิทธิภาพที่พบบ่อยหลายประการในเกมมือถือ และอธิบายวิธีระบุและปรับปรุงแง่มุมเหล่านี้ของเกม
ความเร็วในการโหลด
ผู้เล่นต้องการเข้าสู่การต่อสู้ในเกมของคุณให้เร็วที่สุด ดังนั้นการปรับปรุงเวลาในการโหลดของเกมให้ได้มากที่สุดจึงเป็นสิ่งสำคัญ โดยปกติแล้ว มาตรการต่อไปนี้จะช่วยลดเวลาในการโหลดได้
- ใช้การโหลดแบบ Lazy Loading หากคุณใช้ชิ้นงานเดียวกันในฉากหรือเลเวลที่ต่อเนื่องกันในเกม ให้โหลดชิ้นงานเหล่านี้เพียงครั้งเดียว
- ลดขนาดชิ้นงาน ด้วยวิธีนี้ คุณจะรวมเวอร์ชันที่ไม่ได้บีบอัด ของชิ้นงานเหล่านี้ไว้กับ APK ของเกมได้
- ใช้วิธีการบีบอัดที่ประหยัดพื้นที่ดิสก์ ตัวอย่างของวิธีการดังกล่าวคือ zlib
- ใช้ IL2CPP แทน mono (ใช้ได้เมื่อคุณใช้ Unity เท่านั้น) IL2CPP ช่วยให้สคริปต์ C# ของคุณมีประสิทธิภาพการดำเนินการที่ดีขึ้น
- ทำให้เกมของคุณเป็นแบบมัลติเธรด ดูรายละเอียดเพิ่มเติมได้ที่ส่วนความสอดคล้องของ อัตราเฟรม
ความสม่ำเสมอของอัตราเฟรม
องค์ประกอบที่สำคัญที่สุดอย่างหนึ่งของประสบการณ์การเล่นเกมคือการมี อัตราเฟรมที่สม่ำเสมอ หากต้องการให้บรรลุเป้าหมายนี้ได้ง่ายขึ้น ให้ทําตาม เทคนิคการเพิ่มประสิทธิภาพที่กล่าวถึงในส่วนนี้
Multithreading
เมื่อพัฒนาเกมสำหรับหลายแพลตฟอร์ม คุณอาจวางกิจกรรมทั้งหมด ภายในเกมไว้ในเธรดเดียว แม้ว่าวิธีการดำเนินการนี้จะติดตั้งใช้งานได้ง่ายในเกมเอนจินหลายตัว แต่ก็ยังไม่ดีที่สุดเมื่อเรียกใช้บนอุปกรณ์ Android ด้วยเหตุนี้ เกมแบบ Single-Thread จึงมักโหลดช้าและมี อัตราเฟรมที่ไม่สม่ำเสมอ
Systrace ที่แสดงในรูปที่ 1 แสดงลักษณะการทำงานที่พบได้ทั่วไปในเกม ซึ่งทำงานบน CPU เพียงครั้งละ 1 ตัว
ทำให้เกมเป็นแบบมัลติเธรดเพื่อปรับปรุงประสิทธิภาพของเกม โดยปกติ โมเดลที่ดีที่สุดคือการมี 2 เธรด ดังนี้
- เธรดเกมซึ่งมีโมดูลหลักของเกมและส่งคำสั่งการแสดงผล
- เธรดการแสดงผลซึ่งรับคำสั่งการแสดงผลและแปลเป็นคำสั่งกราฟิกที่ GPU ของอุปกรณ์ใช้เพื่อแสดงฉากได้
Vulkan API ขยายโมเดลนี้เนื่องจากมีความสามารถในการพุชบัฟเฟอร์ทั่วไป 2 รายการพร้อมกัน การใช้ฟีเจอร์นี้จะช่วยให้คุณกระจายเธรดการแสดงผลหลายรายการใน CPU หลายตัว ซึ่งจะช่วยปรับปรุงเวลาในการแสดงผลของฉากให้ดียิ่งขึ้น
นอกจากนี้ คุณยังทำการเปลี่ยนแปลงเฉพาะเอนจินบางอย่างเพื่อเพิ่มประสิทธิภาพ การทำงานแบบหลายเธรดของเกมได้ด้วย
- หากคุณพัฒนาเกมโดยใช้เกมเอนจินของ Unity ให้เปิดใช้ตัวเลือกการแสดงผลแบบหลายเธรดและการปรับสกิน GPU
- หากใช้เครื่องมือการแสดงผลที่กำหนดเอง โปรดตรวจสอบว่าไปป์ไลน์คำสั่งการแสดงผล และไปป์ไลน์คำสั่งกราฟิกสอดคล้องกันอย่างถูกต้อง มิฉะนั้น คุณ อาจทำให้เกิดความล่าช้าในการแสดงฉากของเกม
หลังจากใช้การเปลี่ยนแปลงเหล่านี้แล้ว คุณควรเห็นเกมใช้ CPU อย่างน้อย 2 ตัวพร้อมกัน ดังที่แสดงในรูปที่ 2
การโหลดองค์ประกอบ UI
เมื่อสร้างเกมที่มีฟีเจอร์มากมาย คุณอาจอยากแสดงตัวเลือกและการดำเนินการต่างๆ แก่ผู้เล่นพร้อมกัน อย่างไรก็ตาม เพื่อรักษาอัตราเฟรมให้สม่ำเสมอ คุณควรพิจารณาขนาดหน้าจอมือถือที่ค่อนข้างเล็ก และออกแบบ UI ให้เรียบง่ายที่สุด
รายงาน Systrace ที่แสดงในรูปที่ 3 เป็นตัวอย่างของเฟรม UI ที่ พยายามแสดงองค์ประกอบมากเกินไปเมื่อเทียบกับความสามารถของอุปกรณ์เคลื่อนที่
เป้าหมายที่ดีคือลดเวลาในการอัปเดต UI เป็น 2-3 มิลลิวินาที คุณสามารถ อัปเดตได้อย่างรวดเร็วโดยทำการเพิ่มประสิทธิภาพที่คล้ายกับต่อไปนี้
- อัปเดตเฉพาะองค์ประกอบบนหน้าจอที่ย้าย
- จำกัดจำนวนพื้นผิวและเลเยอร์ UI พิจารณารวมการเรียกกราฟิก เช่น Shader และ Texture ที่ใช้วัสดุเดียวกัน
- เลื่อนการดำเนินการภาพเคลื่อนไหวขององค์ประกอบไปยัง GPU
- ทำการคัดกรองฟรัสตัมและการบดบังที่เข้มงวดมากขึ้น
- หากเป็นไปได้ ให้ดำเนินการวาดโดยใช้ Vulkan API ค่าใช้จ่ายของคำสั่งประมวลผลต่ำกว่าใน Vulkan
การใช้พลังงาน
แม้จะเพิ่มประสิทธิภาพตามที่กล่าวถึงในส่วนก่อนหน้าแล้ว คุณก็อาจพบว่าอัตราเฟรมของเกมลดลงภายใน 45-50 นาทีแรกของการเล่นเกม นอกจากนี้ อุปกรณ์อาจเริ่มร้อนขึ้นและใช้แบตเตอรี่มากขึ้นเมื่อเวลาผ่านไป
ในหลายกรณี ชุดความร้อนและการใช้พลังงานที่ไม่พึงประสงค์นี้เกี่ยวข้อง กับวิธีที่ปริมาณงานของเกมกระจายไปทั่ว CPU ของอุปกรณ์ ใช้แนวทางปฏิบัติแนะนำที่แสดงในส่วนต่อไปนี้เพื่อเพิ่มประสิทธิภาพการใช้พลังงานของเกม
เก็บชุดข้อความที่ใช้หน่วยความจำมากไว้ใน CPU เดียว
ในอุปกรณ์เคลื่อนที่หลายเครื่อง แคช L1 จะอยู่ใน CPU ที่เฉพาะเจาะจง และแคช L2 จะอยู่ในชุด CPU ที่ใช้สัญญาณนาฬิกาเดียวกัน โดยทั่วไปแล้ว วิธีที่ดีที่สุดในการเพิ่มจำนวนการพบแคช L1 คือการรันเทรดหลักของเกมพร้อมกับเทรดอื่นๆ ที่ใช้หน่วยความจำมากใน CPU เดียว
เลื่อนงานระยะสั้นไปยัง CPU ที่มีกำลังต่ำกว่า
เอนจินเกมส่วนใหญ่ รวมถึง Unity จะทราบว่าควรเลื่อนการดำเนินการของ Worker Thread ไปยัง CPU อื่นที่เกี่ยวข้องกับ Main Thread ของเกม อย่างไรก็ตาม เครื่องมือนี้ไม่ทราบสถาปัตยกรรมที่เฉพาะเจาะจงของอุปกรณ์และไม่สามารถคาดการณ์ภาระงานของเกมได้ดีเท่าคุณ
อุปกรณ์ระบบบนชิปส่วนใหญ่มีสัญญาณนาฬิกาที่ใช้ร่วมกันอย่างน้อย 2 รายการ โดยรายการหนึ่งสำหรับ CPU ที่รวดเร็วของอุปกรณ์ และอีกรายการหนึ่งสำหรับ CPU ที่ช้าของอุปกรณ์ ผลที่ตามมาของสถาปัตยกรรมนี้คือ หาก CPU ที่รวดเร็วตัวหนึ่งต้องทำงานด้วยความเร็วสูงสุด CPU ที่รวดเร็วตัวอื่นๆ ทั้งหมดก็จะทำงานด้วยความเร็วสูงสุดเช่นกัน
รายงานตัวอย่างที่แสดงในรูปที่ 4 แสดงเกมที่ใช้ประโยชน์จาก CPU ที่รวดเร็ว อย่างไรก็ตาม กิจกรรมระดับสูงนี้จะสร้างพลังงานและความร้อนจำนวนมากอย่างรวดเร็ว
เพื่อลดการใช้พลังงานโดยรวม วิธีที่ดีที่สุดคือการแนะนำให้ตัวจัดกำหนดการเลื่อนงานที่มีระยะเวลาสั้นกว่า เช่น การโหลดเสียง การเรียกใช้เทรดผู้ปฏิบัติงาน และการเรียกใช้ Choreographer ไปยังชุด CPU ที่ช้าในอุปกรณ์ โอนงานนี้ไปยัง CPU ที่ช้าให้ได้มากที่สุดในขณะที่ยังคงรักษา อัตราเฟรมที่ต้องการไว้
อุปกรณ์ส่วนใหญ่จะแสดง CPU ที่ช้าก่อน CPU ที่เร็ว แต่คุณไม่ควรคิดว่า SOC ของอุปกรณ์ใช้ลำดับนี้ หากต้องการตรวจสอบ ให้เรียกใช้คำสั่งที่คล้ายกับคำสั่งที่แสดงในโค้ดการค้นพบโทโพโลยี CPU ใน GitHub
หลังจากทราบว่า CPU ใดในอุปกรณ์ที่ทำงานช้าแล้ว คุณจะประกาศ ความสัมพันธ์สำหรับเธรดระยะสั้นซึ่งตัวกำหนดเวลาของอุปกรณ์ จะทำตามได้ โดยเพิ่มโค้ดต่อไปนี้ภายในแต่ละเธรด
#include <sched.h> #include <sys/types.h> #include <unistd.h> pid_t my_pid; // PID of the process containing your thread. // Assumes that cpu0, cpu1, cpu2, and cpu3 are the "slow CPUs". cpu_set_t my_cpu_set; CPU_ZERO(&my_cpu_set); CPU_SET(0, &my_cpu_set); CPU_SET(1, &my_cpu_set); CPU_SET(2, &my_cpu_set); CPU_SET(3, &my_cpu_set); sched_setaffinity(my_pid, sizeof(cpu_set_t), &my_cpu_set);
ความเครียดจากความร้อน
เมื่ออุปกรณ์ร้อนเกินไป อุปกรณ์อาจจำกัดความเร็ว CPU และ/หรือ GPU ซึ่งอาจส่งผลต่อเกมในลักษณะที่ไม่คาดคิด เกมที่มีกราฟิกซับซ้อน การคำนวณหนัก หรือกิจกรรมเครือข่ายที่ต่อเนื่องมีแนวโน้มที่จะพบปัญหามากกว่า
ใช้ Thermal API เพื่อตรวจสอบการเปลี่ยนแปลงอุณหภูมิในอุปกรณ์และดำเนินการเพื่อ รักษาการใช้พลังงานที่ต่ำลงและอุณหภูมิของอุปกรณ์ที่เย็นลง เมื่ออุปกรณ์รายงาน ความร้อนสูง ให้หยุดกิจกรรมต่อเนื่องที่กำลังทำอยู่เพื่อลด การใช้พลังงาน เช่น ลดอัตราเฟรมหรือการปูผิวรูปหลายเหลี่ยม
ก่อนอื่น ให้ประกาศออบเจ็กต์ PowerManager และ
เริ่มต้นในเมธอด onCreate() เพิ่มเครื่องมือฟังสถานะความร้อนลงในออบเจ็กต์
Kotlin
class MainActivity : AppCompatActivity() { lateinit var powerManager: PowerManager override fun onCreate(savedInstanceState: Bundle?) { powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager powerManager.addThermalStatusListener(thermalListener) } }
Java
public class MainActivity extends AppCompatActivity { PowerManager powerManager; @Override protected void onCreate(Bundle savedInstanceState) { ... powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); powerManager.addThermalStatusListener(thermalListener); } }
กำหนดการดำเนินการที่จะทำเมื่อ Listener ตรวจพบการเปลี่ยนแปลงสถานะ หากเกมใช้ C/C++ ให้เพิ่มโค้ดลงในระดับสถานะความร้อนใน
onThermalStatusChanged() เพื่อเรียกใช้โค้ดเกมแบบเนทีฟโดยใช้ JNI
หรือใช้ Thermal API แบบเนทีฟ
Kotlin
val thermalListener = object : PowerManager.OnThermalStatusChangedListener() { override fun onThermalStatusChanged(status: Int) { when (status) { PowerManager.THERMAL_STATUS_NONE -> { // No thermal status, so no action necessary } PowerManager.THERMAL_STATUS_LIGHT -> { // Add code to handle light thermal increase } PowerManager.THERMAL_STATUS_MODERATE -> { // Add code to handle moderate thermal increase } PowerManager.THERMAL_STATUS_SEVERE -> { // Add code to handle severe thermal increase } PowerManager.THERMAL_STATUS_CRITICAL -> { // Add code to handle critical thermal increase } PowerManager.THERMAL_STATUS_EMERGENCY -> { // Add code to handle emergency thermal increase } PowerManager.THERMAL_STATUS_SHUTDOWN -> { // Add code to handle immediate shutdown } } } }
Java
PowerManager.OnThermalStatusChangedListener thermalListener = new PowerManager.OnThermalStatusChangedListener () { @Override public void onThermalStatusChanged(int status) { switch (status) { case PowerManager.THERMAL_STATUS_NONE: // No thermal status, so no action necessary break; case PowerManager.THERMAL_STATUS_LIGHT: // Add code to handle light thermal increase break; case PowerManager.THERMAL_STATUS_MODERATE: // Add code to handle moderate thermal increase break; case PowerManager.THERMAL_STATUS_SEVERE: // Add code to handle severe thermal increase break; case PowerManager.THERMAL_STATUS_CRITICAL: // Add code to handle critical thermal increase break; case PowerManager.THERMAL_STATUS_EMERGENCY: // Add code to handle emergency thermal increase break; case PowerManager.THERMAL_STATUS_SHUTDOWN: // Add code to handle immediate shutdown break; } } };
เวลาในการตอบสนองจากการสัมผัสจนถึงการแสดงผล
เกมที่แสดงผลเฟรมให้เร็วที่สุดเท่าที่จะเป็นไปได้จะสร้างสถานการณ์ที่ GPU ทำงานหนัก ซึ่งบัฟเฟอร์เฟรมจะทำงานหนักเกินไป CPU ต้องรอ GPU ซึ่งทำให้เกิดความล่าช้าที่สังเกตได้ระหว่างอินพุตของผู้เล่นกับอินพุตที่ มีผลบนหน้าจอ
หากต้องการพิจารณาว่าคุณปรับปรุงการเว้นเฟรมของเกมได้หรือไม่ ให้ทำตาม ขั้นตอนต่อไปนี้
- สร้างรายงาน Systrace ที่มีหมวดหมู่
gfxและinputหมวดหมู่เหล่านี้ประกอบด้วยการวัดผลที่มีประโยชน์อย่างยิ่งในการพิจารณา เวลาในการตอบสนองต่อการแตะเพื่อแสดงผล ดูส่วน
SurfaceViewของรายงาน Systrace บัฟเฟอร์ที่มากเกินไป ทำให้จำนวนการวาดบัฟเฟอร์ที่รอดำเนินการสลับไปมาระหว่าง 1 ถึง 2 ดังที่แสดง ในรูปที่ 5รูปที่ 5 รายงาน Systrace แสดงบัฟเฟอร์ที่เต็มเกินไป ซึ่ง เต็มเกินไปเป็นระยะๆ จนรับคำสั่งวาดไม่ได้
หากต้องการลดความไม่สอดคล้องในการเว้นระยะเฟรม ให้ดำเนินการตามที่อธิบายไว้ ในส่วนต่อไปนี้
ผสานรวม Android Frame Pacing API เข้ากับเกม
Android Frame Pacing API ช่วยให้คุณ สลับเฟรมและกำหนดช่วงการสลับเพื่อให้เกมรักษา เฟรมเรตที่สม่ำเสมอมากขึ้น
ลดความละเอียดของชิ้นงานที่ไม่ใช่ UI ของเกม
จอแสดงผลในอุปกรณ์เคลื่อนที่สมัยใหม่มีพิกเซลมากกว่าที่เพลเยอร์จะประมวลผลได้มาก จึงไม่เป็นไรหากจะลดขนาดตัวอย่างเพื่อให้พิกเซล 5 หรือ 10 พิกเซลมีสีเดียวกัน เนื่องจากโครงสร้างของแคช Display ส่วนใหญ่ วิธีที่ดีที่สุดคือลดความละเอียดตามมิติเดียวเท่านั้น
อย่างไรก็ตาม อย่าลดความละเอียดขององค์ประกอบ UI ของเกม คุณควร รักษาระดับความหนาของเส้นบนองค์ประกอบเหล่านี้ไว้เพื่อรักษาขนาดเป้าหมายการสัมผัส ให้ใหญ่พอสำหรับผู้เล่นทุกคน
ความราบรื่นในการแสดงผล
เมื่อ SurfaceFlinger เชื่อมต่อกับบัฟเฟอร์การแสดงผลเพื่อแสดงฉากในเกม กิจกรรมของ CPU จะเพิ่มขึ้นชั่วคราว หากกิจกรรม CPU เพิ่มขึ้นอย่างไม่สม่ำเสมอ คุณอาจเห็นเกมกระตุก แผนภาพในรูปที่ 6 แสดงสาเหตุที่ทำให้เกิดเหตุการณ์นี้
หากเฟรมเริ่มวาดช้าเกินไป แม้จะช้าเพียงไม่กี่มิลลิวินาที เฟรมนั้นอาจพลาด หน้าต่างการแสดงผลถัดไป จากนั้นเฟรมจะต้องรอจนกว่าจะถึง Vsync ครั้งถัดไปจึงจะแสดงได้ (33 มิลลิวินาทีเมื่อเล่นเกมที่ 30 FPS) ซึ่งทำให้เกิดความล่าช้าที่ผู้เล่นสังเกตเห็นได้
หากต้องการแก้ไขสถานการณ์นี้ ให้ใช้ Android Frame Pacing API ซึ่งจะแสดงเฟรมใหม่บน VSync wavefront เสมอ
สถานะหน่วยความจำ
เมื่อเรียกใช้เกมเป็นเวลานาน อุปกรณ์อาจพบข้อผิดพลาดเกี่ยวกับหน่วยความจำไม่เพียงพอ
ในกรณีนี้ ให้ตรวจสอบกิจกรรมของ CPU ในรายงาน Systrace และดูความถี่ที่ระบบเรียกใช้ Daemon kswapd หากมีการเรียกใช้จำนวนมาก
ในระหว่างการดำเนินการของเกม คุณควรพิจารณาอย่างละเอียดว่าเกม
จัดการและล้างหน่วยความจำอย่างไร
ดูข้อมูลเพิ่มเติมได้ที่เกี่ยวกับการจัดการหน่วยความจำ
สถานะของชุดข้อความ
เมื่อไปยังส่วนต่างๆ ขององค์ประกอบทั่วไปของรายงาน Systrace คุณจะดู ระยะเวลาที่เธรดหนึ่งๆ ใช้ในสถานะเธรดที่เป็นไปได้แต่ละสถานะได้โดยเลือก เธรดภายในรายงาน ดังที่แสดงในรูปที่ 7
ดังที่รูปที่ 7 แสดงให้เห็น คุณอาจพบว่าเธรดของเกมไม่ได้อยู่ในสถานะ "กำลังทำงาน" หรือ "เรียกใช้ได้" บ่อยเท่าที่ควร รายการต่อไปนี้ แสดงสาเหตุที่พบบ่อยหลายประการที่อาจทำให้เธรดหนึ่งๆ เปลี่ยนไปอยู่ในสถานะที่ผิดปกติเป็นระยะๆ
- หากเทรดเข้าสู่โหมดสลีปเป็นเวลานาน อาจเกิดจาก การแย่งชิงล็อกหรือรอให้ GPU ทำงาน
- หากชุดข้อความถูกบล็อกใน I/O อยู่ตลอดเวลา แสดงว่าคุณกำลังอ่านข้อมูลจากดิสก์มากเกินไปในคราวเดียว หรือเกมของคุณกำลังทำงานหนักเกินไป
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการปรับปรุงประสิทธิภาพของเกมได้ที่ แหล่งข้อมูลเพิ่มเติมต่อไปนี้
วิดีโอ
- งานนำเสนอ Systrace สำหรับเกม จาก Android Game Developer Summit 2018