تصف هذه الصفحة التحسينات المختلفة في حساب الذاكرة التي تم تقديمها في الإصدار 12 من نظام التشغيل Android.
إحصائيات 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
تحلّل واجهة برمجة التطبيقات إحصاءات sysfs
الخاص بمنطقة DMA-BUF لعرض إحصاءات خاصة بكل مصدِّر وحسب المخزن المؤقت.
يُرجى ملاحظة أنّ برامج تشغيل النواة التي تصدّر ملفات DMA-BUF يجب أن تضبط exp_name
.
في الحقل struct dma_buf_export_info
بشكل صحيح إلى اسم المُصدِّر قبل
لاستدعاء واجهة برمجة التطبيقات dma_buf_export()
لإنشاء DMA-BUF.
هذا الإجراء مطلوب في libdmabufinfo
وأداة dmabuf_dump
لاستنتاج الإحصاءات لكل مصدِّر:
في تقرير الأخطاء.
تم تعديل أداة 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 لكل كومّة | بدون تحديد نمط | تم تحليل البيانات من إحصاءات DMA-BUF sysfs. |
إجمالي حجم وحدات DMA-BUF التي تم تصديرها | /sys/kernel/ion/total_heap_size_kb
(لا يشمل حجم ملفات DMA-BUF التي تم تصديرها من خلال جهات تصدير غير تابعة لـ ION) |
تحليل البيانات من إحصاءات أنظمة 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 التي تم ربطها بالذاكرة في مساحة عناوين وحدة معالجة الرسومات مرتين عند احتساب ذاكرة الوصول العشوائي المفقودة. الإصدار 12 من نظام التشغيل Android تنفيذ حل لحساب حجم وحدات DMA-BUF التي تم تعيينها في وحدة معالجة الرسومات مساحة العنوان، ما يعني أنه تم احتسابها مرة واحدة فقط في عمود احتساب ذاكرة الوصول العشوائي (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;
تم تعديل عملية احتساب ذاكرة الوصول العشوائي (RAM) المفقودة.
إنّ كل من إجمالي ذاكرة وحدة معالجة الرسومات الخاصة وإجمالي ذاكرة المخزن المؤقت لمنطقة السوق المحددة التي تم تصديرها
تم تضمينها في 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 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.