CPU推动了所有软件的运行,因此通常是系统性能分析的首要目标。现代系统一般有多颗CPU,通过内核调度器共享给所有运行软件。当需求的CPU资源超过了系统力所能及的范围时,进程里的线程(或者任务)将会排队,等待轮候自己运行的机会。等待给应用程序的运行带来严重延时,使得性能下降。
我们可以通过仔细检查CPU的用量,寻找性能改进的空间,还可以去除一些不需要的负载。
为了提高内存I/O性能,处理器提供了多种硬件缓存。缓存大小的关系如下图,越小则速度越快,并且越靠近CPU。
应用程序在多CPU上扩展的技术分为多进程和多线程,在Linux上可以使用多进程和多线程模型,而这两种技术都是由任务实现。多进程和多线程之间的差异如下图所示:
正如表里多线程的那些优点所示,多线程一般被认为由于多进程,尽管对开发者而已更难实现。
不管使用何种技术,重要的是要创建足够的进程或者线程,以占据预期数量的CPU --- 如果要最大化性能,即所有的CPU。有些应用程序可能在更少的CPU上跑的更快,这是因为线程同步和内存本地性下降反而吞噬了更多的CPU资源。
编译器优化:应用程序在CPU上的运行时间通过编译器选项(包括字长设置)来大幅改进。编译器也频繁地更新以利用最新的CPU指令级以及其他优化。有时应用程序的性能可以通过新的编译器显著地提高。
CPU调度器:进程在处理器上和CPU间的调度是由调度器完成的,这是操作系统内核的关键组件。调度器基本的意图是将CPU时间划分给活跃的进程和线程,而且维护一套优先级的机制,这样更重要的工作可以更快地执行。当需要运行的线程多于可用的CPU数目时,低优先级的线程会等待直到轮到自己。多数的内核线程运行的优先级要比用户级别的优先级高。
调度器可以动态地修改进程的优先级以提升特定工作负载的性能。
内核调度器的主要功能如下图:
功能:
分时:可运行线程之间的多任务,优先执行最高优先级任务。
抢占:一旦有高优先级线程变成可运行状态,调度器能够抢占当前运行的线程,这 样较高优先级的线程可以马上开始运行。
负载均衡:把可运行的线程移到空闲或者较不繁忙的CPU队列中。
通过更换修改/更新CPU调度策略机制可以有效提升系统性能,比如当前CPU调度之EAS 策略。
CPU绑定:把进程和线程绑定在单个CPU或者一组CPU上,这样可以增加进程的CPU缓存温度,提高它的内存I/O性能。
CPU分析工具 |
|
工具 |
描述 |
uptime |
平均负载 |
vmstat |
包括系统范围的CPU平均负载 |
mpstat |
单个CPU统计信息 |
ps |
进程状态 |
pmap | 将进程的内存段和使用统计一起列出 |
top |
监控每个进程/线程CPU用量 |
pidstat |
每个进程/线程CPU用量分解 |
perf |
CPU性能计数器分析 |
systrace |
可记录短时间内的设备活动,并保存在压缩的文本文件中。该工具会生成一份报告,其中汇总了 Android 内核中的数据,例如 CPU 调度程序、磁盘活动和应用线程 |
perfetto |
是 Android 10 中引入的全新平台级跟踪工具 |
AS |
Android Studio 中分析应用的 CPU 使用率和线程活动 |
1). Uptime: 最后三个数字是1、5和15分钟内的平均负载。通过比较者三个数字,你可以判断负载在15分钟内是在上升、下降还是平稳。
2).Top:监控了运行得最多的进程,以一定时间间隔刷新屏幕。
3).mpstat
4).pidstat
5).AndroidStudio:
6).perfetto
https://raw.githubusercontent.com/google/perfetto/master/tools/record_android_trace
csdn下载地址:Androidperfettotools-Android文档类资源-CSDN文库
window/Linux环境:
python3 record_android_trace -o trace_file.perfetto-trace -t 10s -b 32mb sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory
调试终端adb shell:
adb shell perfetto -o /data/misc/perfetto-traces/trace_file.perfetto-trace -t 20s sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory
adb pull data/misc/perfetto-traces/trace_file.perfetto-trace
>>>>>
用https://ui.perfetto.dev/分析
结果:
注:perfetto文档:
https://perfetto.dev/docs/quickstart
内存硬件包括主存、总线、CPU缓存和MMU(内存管理单元)
主存:
目前常见的主存类型是动态随机存取内存(DRAM)。这是一种易失性的内存--它存储的内容在断电时会失去。由于每个比特仅由两个逻辑零件组成:一个电容和一个晶体管,DRAM能提供高容量的存储。其中的电容需要定期更新以保存电荷。
按照不同用途,企业服务器会配置不同容量的DRAM。典型为1GB~1TG甚至更大。
总线:
CPU缓存:
处理器通常会在芯片中包含硬件缓存以提高内存访问性能。这些缓存可能包括如下级别,速度递减和大小递增。
L1: 通常分为指令缓存和数据缓存。
L2: 同时缓存指令和数据。
L3: 更大一级的缓存。
一级缓存通常按虚拟内存地址空间寻址,二级及以上按物理内存地址寻址,具体取决于处理器,
MMU:
内存管理单元(MMU)负责虚拟到物理地址的转换。它按页做转换,而页内的偏移量则直接映射。
内存管理软件包括虚拟内存系统、地址转换、交换、换页和分配。与性能密切相关的内容包括这些部分:内存释放、空闲链表、页扫描、交换、进程地址空间和内存分配器。
内存释放:系统中可用内存过低时,内核有多种方法释放内存,并添加到页空闲链表中。
说明:
页缓存:文件系统缓存。一个称作交换倾向的可调用参数能调节系统倾向性,决定是通过交换页还是交换来释放内存。
交换:页面交换守护进程(kwwapd)执行的换页。它找出最近不使用的页并加入空闲链表,其中包括应用程序内存。页面换出涉及写入文件系统或者一个交换设备,仅在配置了交换文件或设备时才可用。
OOM终结者:内存耗尽,OOM终结者搜索并杀死可牺牲的进程以是否内存,采用
Select_band_process()搜索而后用oom_kill_process()杀死进程。
内存分析工具 |
|
工具 |
描述 |
vmstat |
虚拟内存统计信息命令 |
ps |
进程状态 |
top |
监控每个进程/线程CPU用量以及内存使用情况 |
perfetto |
是 Android 10 中引入的全新平台级跟踪工具 |
Dump memory |
Cat /proc/memoryinfo 或者 输入procrank |
AS |
Android Studio 中分析应用的 内存使用率 |
1). Vmstat : 虚拟内存统计信息命令,它提供包括当前内存和换页在内的系统内存健康程度 总览。每秒运行vmstat检查free列的可用内存。
指令:vmstat -n 1 //每秒查看
2). Ps:进程状态命令ps可以列出包括内存使用统计信息在内的所有进程细节。
3). Top : 监控排名
Top -d 1 //每秒更新一次数据
4). Dump meminfo:
命令:cat /proc/meminfo
命令:procrank //dump 线程的内存使用情况
5).AndroidStudio:
内存分析工具 |
|
工具 |
描述 |
Iostat |
汇总了单个磁盘的统计信息,为负载特征归纳、使用率和饱和度提供了指标 |
Iotop |
包含磁盘I/O版本的Top |
systrace |
可记录短时间内的设备活动,并保存在压缩的文本文件中。该工具会生成一份报告,其中汇总了 Android 内核中的数据,例如 CPU 调度程序、磁盘活动和应用线程 |
1).iotop
指令:iotop -d 1 -m 10 //1S更新一次,最多显示10个线程数据
2).iostat
htop:
Download htop-2.2.0.tar.gz Free - Htop 2.2.0 install file (download3k.com)sourceforge.nethttps://sourceforge.net/projects/htop/
iftop:
iiftop: display bandwidth usage on an interface (ex-parrot.com)sysstat:
文件 · v12.5.5 · mirrors / sysstat / sysstat · GitCodeiotop:
guichaz.free.fr
atop:
Atoptool.nl
镜像下载路径:NDK 下载 | Android NDK | Android Developers
脚本如下://sysstat 案例
#!/bin/bash
###################################
#### build script for sysstat_v12.5.5
#### url:https://gitcode.net/mirrors/sysstat/sysstat/-/tree/v12.5.5
#### Date: 2021-12-28
#### Author: Tim
###################################
# ndk for linux https://developer.android.google.cn/ndk/downloads?hl=zh-cn
NDKROOT_PATH=/home/xxxx/workspace/tools/android-ndk-r23b
# current dir
CUR_PATH=$(pwd)
# Only choose one of these, depending on your build machine...
export TOOLCHAIN=$NDKROOT_PATH/toolchains/llvm/prebuilt/linux-x86_64
# Only choose one of these, depending on your device...
export TARGET=aarch64-linux-android
#export TARGET=armv7a-linux-androideabi
# Set this to your minSdkVersion.
export API=28
# Configure and build.
export AR=$TOOLCHAIN/bin/llvm-ar
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export AS=$CC
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
# make install output dir.
if [ ! -d $CUR_PATH/out ]; then
mkdir -p $CUR_PATH/out
fi
./configure --host $TARGET --cache-file=$CUR_PATH/cache_file_0 --prefix=$CUR_PATH/out --exec-prefix=$CUR_PATH/out
make
make install
编译:# sudo ./build.sh