این صفحه بهبودهای مختلف حسابداری حافظه معرفی شده در اندروید 12 را شرح می دهد.
آمار DMA-BUF در sysfs
در اندروید 11 و اندروید 12، debugfs
نمیتوان در ساختهای کاربری نصب کرد. بنابراین آمار DMA-BUF به sysfs
در فهرست /sys/kernel/dmabuf/buffers
در اندروید 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
API آمار DMA-BUF sysfs
را تجزیه میکند تا آمار هر صادرکننده و هر بافر را نشان دهد.
لطفاً توجه داشته باشید که درایورهای هسته که DMA-BUF ها را صادر می کنند، باید قبل از فراخوانی API dma_buf_export()
برای ایجاد یک DMA-BUF، فیلد exp_name
struct dma_buf_export_info
را روی نام صادرکننده تنظیم کنند. این برای libdmabufinfo
و ابزار dmabuf_dump
برای استخراج آمار هر صادرکننده مورد نیاز است که سپس در گزارش اشکال نمایش داده میشود.
ابزار dmabuf_dump برای خروجی این اطلاعات با آرگومان جدید، -b
اصلاح شده است.
آمار برای چارچوب پشته های DMA-BUF
ION در GKI 2.0 به نفع چارچوب پشتههای DMA-BUF ، که بخشی از هسته بالادستی لینوکس است، منسوخ شده است.
آمار جهانی ION زیر در اندروید 11 ردیابی می شود:
- اندازه کل DMA-BUFهای صادر شده توسط هر پشته ION
- اندازه کل حافظه از پیش تخصیص داده نشده ذخیره شده توسط هر پشته ION
هیچ رابطی برای نمایش آمار هیپ هر یون در اندروید 11 در دسترس نیست.
جدول زیر رابط های آماری ION را با همتایان خود برای دستگاه هایی که از چارچوب هیپ DMA-BUF در اندروید 12 استفاده می کنند، مقایسه می کند.
Android 11 یا دستگاه هایی که با پشتیبانی ION در اندروید 12 راه اندازی می شوند | دستگاههایی که با پشتههای DMA-BUF در Android 12 راهاندازی میشوند | |
---|---|---|
آمار یون هر هیپ | هیچ کدام | تجزیه از آمار DMA-BUF sysfs |
اندازه کل DMA-BUFهای صادر شده | /sys/kernel/ion/total_heap_size_kb (اندازه DMA-BUF های صادر شده توسط صادرکنندگان غیریون را شامل نمی شود) | تجزیه از آمار DMA-BUF sysfs (شامل اندازه تمام DMA-BUFهای صادر شده است). |
کل حافظه جمع آوری شده توسط پشته ها | /sys/kernel/ion/total_pool_size_kb | /sys/kernel/dma_heap/total_pool_size_kb |
دقت محاسبه RAM از دست رفته را بهبود بخشید
قبلاً محاسبه RAM از دست رفته به صورت زیر انجام می شد:
آخرین Long lostRAM
= memInfo.getTotalSizeKb(
) - ( totalPss
- totalSwapPss
)
- memInfo.getFreeSizeKb()
- memInfo.getCachedSizeKb()
- kernelUsed
- memInfo.getZramTotalSizeKb()
;
جزء totalPss
شامل استفاده از حافظه GPU بود (که توسط رابط getMemory() Memtrack HAL برگردانده شد. مؤلفه kernelUsed
شامل کل مصرف حافظه DMA-BUF بود. با این حال، برای دستگاه های اندرویدی، حافظه GPU از موارد زیر است:
- تخصیص مستقیم توسط درایور GPU با استفاده از تخصیص دهنده صفحه فیزیکی
- DMA-BUF ها در فضای آدرس GPU نگاشت شده اند
بنابراین، DMA-BUFهایی که با حافظه در فضای آدرس GPU نگاشت شده بودند، با محاسبه RAM از دست رفته دو بار کم شدند. اندروید 12 راه حلی را برای محاسبه اندازه DMA-BUF های نگاشت شده در فضای آدرس GPU پیاده سازی می کند، به این معنی که تنها یک بار در محاسبه رم گم شده به حساب می آید.
جزئیات راه حل به شرح زیر است:
- Memtrack HAL API
getMemory()
هنگامی که با PID 0 فراخوانی می شود باید کل حافظه GPU خصوصی را برای MemtrackType::GL و MemtrackRecord::FLAG_SMAPS_UNACCOUNTED گزارش کند. - getMemory () هنگامی که با
PID
0
برایMemtrackType
غیر ازGL
فراخوانی می شود، نباید شکست بخورد. در عوض باید 0 برگرداند. - راه حل ردیابی/eBPF حافظه GPU اضافه شده در Android 12 کل حافظه GPU را به خود اختصاص می دهد. با کم کردن کل حافظه خصوصی GPU از کل حافظه GPU، اندازه DMA-BUF های نگاشت شده در فضای آدرس GPU فراهم می شود. سپس میتوان از این مقدار برای بهبود دقت محاسبات رم از دست رفته با محاسبه صحیح مصرف حافظه GPU استفاده کرد.
- حافظه GPU خصوصی در
totalPss
در اکثر پیاده سازی های Memtrack HAL گنجانده شده است و بنابراین باید قبل از حذف آن ازlostRAM
حذف شود.
راه حل اجرا شده در بخش بعدی به تفصیل توضیح داده شده است.
تغییرپذیری Memtrack را از RAM از دست رفته حذف کنید
از آنجایی که پیاده سازی Memtrack HAL می تواند در شرکای مختلف متفاوت باشد، حافظه GPU موجود در totalPSS
از HAL همیشه سازگار نیست. برای حذف تغییرپذیری از lostRAM
، حافظه در نظر گرفته شده در MemtrackType::GRAPHICS
و MemtrackType::GL
در طول محاسبه lostRAM
از totalPss
حذف میشود.
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;
محاسبه RAM از دست رفته به روز شد
هم کل حافظه GPU خصوصی و هم کل حافظه بافر DMA صادر شده در kernelUsed + totalPss
موجود است که از lostRAM
حذف شده است. این امر هم دوبار شمارش و هم تغییرپذیری Memtrack را از محاسبه RAM از دست رفته حذف می کند.
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();
اعتبار سنجی
تستهای VTS این قانون را اجرا میکنند که دستگاههایی که در اندروید 12 با هسته لینوکس نسخه 5.4 یا بالاتر راهاندازی میشوند، از API ()getGpuDeviceInfo پشتیبانی میکنند.
یک Memtrack HAL API getGpuDeviceInfo()
جدید باید اطلاعات مربوط به دستگاه GPU در حال استفاده را برگرداند.
این حسابداری حافظه و دید بهتری را در بافر DMA و استفاده از حافظه GPU فراهم می کند. پیاده سازی memtrack AIDL HAL برای از دست دادن بهتر RAM و حسابداری حافظه. این ویژگی به خدمات Google وابسته نیست.
پیاده سازی
این ویژگی به AIDL Memtrack HAL بستگی دارد و دستورالعملهای پیادهسازی آن در اندروید 12 بهعنوان نظر در کد موجود است.
تمام HIDL HAL ها برنامه ریزی شده است که در نسخه های بعدی به AIDL تبدیل شوند.
API های زیر به 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();
برای اطمینان از اینکه نسخه شما طبق برنامه کار می کند، نقاط ردیابی را در درایورهای GPU خود ادغام کنید و API AIDL memtrack HAL getMemory()
را پیاده سازی کنید تا به درستی کل حافظه خصوصی GPU-GPU را هنگامی که با PID 0 برای MemtrackType::GL و MemtrackRecord فراخوانی می شود، بازگردانید: FLAG_SMAPS_UNACCOUNTED.
این صفحه بهبودهای مختلف حسابداری حافظه معرفی شده در اندروید 12 را شرح می دهد.
آمار DMA-BUF در sysfs
در اندروید 11 و اندروید 12، debugfs
نمیتوان در ساختهای کاربری نصب کرد. بنابراین آمار DMA-BUF به sysfs
در فهرست /sys/kernel/dmabuf/buffers
در اندروید 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
API آمار DMA-BUF sysfs
را تجزیه میکند تا آمار هر صادرکننده و هر بافر را نشان دهد.
لطفاً توجه داشته باشید که درایورهای هسته که DMA-BUF ها را صادر می کنند، باید قبل از فراخوانی API dma_buf_export()
برای ایجاد یک DMA-BUF، فیلد exp_name
struct dma_buf_export_info
را روی نام صادرکننده تنظیم کنند. این برای libdmabufinfo
و ابزار dmabuf_dump
برای استخراج آمار هر صادرکننده مورد نیاز است که سپس در گزارش اشکال نمایش داده میشود.
ابزار dmabuf_dump برای خروجی این اطلاعات با آرگومان جدید، -b
اصلاح شده است.
آمار برای چارچوب پشته های DMA-BUF
ION در GKI 2.0 به نفع چارچوب پشتههای DMA-BUF ، که بخشی از هسته بالادستی لینوکس است، منسوخ شده است.
آمار جهانی ION زیر در اندروید 11 ردیابی می شود:
- اندازه کل DMA-BUFهای صادر شده توسط هر پشته ION
- اندازه کل حافظه از پیش تخصیص داده نشده ذخیره شده توسط هر پشته ION
هیچ رابطی برای نمایش آمار هیپ هر یون در اندروید 11 در دسترس نیست.
جدول زیر رابط های آماری ION را با همتایان خود برای دستگاه هایی که از چارچوب هیپ DMA-BUF در اندروید 12 استفاده می کنند، مقایسه می کند.
Android 11 یا دستگاه هایی که با پشتیبانی ION در اندروید 12 راه اندازی می شوند | دستگاههایی که با پشتههای DMA-BUF در Android 12 راهاندازی میشوند | |
---|---|---|
آمار یون هر هیپ | هیچ کدام | تجزیه از آمار DMA-BUF sysfs |
اندازه کل DMA-BUFهای صادر شده | /sys/kernel/ion/total_heap_size_kb (اندازه DMA-BUF های صادر شده توسط صادرکنندگان غیریون را شامل نمی شود) | تجزیه از آمار DMA-BUF sysfs (شامل اندازه تمام DMA-BUFهای صادر شده است). |
کل حافظه جمع آوری شده توسط پشته ها | /sys/kernel/ion/total_pool_size_kb | /sys/kernel/dma_heap/total_pool_size_kb |
دقت محاسبه RAM از دست رفته را بهبود بخشید
قبلاً محاسبه RAM از دست رفته به صورت زیر انجام می شد:
آخرین Long lostRAM
= memInfo.getTotalSizeKb(
) - ( totalPss
- totalSwapPss
)
- memInfo.getFreeSizeKb()
- memInfo.getCachedSizeKb()
- kernelUsed
- memInfo.getZramTotalSizeKb()
;
جزء totalPss
شامل استفاده از حافظه GPU بود (که توسط رابط getMemory() Memtrack HAL برگردانده شد. مؤلفه kernelUsed
شامل کل مصرف حافظه DMA-BUF بود. با این حال، برای دستگاه های اندرویدی، حافظه GPU از موارد زیر است:
- تخصیص مستقیم توسط درایور GPU با استفاده از تخصیص دهنده صفحه فیزیکی
- DMA-BUF ها در فضای آدرس GPU نگاشت شده اند
بنابراین، DMA-BUFهایی که با حافظه در فضای آدرس GPU نگاشت شده بودند، با محاسبه RAM از دست رفته دو بار کم شدند. Android 12 راه حلی را برای محاسبه اندازه-خرید DMA که در فضای آدرس GPU نقشه برداری شده است ، پیاده سازی می کند ، به این معنی که فقط در محاسبه RAM از دست رفته فقط یک بار به حساب می آید.
جزئیات راه حل به شرح زیر است:
- memtrack hal api
getMemory()
هنگامی که با PID 0 فراخوانی می شود ، باید حافظه جهانی GPU-Private را برای memtracktype :: GL و MemtrackRecord :: flag_smaps_unaccounted گزارش دهند. - getMemory () هنگامی که با
PID
0
برایMemtrackType
غیر ازGL
فراخوانی می شود، نباید شکست بخورد. در عوض باید 0 برگرداند. - راه حل ردیابی/eBPF حافظه GPU اضافه شده در Android 12 کل حافظه GPU را به خود اختصاص می دهد. با کم کردن کل حافظه خصوصی GPU از کل حافظه GPU، اندازه DMA-BUF های نگاشت شده در فضای آدرس GPU فراهم می شود. سپس میتوان از این مقدار برای بهبود دقت محاسبات رم از دست رفته با محاسبه صحیح مصرف حافظه GPU استفاده کرد.
- حافظه GPU خصوصی در
totalPss
در اکثر پیاده سازی های Memtrack HAL گنجانده شده است و بنابراین باید قبل از حذف آن ازlostRAM
حذف شود.
راه حل اجرا شده در بخش بعدی به تفصیل توضیح داده شده است.
تغییرپذیری Memtrack را از RAM از دست رفته حذف کنید
از آنجایی که پیاده سازی Memtrack HAL می تواند در شرکای مختلف متفاوت باشد، حافظه GPU موجود در totalPSS
از HAL همیشه سازگار نیست. برای حذف تغییرپذیری از lostRAM
، حافظه در نظر گرفته شده در MemtrackType::GRAPHICS
و MemtrackType::GL
در طول محاسبه lostRAM
از totalPss
حذف میشود.
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;
محاسبه RAM از دست رفته به روز شد
هر دو حافظه GPU خصوصی و کل حافظه بافر DMA صادر شده در kernelUsed + totalPss
که از lostRAM
حذف می شوند موجود است. این امر هم دوبار شمارش و هم تغییرپذیری Memtrack را از محاسبه RAM از دست رفته حذف می کند.
final long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
- memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
- kernelUsed - memInfo.getZramTotalSizeKb();
اعتبار سنجی
تستهای VTS این قانون را اجرا میکنند که دستگاههایی که در اندروید 12 با هسته لینوکس نسخه 5.4 یا بالاتر راهاندازی میشوند، از API ()getGpuDeviceInfo پشتیبانی میکنند.
یک Memtrack HAL API getGpuDeviceInfo()
جدید باید اطلاعات مربوط به دستگاه GPU در حال استفاده را برگرداند.
این حسابداری حافظه و دید بهتری را در بافر DMA و استفاده از حافظه GPU فراهم می کند. پیاده سازی memtrack AIDL HAL برای از دست دادن بهتر RAM و حسابداری حافظه. این ویژگی به خدمات Google وابسته نیست.
پیاده سازی
این ویژگی به AIDL Memtrack HAL بستگی دارد و دستورالعملهای پیادهسازی آن در اندروید 12 بهعنوان نظر در کد موجود است.
تمام HIDL HAL ها برنامه ریزی شده است که در نسخه های بعدی به AIDL تبدیل شوند.
API های زیر به 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();
برای اطمینان از اینکه نسخه شما طبق برنامه کار می کند، نقاط ردیابی را در درایورهای GPU خود ادغام کنید و API AIDL memtrack HAL getMemory()
را پیاده سازی کنید تا به درستی کل حافظه خصوصی GPU-GPU را هنگامی که با PID 0 برای MemtrackType::GL و MemtrackRecord فراخوانی می شود، بازگردانید: FLAG_SMAPS_UNACCOUNTED.