A. android獲取系統cpu信息,內存,版本,電量等信息
1、CPU頻率,CPU信息:/proc/cpuinfo和/proc/stat
通過讀取文件/proc/cpuinfo系統CPU的類型等多種信息。
讀取/proc/stat 所有CPU活動的信息來計算CPU使用率
下面我們就來講講如何通過代碼來獲取CPU頻率:
復制代碼 代碼如下:
package com.orange.cpu;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
public class CpuManager {
// 獲取CPU最大頻率(單位KHZ)
// "/system/bin/cat" 命令行
// "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" 存儲最大頻率的文件的.路徑
public static String getMaxCpuFreq() {
String result = "";
ProcessBuilder cmd;
try {
String[] args = { "/system/bin/cat",
"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq" };
cmd = new ProcessBuilder(args);
Process process = cmd.start();
InputStream in = process.getInputStream();
byte[] re = new byte[24];
while (in.read(re) != -1) {
result = result + new String(re);
}
in.close();
} catch (IOException ex) {
ex.printStackTrace();
result = "N/A";
}
return result.trim();
}
// 獲取CPU最小頻率(單位KHZ)
public static String getMinCpuFreq() {
String result = "";
ProcessBuilder cmd;
try {
String[] args = { "/system/bin/cat",
"/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq" };
cmd = new ProcessBuilder(args);
Process process = cmd.start();
InputStream in = process.getInputStream();
byte[] re = new byte[24];
while (in.read(re) != -1) {
result = result + new String(re);
}
in.close();
} catch (IOException ex) {
ex.printStackTrace();
result = "N/A";
}
return result.trim();
}
// 實時獲取CPU當前頻率(單位KHZ)
public static String getCurCpuFreq() {
String result = "N/A";
try {
FileReader fr = new FileReader(
"/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq");
BufferedReader br = new BufferedReader(fr);
String text = br.readLine();
result = text.trim();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
// 獲取CPU名字
public static String getCpuName() {
try {
FileReader fr = new FileReader("/proc/cpuinfo");
BufferedReader br = new BufferedReader(fr);
String text = br.readLine();
String[] array = text.split(":s+", 2);
for (int i = 0; i < array.length; i++) {
}
return array[1];
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
2、內存:/proc/meminfo
復制代碼 代碼如下:
public void getTotalMemory() {
String str1 = "/proc/meminfo";
String str2="";
try {
FileReader fr = new FileReader(str1);
BufferedReader localBufferedReader = new BufferedReader(fr, 8192);
while ((str2 = localBufferedReader.readLine()) != null) {
Log.i(TAG, "---" + str2);
}
} catch (IOException e) {
}
}
3、Rom大小
復制代碼 代碼如下:
public long[] getRomMemroy() {
long[] romInfo = new long[2];
//Total rom memory
romInfo[0] = getTotalInternalMemorySize();
//Available rom memory
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long availableBlocks = stat.getAvailableBlocks();
romInfo[1] = blockSize * availableBlocks;
getVersion();
return romInfo;
}
public long getTotalInternalMemorySize() {
File path = Environment.getDataDirectory();
StatFs stat = new StatFs(path.getPath());
long blockSize = stat.getBlockSize();
long totalBlocks = stat.getBlockCount();
return totalBlocks * blockSize;
}
4、sdCard大小
復制代碼 代碼如下:
public long[] getSDCardMemory() {
long[] sdCardInfo=new long[2];
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
File sdcardDir = Environment.getExternalStorageDirectory();
StatFs sf = new StatFs(sdcardDir.getPath());
long bSize = sf.getBlockSize();
long bCount = sf.getBlockCount();
long availBlocks = sf.getAvailableBlocks();
sdCardInfo[0] = bSize * bCount;//總大小
sdCardInfo[1] = bSize * availBlocks;//可用大小
}
return sdCardInfo;
}
5、電池電量
復制代碼 代碼如下:
private BroadcastReceiver batteryReceiver=new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
int level = intent.getIntExtra("level", 0);
// level加%就是當前電量了
}
};
registerReceiver(batteryReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
6、系統的版本信息
復制代碼 代碼如下:
public String[] getVersion(){
String[] version={"null","null","null","null"};
String str1 = "/proc/version";
String str2;
String[] arrayOfString;
try {
FileReader localFileReader = new FileReader(str1);
BufferedReader localBufferedReader = new BufferedReader(
localFileReader, 8192);
str2 = localBufferedReader.readLine();
arrayOfString = str2.split("s+");
version[0]=arrayOfString[2];//KernelVersion
localBufferedReader.close();
} catch (IOException e) {
}
version[1] = Build.VERSION.RELEASE;// firmware version
version[2]=Build.MODEL;//model
version[3]=Build.DISPLAY;//system version
return version;
}
7、mac地址和開機時間
復制代碼 代碼如下:
public String[] getOtherInfo(){
String[] other={"null","null"};
WifiManager wifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
if(wifiInfo.getMacAddress()!=null){
other[0]=wifiInfo.getMacAddress();
} else {
other[0] = "Fail";
}
other[1] = getTimes();
return other;
}
private String getTimes() {
long ut = SystemClock.elapsedRealtime() / 1000;
if (ut == 0) {
ut = 1;
}
int m = (int) ((ut / 60) % 60);
int h = (int) ((ut / 3600));
return h + " " + mContext.getString(R.string.info_times_hour) + m + " "
+ mContext.getString(R.string.info_times_minute);
}
B. 安卓手機應用CPU佔用時間是如何計算的
cpu指標的查看方式有多種,最直接的就是android自帶的DDMS可視化工具,也可以在IDE(Android Studio)的Monitor中實時查看。另外就是通過linux系統/proc/stat和/proc/<pid>/stat文件進行佔用率的計算,也可以利用top命令或者mpsys cupinfo等命令實時查看當前cpu情況。我們接下來詳細看下每一種方法是如何查看和獲得cpu佔用率數據
C. Android性能優化第(八)篇---App啟動速度優化之耗時檢測處理
應用的啟動速度緩慢這是很多開發者都遇到的一個問題,比如啟動緩慢導致的黑屏,白屏問題,大部分的答案都是做一個透明的主題,或者是做一個Splash界面,但是這並沒有從根本上解決這個問題。那麼如何從根本上解決這個問題或者做到一定程度的緩解?
1、冷啟動:當啟動應用時,後台沒有該應用的進程,這時系統會首先會創建一個新的進程分配給該應用,這種啟動方式就是冷啟動。
2、熱啟動:當啟動應用時,後台已有該應用的進程,比如按下home鍵,這種在已有進程的情況下,這種啟動會從已有的進程中來啟動應用,這種啟動方式叫熱啟動。
3、溫啟動 :當啟動應用時,後台已有該應用的進程,但是啟動的入口Activity被幹掉了,比如按了back鍵,應用雖然退出了,但是該應用的進程是依然會保留在後台,這種啟動方式叫溫啟動。
adb shell am start -W [PackageName]/[PackageName.MainActivity]
執行成功後將返回三個測量到的時間:
這裡面涉及到三個時間,ThisTime、TotalTime 和 WaitTime。WaitTime 是 startActivityAndWait 這個方法的調用耗時,ThisTime 是指調用過程中最後一個 Activity 啟動時間到這個 Activity 的 startActivityAndWait 調用結束。TotalTime 是指調用過程中第一個 Activity 的啟動時間到最後一個 Activity 的 startActivityAndWait 結束。如果過程中只有一個 Activity ,則 TotalTime 等於 ThisTime。
總結:如果只關心某個應用自身啟動耗時,參考TotalTime;如果關心系統啟動應用耗時,參考WaitTime;如果關心應用有界面Activity啟動耗時,參考ThisTime。
從我們Application開始到首頁顯示出來,這個過程,我們應該注意一些什麼,將這個過程細分一下,會有下面的時間點需要注意。
Application的構造器方法——>attachBaseContext()——>onCreate()——>Activity的構造方法——>onCreate()——>配置主題中背景等屬性——>onStart()——>onResume()——>測量、布局、繪制顯示在界面上。
因為上面這些階段全部都是在主線程中執行的,任何不經意的操作都可能拖慢應用的啟動速度。所以我們不應在Application以及Activity的生命周期回調中做任何費時操作,具體指標大概是你在onCreate,onResume,onStart等回調中所花費的總時間最好不要超過400ms,否則用戶在桌面點擊你的應用圖標後,將感覺到明顯的卡頓。但是有些 不得以的任務 又必須在UI顯示之前執行。所以我們要將 任務 劃分優先順序。
對於首頁渲染完成後,開始載入,或者延遲載入,延遲載入的目的就是界面先顯示出來,然後載入,但是你覺得要延遲多久呢?在 Android 的高端機型上,應用的啟動是非常快的 , 這時候只需要 Delay 很短的時間就可以了, 但是在低端機型上,應用的啟動就沒有那麼快了,而且現在應用為了兼容舊的機型,往往需要 Delay 較長的時間,這樣帶來體驗上的差異是很明顯的。延遲載入有一種方式。
極力推薦用第二種,在窗口完成以後進行載入,這裡面的run方法是在onResume之後運行的。關於這種懶載入機制,參考 Android應用啟動優化:一種DelayLoad的實現和原理(上篇) ,給出了詳細的解釋。
通過上面我們知道一種懶載入機制,所以我們可以將Application中和首頁的onCreate中的有些耗時任務,放到首頁渲染完畢後載入。如何找出這些耗時任務,TraceView就派上用場了,TraceView的用法,移步我的前面的博客 Android性能優化第(六)篇---TraceView 分析圖怎麼看?
比如在首頁的onCreate中我們進行了用戶啟動上報,這個進行懶載入是不是分分鍾減少139毫秒呢?
在比如在Application裡面用到了GSON,將String轉化成json,我將這個移動到懶載入裡面,是不是又減少了100毫秒呢?
在比如,有些Application中做了支付SDK的初始化,用戶又不會一打開App就要支付,放在Application中載入幹嘛?
此處我們這里舉得例子是優化了139毫秒和100毫秒的,其實真正耗時的任務有的有1秒多,都被我優化完了,所以trace圖中看不到了,就舉個了這兩個例子,還有SharedPreferences也是耗時大戶,經過檢測保存一個boolean變數耗時120+毫秒以上。
利用TraceView可以清楚我們每一個方法的耗時時間,極大的幫助了我們做優化工作。
五、優化思路總結
1、UI渲染優化,去除重復繪制,減少UI重復繪制時間,打開設置中的GPU過度繪制開關,各界面過度繪制不應超過2.5x;也就是打開此調試開關後,界面整體呈現淺色,特別復雜的界面,紅色區域也不應該超過全屏幕的四分之一;
2、根據優先順序的劃分,KoMobileApplication的一些初始化工作能否將任務優先順序劃分成3,在首頁渲染完成後進行載入,比如:PaySDKManager。
3、主線程中的所有SharedPreference能否在非UI線程中進行,SharedPreferences的apply函數需要注意,因為Commit函數會阻塞IO,這個函數雖然執行很快,但是系統會有另外一個線程來負責寫操作,當apply頻率高的時候,該線程就會比較佔用CPU資源。類似的還有統計埋點等,在主線程埋點但非同步線程提交,頻率高的情況也會出現這樣的問題。
4、檢查BaseActivity,不恰當的操作會影響所有子Activity的啟動。
5、對於首次啟動的黑屏問題,對於「黑屏」是否可以設計一個.9圖片替換掉,間接減少用戶等待時間。
6、對於網路錯誤界面,友好提示界面,使用ViewStub的方式,減少UI一次性繪制的壓力。
7、任務優先順序為2,3的,通過下面這種方式進行懶載入的方式
8、Multidex的使用,也是拖慢啟動速度的元兇,必須要做優化。後面有空專門寫一篇Multidex。
相關鏈接:
Android應用啟動優化:一種DelayLoad的實現和原理(上篇)http://androidperformance.com/2015/11/18/Android-app-lunch-optimize-delay-load.html
Android性能優化之加快應用啟動速度http://www.open-open.com/lib/view/open1452821612355.html
手機淘寶性能優化全記錄http://www.open-open.com/lib/view/open1452488209370.html
Android客戶端性能優化(魅族資深工程師毫無保留奉獻)http://blog.tingyun.com/web/article/detail/155#rd
Please accept mybest wishes for your happiness and success !
D. android cpu佔用多少算高
應用在工作中佔用cpu高點都不要緊,只要不是長時間佔用就可以,即使峰值達到100%都不怕。
就怕持續佔用CPU。
比如說一個美圖軟體,有任務(比如拍照,圖像處理)的時候,需要佔用CPU進行處理,此種情況佔用CPU高點都沒關系,瞬間峰值達到100%都不怕,只要它不長時間佔用即可。但是在無任務的時候,CPU就應該降下來,如果不降下來,就是代碼有問題。
E. Android:安卓系統中,處理器的一個時間片大概有多長時間
CPU分配的最小時間片斷為2ms
F. 安卓CPU性能原地踏步的兩年
2020年的驍龍865是高通最近幾年最成功的旗艦SoC,同年的麒麟9000成為海思絕唱。隨後2021年的驍龍888永久改變了安卓手機的散熱配置,2022年的驍龍8 Gen 1更進一步,連用風扇主動散熱的 游戲 手機都在繼續升級散熱。
當年驍龍810機型並未大批量鋪貨,所以公眾其實還是第一次感受到移動SoC的熱情如火,這是安卓手機GPU性能飛漲的兩年,但也是安卓CPU原地踏步的兩年。
下面故事概括就是一條條邏輯鏈:
iPhone用戶和非手機圈用戶,可能並不了解為什麼安卓陣營哀嚎了兩年,我們按時間順序理一下,究竟發生什麼事。畢竟大家習慣了手機性能以每年20%-30%幅度增長的日子,但實際上安卓陣營已經出現性能體驗原地踏步的情況了。
故事從2020年底驍龍888發布說起。後者首發三星5nm工藝,也首發搭載arm首個真正的超大核架構Cortex-X1。驍龍888發布之前,微博大V數碼閑聊站稱驍龍888性能強,功耗低,大家對未來充滿了期待。
極客灣視頻
首發驍龍888的小米11在2021年元旦開賣,極客灣在1月6號的《驍龍888性能分析:翻車!》為驍龍888火熱的一年拉開了序幕。驍龍888是否翻車,成為了2021年機圈最熱門的話題之一。
2017年的驍龍835日常功耗在3W的量級,隨後的驍龍845、驍龍855、驍龍865功耗「穩步增長」,來到了5W到6W區間。而驍龍888的X1大核,單顆功耗就能跑到3.3W,CPU多核功耗從驍龍865的5.9W直接飆到7.8W。其GPU部分的功耗和能耗比曲線也不普通,以致於早期很多人都認為驍龍888的GPU只是在驍龍865的基礎上繼續超頻並導致功耗偏高。
因為驍龍888的功耗數據高得不正常,所以後來還出現了物理拆機,用「假電池排線」的物理方法強行測試功耗。雖然結果比軟體測試功耗低2W,但整機功耗依然達到了10W級別,瞬時功耗迫近11W。
功耗的上漲,導致在「交互化跑分軟體」《原神》中,驍龍888機型都能輕松突破45度,部分極端機型可以沖到近50度。3C數碼產品有48度的溫度線,以防止用戶被「低溫燙傷」,所以驍龍888機型幾乎都遭遇了屏幕強制降低亮度,系統鎖幀等現象( 游戲 手機除外)。
隨後的事情,可能很多用戶都有所聽聞。天氣轉暖,先是大批用戶反映驍龍888旗艦會有發熱卡頓的問題,甚至會觸發過熱警告。隨後一眾廠商趕在夏天之前推送了降頻固件,用限制性能輸出的方法來降低發熱,以壓制驍龍888的熱情。
緊接著就是出現大批量「驍龍888降頻後性能不如驍龍865」的反饋和不滿。最慘的小米,一來是首發的驍龍888,二來是早期執行「為發燒而生」的積極調度策略,夏天出現了小米11因高溫燒Wi-Fi的事件。雖然後續有相當良心的換機政策和機型改進,但一朝被蛇咬的小米,隨後成為溫控和頻率控制最保守的廠商。
時間可以沖淡一切,大家坦然接受了驍龍888的熱情,甚至親切地調侃「只有驍龍888還在冬季給我一絲溫暖」。然後,驍龍8 Gen 1來了。
大米評測數據
一代新人勝舊人,稱號也從「火龍」升級為「炎龍」。新的 X2大核,單核功耗刷新了驍龍888的紀錄,從3.3W躍升到4W級別,新的A710大核也有2.1W(中核有3顆)。而新的Adreno GPU,在GFXBench曼哈頓3.0場景的功耗,也從驍龍888的8.2W躍升到10.9W。
這是手機SoC 歷史 上從未出現過的功耗成績,CPU峰值和GPU峰值功耗雙雙突破10W,儼然是平板電腦,甚至是輕薄本級的功耗級別了。蘋果M1和驍龍8 Gen 1,以不同的方式達成了各自的「PC級」標准。
上一顆這么奔放的手機SoC還是2015年的驍龍810。但和7年前不同的是,現在的手機廠商有足夠的技術儲備,能短時間壓住它的發熱。驍龍8 Gen 1不羈的功耗表現,讓包括三星在內的所有安卓廠商,都在發布會上強調自家的散熱配置。「馴龍高手」從以前的調侃,變成所有安卓廠商的目標。
再疊加現階段國內部分32位應用的效率問題(驍龍8 Gen 1新架構中,8顆核心裡只能3顆中核支持32位應用),加劇了老舊應用中的發熱和卡頓問題。要知道,一年裡對手機發熱最為友好的冬春季節即將結束,對溫度更加敏感的夏天就在眼前了。
同樣的發熱問題,也出現在使用同款三星5nm/4nm工藝的Exynos 2100和Exynos 2200上(歐版韓版的三星Galaxy S21系列和歐版的S22系列)。後者是首個搭載AMD RDNA2 GPU的移動SoC,其不但GPU絕對性能沒打過驍龍8 Gen 1和天璣9000,CPU部分也和驍龍8 Gen 1一樣出現能耗比倒退。
同一條時間線上,在用戶飽受發熱之苦的2021年12月,聯發科發布了第一個真正超越高通的SoC——天璣9000。聯發科在量產機開賣前3個月就把工程機拿給媒體進行測試的操作,也是以前從未出現過的。
台積電4nm、更有誠意的堆料、測試機上壓倒性的CPU和能效比,都讓大家期待值拉滿。「干翻X通!天下人苦X通久矣」的歡呼聲不絕於耳。最終萬眾期待的天璣9000,由OPPO Find X5 Pro天璣版PPT首發,由Redmi K50 Pro物理首發。
聯發科天璣9000量產機確實展現出碾壓驍龍8 Gen 1的能耗比,但峰值功耗依然誇張,能耗比也不如工程機逆天。故有梗:聯發科提前給測試機,是為了防止後續廠商調不好的時候賴晶元。至此,2022年3顆採用armv9新架構的新SoC,全部都在能耗比上「掛彩」。
還有一個小插曲。2021年的三星Galaxy S21 Ultra、一加9 Pro和OPPO Find X3系列等安卓旗艦搭載了更加省電的LTPO屏幕(可以動態調整屏幕刷新率的省電技術),而2022年旗艦更是大批量搭載更加省電的LTPO 2.0屏幕。這2代LTPO屏幕恰巧遇上驍龍888和驍龍8 Gen 1,它們省下的電根本不夠SoC吃,故有「關於納智捷發動機油老虎廠家去拚命優化輪胎省油的那些事兒」的梗。
「熱」本身不致命,致命的是CPU性能也原地踏步。這里涉及能耗比(性能和功耗的比值)和熱承載的概念:
驍龍8 Gen 1的CPU性能和驍龍888並沒實質性提升。另外要注意,驍龍888的X1大核是2.8GHz的,而驍龍8 Gen 1的X2大核的3.0GHz的,同頻率下的性能甚至還反向升級了。功耗增長,性能不漲,能效比那日常效果怎麼樣呢?
擺在廠商面前的選擇有兩個:放開驍龍8 Gen 1跑,續航和發熱受累。或控制頻率,保住續航和發熱。從結果上看,所有廠商都選了後者。導致新驍龍8隻有在GeekBench、GFXBench、3DMakr等極少數跑分應用能火力全開。
從2018年的驍龍845開始,安卓旗艦SoC的最高頻只會在應用開啟和信息載入等重負載場景出現,部分驍龍888機型在2021年夏天採用全局降頻的調度,開啟應用也無法調用最高頻率。而到驍龍8 Gen 1這一代,除 游戲 手機和moto,已經沒有國產廠商敢在日常開放最高頻率。這是驍龍8 Gen 1旗艦的日常流暢度還贏不了驍龍888直接原因(即便是天璣9000的Redmi K50 Pro也得開性能模式才能沖到最高頻,日常流暢度也無法和下面提到的天璣8100拉開差距)
跑分性能和日常性能的巨大差異,讓今年 「跑分作弊」的問題愈發明顯。跑分白名單是存在多年的設定,錘子手機時期的羅永浩就炮轟過安卓平台的跑分白名單問題:手機遇到跑分軟體就瘋跑,日常使用卻降頻卡頓。
但今年驍龍8 Gen 1在跑分和日常調度上的差距之大,確實也是史無前例的,進一步促進了「跑分無用論」,沖擊到跑分工具的信任基礎:跑分那麼高,不還是卡?
三星因跑分作弊被GeekBench除名
但跑分平台才是最著急的那個,著名跑分平台GeekBench多年來一直有聲討跑分白名單的操作,三星、華為、一加、小米都是被炮轟的常客。
大米評測數據
那驍龍8 Gen 1日常調度下有多少性能呢?通過修改跑分工具的APK包名,讓GeekBench偽裝成普通應用繞開系統白名單,結果除開之前被除名的三星S22系列,小米、iQOO、真我、一加和系列都有明顯的性能下降。
調度最保守的小米12 Pro,多核成績下降12%,是早期驍龍865級別(對的,安卓CPU性能2年漲12%,而且只能在跑分白名單里);單核成績下降35%,低於中端的驍龍778G。盧偉冰在K50電競版發布會上說「破晶元」的梗,一定程度也得和嚴格的溫控和頻率調節有關。
不過熱歸熱,必須承認驍龍8 Gen 1的GPU性能進步巨大,暴漲50%以上,其GPU能耗比還是高於驍龍888的。這兩年來,無論是高通的Adreno,還是三星、聯發科等使用ARM公版Mali架構的GPU,都有巨大的性能進步。例如,驍龍888的GPU有35%的提升,然後驍龍8 Gen 1的GPU又提升50%,一舉把前兩年被蘋果A13/A14拉開的差距追了回來。
但遺憾的是,移動平台還沒有能完全利用這批GPU性能的重要應用出現,《原神》等主流 游戲 的瓶頸一直都在CPU上,移動GPU的性能卻在持續溢出。而GPU規模的增長,讓其中低負載的功耗依然可觀。在機身只能承載6W功耗的情況下,GPU和GPU「搶功耗」的情況非常明顯,加劇了CPU的降頻。
面對熱情的晶元,手機廠商都不約而同地做出了一致的「聯合優化」:降亮度、鎖幀、降解析度。而且這三板斧還從《原神》波及到負載不算高的《王者榮耀》、《和平精英》上,這樣是「盛況」同樣是 歷史 上從未出現過的。
以前也有降低 游戲 渲染解析度的設定(某GPU Tubro),廠商可以獲得發布會上一條條筆直的 游戲 幀率曲線,並能有效降低 游戲 發熱。紅魔和黑鯊的驍龍8 Gen 1 游戲 旗艦還能對perfdog的幀率曲線進行「補幀」,做到真正的直線,從而讓測試工具失去檢測實際幀率的效果。
但降解析度的代價也是顯而易見的,顧名思義,就是畫麵糊了。但慘痛的現實是,廠商後期OTA或用戶自行破解畫面限制後,發現驍龍8 Gen 1旗艦的 游戲 體驗依然贏不了2兩年前的驍龍865(類比梗:不明白為什麼有的家長會支持禁網路 游戲 ,這樣別人不就發現你孩子沒出息其實是因為笨了嗎)。
現在安卓陣營的情況:好消息是驍龍865還能再戰,壞消息也是驍龍865還能再戰。形成了「驍龍870倒掛驍龍888,而驍龍888又倒掛驍龍8 Gen 1」的奇景。
聯發科這邊也出現了倒掛:22年3月剛發布的天璣8100,用著老一代的台積電5nm和老一代的A78架構,展現出 歷史 最強的能耗比,在《原神》等大型 游戲 測試中,親手把天璣9000擊敗,成為物理意義上的「年度」旗艦。天璣8100:高通870!接受我的挑戰吧! 然後驍龍8 Gen 1和天璣9000應聲倒下。
兩代驍龍的熱情原因,大家第一個懷疑的就是三星的5nm和4nm工藝。除了代工驍龍888和驍龍8 Gen 1,三星也用相同的工藝做了同樣「火熱」的Exynos 2100/2200,並為Google自研的Tensor(唯一搭載雙X1超大核的SoC)代工。除了相似的工藝和架構,「熱情」就是它們最大的共同點。
半導體的晶體管密度,是衡量工藝先進程度的重要指標。相同情況下,製程越先進,發熱越低。晶元能用同等功耗輸出更強的性能,或用更低功耗做到相同的性能。
根據Wikichip數據,三星5nm工藝節點的晶體管密度只有126.7MTr/mm2,4nm LPE是145.8MTr/mm2。但台積電上一代的5nm工藝就已經有171.3MTr/mm2,甚至台積電的N7P工藝都有113.9MTr/mm2。製程數字上,大家是齊頭並進,但實際晶體管密度卻有1到2代的代差。
如果僅僅只有製程的拖累,驍龍8 Gen 1或許不至於這么慘。今年的狀況,是三星工藝和ARM新架構的「強強聯手」的結果。
今年安卓陣營遇到了ARM推出amrv8十年後的第一次重大指令集更新——armv9。驍龍8 Gen 1、天璣9000、Exynos 2200三大產品都換成了X2+A710+A510架構。除去超大核X2的性能原地踏步,大核A710的能耗比也有較為明顯的下降,而最應該提高能耗比的A510小核,只是續接了前代A55小核的能耗曲線,性能更強但功耗也更大,導致晶元低負載功耗也上漲了。
架構升級反而導致實際性能倒退的事情,7年前還發生過一次。那是遙遠的2015年。那一年,「火龍」的名號還屬於驍龍810。
當年的情況是,蘋果在2013年出其不意地發布了首顆64位移動處理器——蘋果A7。次年,高通用台積電20nm,在驍龍810上「強行使用」ARM的首個64位架構A57。後面的事情大家都知道了,驍龍808被迫成為「代理旗艦」,主流廠商跳過驍龍810,造成當年部分國產旗艦的斷檔。那一年也是三星唯一一年,沒同時使用驍龍和自家Exynos晶元,那年的Galaxy S6系列和Galaxy Note5都只有Exynos 7420版本。
更雪上加霜的是,armv9架構中的X2和A510不再支持32位APP,國內大量「堅持」32位的落後APP只能在3顆A710大核上運行,造成了「3核有難、5核圍觀」的窘況。A710大核拉升了CPU的電壓,導致性能低,但功耗卻不低。
移動智能終端生態聯盟4月6日公告
國內還有大量32位APP,甚至國產手機系統中部分自帶APP都還是32位的。在驍龍8 Gen 1發布3個月後,OPPO、vivo、小米、應用寶和網路,終於在4月聯手宣布不再允許單獨上架32位APP,算是從根源上促進了國內APP的64位化。
而作為對比,蘋果iOS在2015年就要求App Store內任何應用更新都必須包含64位版本,到2017年的iOS 11就強制禁用了32位應用。回過頭來看,ARM為了中國國情,特意在A710上保留32位APP的支持,還真不知道算是好事,還是壞事了。
另外提一嘴ARM公司的插曲,英偉達在2020年9月和軟銀達成收購ARM的協議,在2022年2月宣布收購失敗,隨後軟銀宣布將在2023年推動ARM上市。時間上的「巧合」,讓大家調侃ARM新架構不行,是因為「ARM忙著被收購,沒心思搞架構」,但ARM公版架構的前景才是更加讓人擔憂的。ARM為備戰IPO准備全球裁員12%-15%,CPU架構被蘋果越拋越遠,這是內憂。而外患自然是合作夥伴的「叛逃」。
在蘋果全平台轉向ARM平台的2年間,M1、M1 Pro、M1 Max、M1 Ultra輪番刷新大家對ARM陣營的認知。這和ARM官方架構的頹勢形成鮮明對比,並證明ARM指令集也是可以做高性能產品的。而實際上高通也不是成心「擠牙膏」,高通在2021年1月以14億美元的價格收購了晶元設計公司Nuvia,後者由三位從蘋果離職的晶元專家創立。當中的Gerard Williams主持設計了蘋果A13和之前的CPU,其也可能參與了A14和M1系列晶元的設計。所以外界普遍猜測,高通將會回到全自研架構。
PS:高通驍龍在2007開始就是自研架構,在2016年的驍龍835放棄了自研架構,開始以ARM公版架構為基礎做魔改。而三星Exynos則是在2016年的Exynos 8890開始用自研的貓鼬大核架構,堅持到2020年的Exynos 990(第五代貓鼬M5),在2021年重歸ARM公版懷抱。
2017年之前,國產旗艦的最大優點就是良心頂級+驍龍晶元。而這兩年,國產旗艦的最大遺憾成了晶元。晶元好的手機不一定好,但晶元差的手機絕對差。任你屏幕、續航、充電、相機的外圍堆料配置有多強,只要晶元差,那就是短板在漏水的木桶。
普羅大眾從未如此深刻地體會到SoC晶元對手機的重要性。大家習慣了SoC是會不斷進步(最起碼不至於會倒退)。正如網友所說:2017年的驍龍835那會,按照處理器買手機的人,在網上被噴得一無是處。而到了2022年,所有人都按照處理器型號來買手機。
「安迪比爾定律」從未失效,新晶元提供的性能都會被新的軟體吃掉。就算這兩年安卓平台的CPU性能原地踏步,甚至有所倒退的情況下,國內軟體也從未停止「前進的腳步」。QQ都已經內置虛幻引擎成為真正的「國產3A大作」,微信、淘寶們也從未停止新增「趣味」功能的腳步。而比「老旗艦因新版APP而變慢」更慘的是「新旗艦流暢度還贏不了老旗艦」。
「當蘋果拿2個M1 Max合在一起,並給顯示器上A13的時候,華為只能從倉庫里找1年半前切割好的晶元,一次一次的屏蔽下去以苟延殘喘」。
華為受到禁令影響,麒麟9000成為絕唱,這是不幸,但這個時機卻是不幸中的萬幸。華為遇上了安卓陣營「丟失的2年」:麒麟9000用了非常爭氣的A77架構,它後面就是驍龍888用的X1和擠牙膏用的A78架構,再過了一年是驍龍8 Gen 1上的X2+A710+A510。
而鴻蒙起步時的Android 10,同樣是瓶頸前的一代。隨後的Android 11和Android 12,其他國產系統可是吃了不少苦頭。而和華為的運氣形成鮮明對比的是魅族:聯發科遇上了最好的魅族,魅族錯過了最好的聯發科。
放大到行業層面,2020到2022是國產旗艦沖高端的關鍵時間。華為讓出高端空間的2年,國產旗艦進步巨大,大家用上了2K屏幕、充電以倍數秒殺蘋果和三星、國產系統白花齊放、甚至拍照水平都已經不把iPhone放在眼內(當然,視頻還是iPhone最強)。可以說,國產廠商把能把握的東西都准備好了,但結果遇上了2021年的驍龍888和今年的驍龍8 Gen 1。
我們看到的是海思在最風光最強盛的時候「被急流勇退」,我們心中的海思只有可惜,但絕不算可憐。以致網友調侃「高通這公司能處,麒麟被制裁它是真的會等,也真會激勵發哥變強」,大家還以為是高通在幫華為拖住其他安卓廠商。而蘋果看著安卓陣營內斗,庫克含淚收割高端市場。
Counterpoint數據
在三星已成擺設的國內市場,只有蘋果一個物理對手,其他品牌接不住華為放出的高端市場,這是個值得中國人銘記的恥辱:2021年,中國高端手機佔比(售價>600美元),從2020年的44.6%下降到36.5%,全部安卓加起來都贏不了iPhone。截止4月6日,作為這批國產旗艦的門面,小米12系列首月銷量是前代的41%。這里有疫情的影響,但晶元要背負多少責任?就得由大家自行判斷了。
同樣諷刺的是,擁有華為以前渠道的榮耀,以極高的速度崛起。從榮耀50到榮耀60,從Magic3到Magic4,產品力上是能感知到榮耀被耽擱的大半年的。但和其他旗艦一樣用驍龍晶元的榮耀,用銷量向我們證明,單純的產品力在絕對的渠道力量面前其實是挺無力的。這樣的事實,又何嘗不是扇在產品經理臉上的響亮耳光。余承東說華為會在明年強勢回歸,我們也很好奇,那時候的榮耀,會什麼樣的身份出現?
手機市場每隔幾年就會有「江郎才盡、已經看到天花板」的說法。2017年的小米MIX開啟了全面屏時代,為智能手機續命2年;華為帶起來的大底感測器和長焦鏡頭軍備競賽,又為國產旗艦提供了3年的發展期。
而現在的手機市場和國內A股一樣茫然,大家看不到未來的路。A股只有上下兩個走向,而且總該會看到底部,但國產手機卻越發迷茫。幾乎被窮盡的外觀設計、進入瓶頸期的屏幕、充電和拍照、輪不到國產廠商控制的SoC,都在提醒我們,手機廠商貌似也沒找到下一個發展方向。但此時此刻,唯一能確定的是,下一個風口不是折疊屏。
雷峰網雷峰網雷峰網
G. Android性能測試(內存、cpu、fps、流量、GPU、電量)——adb篇
3)查看進程列表:adb shell "ps",同時也能獲取到應用的UID,方式如下(不需root許可權):
u0_a開頭的都是Android的應用進程,Android的應用的UID是從10000開始,到19999結束,可以在Process.java中查看到(FIRST_APPLICATION_UID和LAST_APPLICATION_UID),u0_a後面的數字就是該應用的UID值減去FIRST_APPLICATION_UID所得的值,所以,對於截圖這個應用進程,它是u0_a155,按前面的規制,它的UID就是155 + FIRST_APPLICATION_UID = 10155。
VSS - Virtual Set Size 虛擬耗用內存(包含共享庫佔用的內存)
RSS - Resident Set Size 實際使用物理內存(包含共享庫佔用的內存)
PSS - Proportional Set Size 實際使用的物理內存(比例分配共享庫佔用的內存)
USS - Unique Set Size 進程獨自佔用的物理內存(不包含共享庫佔用的內存)
一般來說內存佔用大小有如下規律:VSS >= RSS >= PSS >= USS
使用 adb shell "mpsys meminfo -s <pakagename | pid>"命令,輸出結果分以下4部分:
PS:在apk內調用運行獲取其他app的內存數據則需要root許可權
adb命令:adb shell mpsys gfxinfo <package | pid>
正常情況下幀率應該在16.67ms左右,1秒60幀,執行結果如下:
詳細計算方法如下:
還有一個命令是: adb shell mpsys SurfaceFlinger --latency LayerName
其中LayerName在各個不同系統中獲取的命令是不一樣的
在Android 6系統直接就是SurfaceView
在Android 7系統中可以通過 mpsys window windows | grep mSurface | grep SurfaceView 然後通過數據截取到
在Android 8系統中可以通過 mpsys SurfaceFlinger | grep android包名獲取到
執行命令結果如下:
計算方法比較簡單,一般列印出來的數據是129行(部分機型列印兩次257行,但是第一部分是無效數據,取後半部分),取len-2的第一列數據為end_time,取len-128的第一列數據為start_time
fps = 127/((end_time - start_time) / 1000000.0)
至於為啥要取第一列數據,這里不做過多介紹,歡迎參看這兩篇文章
老羅的文章SurfaceView原理
Android性能測試之fps獲取
至於為啥要處於1000000,因為命令列印出來的是納秒單位,要轉為毫秒進行計算,127就是因為命令一次列印出來127幀的數據而已
有兩種方法可以獲取
1) adb shell "top -n 5 | grep <package | pid>" ,第三列就是實時監控的CPU佔用率(-n 指定執行次數,不需root許可權),這邊top命令執行需要2到3s左右,一般可以採用busybox 的top命令執行,效率會快很多
2) adb shell "mpsys cpuinfo | grep <package | pid>"
兩種方法直接區別在於,top是持續監控狀態,而mpsys cpuinfo獲取的實時CPU佔用率數據
adb命令:adb shell "mpsys batterystats < package | pid>" (Android 5.0後引入)
獲取單個應用的耗電量信息,具體返回結果待研究
adb命令:adb shell "mpsys battery"
出現信息解讀:
AC powered:false 是否連接AC(電源)充電線
USB powered:true 是否連接USB(PC或筆記本USB插口)充電
Wireless powered:false 是否使用了無線電源
status: 1 電池狀態,2為充電狀態,其他為非充電狀態
level:58 電量(%)
scale: 100. 電量最大數值
voltage: 3977 當前電壓(mV)
current now: -335232. 當前電流(mA)
temperature:355 電池溫度,單位為0.1攝氏度
adb 命令:adb shell "mpsys< package | pid> | grep UID" [通過ps命令,獲取app的UID(安裝後唯一且固定)]
adb shell cat /proc/uid_stat/UID/tcp_rcv [cat為查看命令,讀取tcp_rcv獲取應用接收流量信息(設備重啟後清零)]
adb shell cat /proc/uid_stat/UID/tcp_snd [cat為查看命令,讀取tcp_snd獲取應用發送流量信息(設備重啟後清零)]
計算流量消耗步驟:
或者還有一種方式獲取應用流量消耗:
首先判斷類型:
cat /sys/class/thermal/thermal_zone*/type
只有紅框框出來的是有效的
cat /sys/class/thermal/thermal_zone*/temp
獲取CPU溫度
mpsys battery | grep temperature 單位0.1攝氏度
獲取/proc/stat文件內容(無許可權限制)
總的cpu時間片是 total = user+nice+system+idle+iowait+irq+softirq
忙碌時間為 notidle = user+nice+system +iowait+irq+softirq
cpu使用率計算方法為,先取開始的total值和忙碌時間notidle,隔一段時間片,再取一次計算total2,notidle2, cpuuse = (notidle2 – notidle) * 100 / (total2 - total)%
PS:由於Android 8許可權收緊,在Android 8系統手機內apk內讀取文件內容為空,需要shell許可權才可獲取文件內容,下同
讀/sys/devices/system/cpu/cpuX/cpufreq/scaling_cur_freq文件的值,X不定,看是幾核手機,scaling_cur_freq是否存在也不一定,需要判斷
至於為啥不取cpuinfo_cur_freq文件的值,原因是android 6,7系統獲取的時候,這個文件shell沒有讀取許可權,需要root許可權
參考文章: https://blog.csdn.net/long_meng/article/details/45934899
Android 6,7系統可執行
mpsys window windows | grep "mCurrentFocus"
執行結果一般為類似:
mCurrentFocus=Window{81caaa5 u0 com.tencent.mobileqq/com.tencent.mobileqq.activity.SplashActivity}
按照一定規則把com.tencent.mobileqq提取出來即可
直接apk內讀取文件即可,不需要shell許可權(支持到Android8)
Gpu使用率獲取:會得到兩個值,(前一個/後一個)*100%=使用率
adb shell cat /sys/class/kgsl/kgsl-3d0/gpubusy
Gpu工作頻率:
adb shell cat /sys/class/kgsl/kgsl-3d0/gpuclk
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/cur_freq
Gpu最大、最小工作頻率:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/max_freq
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/min_freq
Gpu可用頻率
adb shell cat /sys/class/kgsl/kgsl-3d0/gpu_available_frequencies
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/available_frequencies
Gpu可用工作模式:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/available_governors
Gpu當前工作模式:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/governor
H. Android應用查看CPU與內存佔用說明
命令中的"應用包名"應該替換為你需要查詢的包名.
執行命令後, 在輸出的內容中, 第二項即應用的進程名, 例如:
那麼 22411 即為該應用當前的pid.
其中的"應用的pid"為上一步獲取到的pid
執行命令後, 命令行工具即會列印應用運行信息
命令中的"應用包名"應該替換為你需要查詢的包名.
命令執行後過段時間即會列印內存佔用大小.
I. 安卓手機CPU頻率怎麼看怎麼檢查查看
安卓手機CPU頻率怎麼查看呢?在這篇指南中,將為大家介紹一下具體的操作步驟。
以MIUI系統為例,打開MIUI桌面上的「應用商店」圖標,進入應用商店。
進入應用商店主頁面之後,點擊頁面頂部搜索欄,並輸入「CPU」關鍵字,在搜索結果列表中,選擇CPU監控應用,下載並安裝該應用。
應用下載完畢之後,打開該應用,在應用首頁就可以看到當前CPU運行的頻率以及溫度了,會有曲線顯示在屏幕上。
除了CPU運行頻率的實時顯示之外,還可以通過查看歷史記錄、歷史分析等來具體查看CPU的運行頻率,不過需要等待軟體運行一段時間採集了數據之後才可以查看。