توضّح هذه الصفحة التحسينات المختلفة التي تم إدخالها في نظام التشغيل Android 12 في ما يتعلّق بحساب الذاكرة.
إحصاءات DMA-BUF في sysfs
في الإصدارَين 11 و12 من نظام التشغيل Android، لا يمكن
تثبيت debugfs
في إصدارات المستخدم. لذلك، تمت إضافة إحصاءات DMA-BUF إلى sysfs
في دليل
/sys/kernel/dmabuf/buffers
في Android 12.
المسار | الوصف |
---|---|
/sys/kernel/dmabuf/buffers
|
يحتوي الدليل /sys/kernel/dmabuf/buffers على لقطة شاشة لحالة
كل ذاكرة DMA-BUF الداخلية.
يحتوي /sys/kernel/dmabuf/buffers/<inode_number> على إحصاءات
عن DMA-BUF التي تحمل رقم ملف البيانات التعريفي الفريد <inode_number> .
|
/sys/kernel/dmabuf/buffers/<inode_number>/exporter_name
|
يحتوي هذا الملف للقراءة فقط على اسم أداة تصدير DMA-BUF. |
/sys/kernel/dmabuf/buffers/<inode_number>/size
|
يحدِّد هذا الملف للقراءة فقط حجم DMA-BUF بالبايت. |
تُحلِّل libdmabufinfo
واجهة برمجة التطبيقات إحصاءات DMA-BUF sysfs
لعرض إحصاءات لكلّ مُصدِّر وذاكرة تخزين مؤقت.
يُرجى العلم أنّ برامج تشغيل kernel التي تُصدِّر وحدات DMA-BUF يجب أن تضبط الحقل exp_name
في struct dma_buf_export_info
بشكلٍ صحيح على اسم المصدِّر قبل
استدعاء واجهة برمجة التطبيقات dma_buf_export()
لإنشاء وحدة DMA-BUF.
هذا مطلوب لتطبيق libdmabufinfo
وأداة dmabuf_dump
من أجل الحصول على إحصاءات لكل مصدر، والتي يتم عرضها بعد ذلك في bugreport.
تم تعديل أداة dmabuf_dump
لعرض هذه المعلومات باستخدام وسيطة جديدة، وهي -b
.
إحصاءات لإطار عمل "كومات DMA-BUF"
يتم إيقاف ION في GKI 2.0 نهائيًا لصالح إطار عمل كومدات DMA-BUF، الذي يُعدّ جزءًا من نواة Linux الأساسية.
يتم تتبُّع الإحصاءات العالمية التالية حول ION في Android 11:
- إجمالي حجم وحدات DMA-BUF التي تم تصديرها بواسطة كل كومّة ION
- إجمالي حجم الذاكرة غير المستخدَمة والمخصّصة مسبقًا والتي تخزّنها كل حزمة ION
لا تتوفّر واجهة لعرض إحصاءات كل ذاكرة ION في Android 11.
يقارن الجدول التالي بين واجهات إحصاءات ION و الواجهات المشابهة لها للأجهزة التي تستخدم إطار عمل كومّة DMA-BUF في Android 12.
Android 11 أو الأجهزة التي تعمل بنظام التشغيل Android 12 مع إتاحة ION | الأجهزة التي يتم تشغيلها باستخدام مجموعات DMA-BUF في Android 12 | |
---|---|---|
إحصاءات ION لكل كومّة | ما مِن قيود مفروضة | تم تقسيمها من إحصاءات sysfs الخاصة بـ DMA-BUF |
إجمالي حجم وحدات DMA-BUF التي تم تصديرها | /sys/kernel/ion/total_heap_size_kb
(لا يشمل ذلك حجم وحدات DMA-BUF التي يتم تصديرها من قِبل أدوات تصدير غير ION) |
تم تقسيمها من إحصاءات sysfs الخاصة بـ DMA-BUF
(يتضمّن حجم جميع وحدات DMA-BUF التي تم تصديرها). |
إجمالي الذاكرة المجمّعة حسب الحِزم | /sys/kernel/ion/total_pool_size_kb |
/sys/kernel/dma_heap/total_pool_size_kb |
تحسين دقة احتساب ذاكرة الوصول العشوائي المفقودة
في السابق، كان يتم احتساب ذاكرة الوصول العشوائي المفقودة على النحو التالي:
القيمة النهائية الطويلة lostRAM
= memInfo.getTotalSizeKb(
) - (totalPss
- totalSwapPss
)
- memInfo.getFreeSizeKb()
- memInfo.getCachedSizeKb()
- kernelUsed
- memInfo.getZramTotalSizeKb()
يتضمّن المكوّن totalPss
استخدام ذاكرة وحدة معالجة الرسومات (يتم إرجاعه من واجهة getMemory()
في Memtrack HAL). يتضمّن مكوّن kernelUsed
إجمالي استخدام ذاكرة DMA-BUF.
ومع ذلك، بالنسبة إلى أجهزة Android، تأتي ذاكرة وحدة معالجة الرسومات من المصادر التالية:
- عمليات التوزيع المباشرة التي يجريها برنامج تشغيل وحدة معالجة الرسومات باستخدام أداة توزيع الصفحات المادية
- وحدات DMA-BUF التي تم ربطها بمساحة عناوين وحدة معالجة الرسومات
لذلك، تم طرح وحدات DMA-BUF التي تم ربطها بالذاكرة في مساحة عناوين وحدة معالجة الرسومات مرتين عند احتساب ذاكرة الوصول العشوائي المفقودة. ينفِّذ نظام التشغيل Android 12 حلًا لاحتساب حجم وحدات DMA-BUF التي تم ربطها بمساحة عناوين GPU، ما يعني أنّه يتم احتسابها مرة واحدة فقط في عملية احتساب ذاكرة الوصول العشوائي (RAM) المفقودة.
في ما يلي تفاصيل الحلّ:
- عند استدعاء واجهة برمجة التطبيقات Memtrack HAL API
getMemory()
باستخدام PID 0، يجب أن تُبلغ عن إجمالي الذاكرة الخاصة بوحدة معالجة الرسومات على مستوى النظام، وذلك لأجل MemtrackType::GL وMemtrackRecord::FLAG_SMAPS_UNACCOUNTED. - يجب ألا تتعذّر طريقة getMemory() عند استدعائها باستخدام
PID
0
لقيمةMemtrackType
غيرGL
. يجب أن يعرض بدلاً من ذلك القيمة 0. - يُحتسَب إجمالي ذاكرة وحدة معالجة الرسومات في حلّ نقطة تتبُّع ذاكرة وحدة معالجة الرسومات/eBPF الذي تمت إضافته في Android 12. يؤدي طرح إجمالي ذاكرة وحدة معالجة الرسومات الخاصة من إجمالي ذاكرة وحدة معالجة الرسومات إلى تحديد حجم وحدات DMA-BUF التي تم ربطها بمساحة عناوين وحدة معالجة الرسومات. ويمكن بعد ذلك استخدام القيمة لتحسين دقة عمليات احتساب ذاكرة الوصول العشوائي المفقودة من خلال احتساب استخدام ذاكرة وحدة معالجة الرسومات بشكل صحيح.
- يتم تضمين ذاكرة وحدة معالجة الرسومات الخاصة في
totalPss
في معظم عمليات تنفيذ Memtrack HAL ، وبالتالي يجب إزالة تكرارها قبل إزالتها منlostRAM
.
يمكنك الاطّلاع على تفاصيل الحلّ الذي تم تنفيذه في القسم التالي.
إزالة التباين في أداة Memtrack من ذاكرة الوصول العشوائي المفقودة
بما أنّ عمليات تنفيذ HAL في Memtrack قد تختلف من شريك لآخر، فإنّ ذاكرة وحدة معالجة الرسومات
المضمّنة في totalPSS
من HAL لا تكون متسقة دائمًا. لإزالة
التفاوت من lostRAM
، تتم إزالة الذاكرة المُدرَجة في MemtrackType::GRAPHICS
وMemtrackType::GL
من totalPss
أثناء احتساب lostRAM
.
تتم إزالة MemtrackType::GRAPHICS
من totalPss
واستبدالها
بذاكرة totalExportedDmabuf
في عملية احتساب lostRAM
في
ActivityManagerService.java
كما هو موضّح أدناه:
final long totalExportedDmabuf = Debug.getDmabufTotalExportedKb();
. . .
final long dmabufUnmapped = totalExportedDmabuf - dmabufMapped;
. . .
// Account unmapped dmabufs as part of the kernel memory allocations
kernelUsed += dmabufUnmapped;
// Replace Memtrack HAL reported Graphics category with mapped dmabufs
totalPss -= totalMemtrackGraphics;
totalPss += dmabufMapped;
تتم إزالة ذاكرة MemtrackType::GL
من totalPss
واستبدالها بملف
ذاكرة وحدة معالجة الرسومات الخاصة (gpuPrivateUsage
) في عملية احتساب lostRAM
فيملف
ActivityManagerService.java
كما هو موضّح أدناه:
final long gpuUsage = Debug.getGpuTotalUsageKb();
. . .
final long gpuPrivateUsage = Debug.getGpuPrivateMemoryKb();
. . .
// Replace the Memtrack HAL-reported GL category with private GPU allocations.
// Count it as part of the kernel memory allocations.
totalPss -= totalMemtrackGl;
kernelUsed += gpuPrivateUsage;
تم تعديل عملية احتساب ذاكرة الوصول العشوائي المفقودة.
إنّ إجمالي ذاكرة وحدة معالجة الرسومات الخاصة وإجمالي ذاكرة وحدة التخزين المؤقت لوحدة التحكّم المباشر بالذاكرة (DMA) التي تم تصديرها كلاهما
مضمّن في kernelUsed + totalPss
الذي تمت إزالته من lostRAM
. ويؤدي ذلك
إلى إزالة كل من العد المزدوج وتقلبات أداة Memtrack من عملية احتساب ذاكرة الوصول العشوائي
المفقودة.
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();
التحقُّق
تفرض اختبارات سلامة النقل (VTS) قاعدة أنّ الأجهزة التي تعمل بالإصدار 12 من Android التي تستخدم الإصدار 5.4 من نواة Linux أو إصدارًا أحدث تكون متوافقة مع واجهة برمجة التطبيقات getGpuDeviceInfo().
يجب أن تعرِض واجهة برمجة التطبيقات الجديدة Memtrack HAL API getGpuDeviceInfo()
معلومات عن وحدة معالجة الرسومات المستخدَمة.
ويؤدي ذلك إلى توفير إمكانية أفضل لحساب الذاكرة والاطّلاع على استخدام ذاكرة وحدة معالجة الرسومات ومقدّم الذاكرة DMA. تنفيذ memtrack AIDL HAL لتحسين احتساب ذاكرة الوصول العشوائي المفقودة والذاكرة لا تعتمد هذه الميزة على خدمات Google.
التنفيذ
تعتمد هذه الميزة على AIDL Memtrack HAL، وتتم تضمين اتجاهات تنفيذها في Android 12 في الرمز البرمجي كتعليقات.
من المخطّط تحويل جميع واجهات HIDL HAL إلى واجهات AIDL في الإصدارات المستقبلية.
تمت إضافة واجهات برمجة التطبيقات التالية إلى core/java/android/os/Debug.java
:
/**
* Return total memory size in kilobytes for exported DMA-BUFs or -1 if
* the DMA-BUF sysfs stats at /sys/kernel/dmabuf/buffers could not be read.
*
* @hide
*/
public static native long getDmabufTotalExportedKb();
/**
* Return memory size in kilobytes allocated for DMA-BUF heap pools or -1 if
* /sys/kernel/dma_heap/total_pools_kb could not be read.
*
* @hide
*/
public static native long getDmabufHeapPoolsSizeKb();
للتأكّد من أنّ نسختك تعمل على النحو المطلوب، يمكنك دمج نقاط التتبّع في برامج تشغيل وحدة معالجة الرسومات،
وتنفيذ واجهة برمجة التطبيقات AIDL Memtrack HAL getMemory()
لعرض
الإجمالي العام للذاكرة الخاصة لوحدة معالجة الرسومات عند طلبها باستخدام PID 0 لـ MemtrackType::GL
وMemtrackRecord::FLAG_SMAPS_UNACCOUNTED.