توضح هذه الصفحة التحسينات المتنوعة لحساب الذاكرة التي تم تقديمها في Android 12.
إحصائيات DMA-BUF في sysfs
في Android 11 وAndroid 12، لا يمكن تثبيت 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 الفريد <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-BUFs يجب أن تقوم بتعيين حقل 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 heaps ، والذي يعد جزءًا من نواة Linux الأولية.
يتم تتبع إحصائيات ION العالمية التالية في Android 11:
- الحجم الإجمالي لـ DMA-BUFs المصدرة بواسطة كل كومة ION
- الحجم الإجمالي للذاكرة المخصصة مسبقًا غير المستخدمة والمخزنة بواسطة كل كومة ION
لا توجد واجهة متاحة لعرض إحصائيات الكومة لكل ION في Android 11.
يقارن الجدول التالي واجهات إحصائيات ION مع نظيراتها للأجهزة التي تستخدم إطار عمل DMA-BUF الكومة في Android 12.
Android 11 أو الأجهزة التي يتم تشغيلها بدعم ION في Android 12 | الأجهزة التي يتم تشغيلها باستخدام أكوام DMA-BUF في Android 12 | |
---|---|---|
إحصائيات أيون لكل كومة | لا أحد | تم تحليلها من إحصائيات DMA-BUF sysfs |
الحجم الإجمالي لوحدات DMA-BUF المصدرة | /sys/kernel/ion/total_heap_size_kb (لا يشمل حجم DMA-BUFs المصدرة من قبل المصدرين غير الأيونيين) | تم تحليلها من إحصائيات DMA-BUF sysfs (يتضمن حجم كافة وحدات 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، فقد جاءت ذاكرة GPU مما يلي:
- التخصيصات المباشرة التي يتم إجراؤها بواسطة برنامج تشغيل GPU باستخدام مخصص الصفحة الفعلي
- تم تعيين DMA-BUFs في مساحة عنوان GPU
ولذلك، تم طرح وحدات DMA-BUF التي تم تعيينها للذاكرة في مساحة عنوان وحدة معالجة الرسومات مرتين عند حساب ذاكرة الوصول العشوائي المفقودة. يطبق Android 12 حلاً لحساب حجم DMA-BUFs المعينة في مساحة عنوان وحدة معالجة الرسومات، مما يعني أنه يتم حسابها مرة واحدة فقط في حساب ذاكرة الوصول العشوائي المفقودة.
وتفاصيل الحل كالتالي:
- يجب أن تقوم واجهة Memtrack HAL API
getMemory()
عند استدعائها باستخدام PID 0 بالإبلاغ عن إجمالي الذاكرة العامة لوحدة معالجة الرسومات، لـ MemtrackType::GL وMemtrackRecord::FLAG_SMAPS_UNACCOUNTED. - يجب ألا يفشل getMemory() عند استدعائه باستخدام
PID
0
لـMemtrackType
بخلافGL
. يجب بدلاً من ذلك إرجاع 0. - تمت إضافة حل نقطة تتبع ذاكرة GPU/eBPF في حسابات Android 12 لإجمالي ذاكرة GPU. يؤدي طرح إجمالي الذاكرة الخاصة لوحدة معالجة الرسومات من إجمالي ذاكرة وحدة معالجة الرسومات إلى توفير حجم DMA-BUFs المعينة في مساحة عنوان وحدة معالجة الرسومات. يمكن بعد ذلك استخدام القيمة لتحسين دقة حسابات ذاكرة الوصول العشوائي المفقودة من خلال حساب استخدام ذاكرة وحدة معالجة الرسومات بشكل صحيح.
- يتم تضمين ذاكرة GPU الخاصة في
totalPss
في معظم تطبيقات Memtrack HAL وبالتالي يجب إلغاء تكرارها قبل إزالتها منlostRAM
.
الحل المطبق مفصل في القسم التالي.
إزالة تباين Memtrack من ذاكرة الوصول العشوائي المفقودة
نظرًا لأن تطبيقات Memtrack HAL يمكن أن تختلف عبر الشركاء، فإن ذاكرة GPU المضمنة في 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
واستبدالها بذاكرة GPU الخاصة ( 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;
تحديث حساب ذاكرة الوصول العشوائي المفقودة
يتم تضمين كل من إجمالي ذاكرة GPU الخاصة وإجمالي ذاكرة المخزن المؤقت DMA المصدرة في kernelUsed + totalPss
والتي تتم إزالتها من lostRAM
. يؤدي هذا إلى التخلص من العد المزدوج وتباين Memtrack من حساب ذاكرة الوصول العشوائي المفقودة.
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();
تصديق
تفرض اختبارات VTS القاعدة التي تنص على أن الأجهزة التي تعمل بنظام التشغيل Android 12 بإصدار Linux kernel 5.4 أو أعلى تدعم واجهة برمجة تطبيقات getGpuDeviceInfo() .
يجب أن تقوم واجهة Memtrack HAL API getGpuDeviceInfo()
الجديدة بإرجاع معلومات حول جهاز GPU قيد الاستخدام.
يوفر هذا حسابًا أفضل للذاكرة ورؤية أفضل لمخزن DMA واستخدام ذاكرة GPU. قم بتطبيق memtrack AIDL HAL لتحسين ذاكرة الوصول العشوائي المفقودة وحساب الذاكرة. هذه الميزة لا تعتمد على خدمات جوجل.
تطبيق
تعتمد هذه الميزة على AIDL Memtrack HAL ، ويتم تضمين توجيهات تنفيذها في Android 12 في التعليمات البرمجية كتعليقات.
تم التخطيط لتحويل جميع HIDL HALs إلى 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()
API لإرجاع إجمالي الذاكرة العامة لوحدة معالجة الرسومات بشكل صحيح عند استدعائها باستخدام PID 0 لـ MemtrackType::GL وMemtrackRecord:: FLAG_SMAPS_UNACCOUNTED.