姓名:郭佳朋? ?學(xué)號(hào):14310116045
轉(zhuǎn)載自:http://blog.csdn.net/kester_/article/details/71055901
【嵌牛導(dǎo)讀】:NDK 開(kāi)發(fā)時(shí)會(huì)涉及到 CPU 架構(gòu)的適配沦辙,不同的機(jī)器上可能會(huì)有不同的 CPU 架構(gòu),也就是說(shuō)投剥,翻譯到機(jī)器上使用的規(guī)則不一樣魁巩,Android 上有7種 CPU 架構(gòu)碱茁。
【嵌牛鼻子】:CPU架構(gòu)
【嵌牛提問(wèn)】:?了解CPU相關(guān)嗎粒褒?
【嵌牛正文】:安卓CPU基礎(chǔ)
凡是接觸過(guò)安卓系統(tǒng)的朋友仗岸,對(duì)CPU一定不會(huì)陌生林螃。
NDK 開(kāi)發(fā)時(shí)會(huì)涉及到 CPU 架構(gòu)的適配奕删,不同的機(jī)器上可能會(huì)有不同的 CPU 架構(gòu),也就是說(shuō)疗认,翻譯到機(jī)器上使用的規(guī)則不一樣完残,Android 上有7種 CPU 架構(gòu)伏钠。
1.armeabi
2.armeabi-v7a
3.arm64-v8a
4.x86
5.x86_64
6.MIPS
7.MIPS64
從廠家上來(lái)分是有三種,arm谨设,x86熟掂,MIPS,arm 系列是絕大多數(shù)手機(jī)上使用的扎拣,x86 主要是運(yùn)用在平板上赴肚,而 MIPS 基本上就沒(méi)見(jiàn)過(guò)。
從類型來(lái)分二蓝,有32位和64位誉券,名字中沒(méi)有64的就是32位的了。
正常來(lái)說(shuō)只使用 armeabi-v7a 就可以適配基本所有手機(jī)了刊愚,因?yàn)楝F(xiàn)在手機(jī)基本上都支持這種CPU架構(gòu)踊跟,但是對(duì)于同時(shí)也能支持 arm64-v8a 的手機(jī)來(lái)說(shuō),性能上就不如使用對(duì)應(yīng) CPU 架構(gòu)的快了鸥诽,畢竟是32位和64位的區(qū)別商玫,值得一提的是,arm 系列本身是沒(méi)有64位衙传,而是 intel 的x86_64先出現(xiàn)的决帖,之后 arm 收購(gòu)了 MIPS64,基于 MIPS64 改良出 arm64-v8a蓖捶,所以也能理解為什么 MIPS 幾乎沒(méi)有地回,而另外,arm64-v8a 的 CPU 架構(gòu)上也能運(yùn)行 armeabi-v7a俊鱼,為什么呢刻像?不是64位上運(yùn)行32位,而是 arm64-v8a 上本身搭載了 armeabi-v7a并闲,所以在 arm64-v8a 上運(yùn)行 armeabi-v7a 是使用32位處理的细睡,沒(méi)毛病。
如果應(yīng)用中有不止一個(gè) so帝火,那就要注意了溜徙,如果這時(shí)你一個(gè) so 同時(shí)支持了 armeabi-v7a 和arm64-v8a,而另一個(gè) so 只支持了一種犀填,那可能會(huì)運(yùn)行有問(wèn)題蠢壹,這時(shí)要么另一個(gè) so 也支持兩種,要么把第一個(gè) so 刪掉對(duì)應(yīng)目錄九巡,只支持相同的一種图贸。
在提供支持多個(gè) CPU 架構(gòu)的 SDK 時(shí),可以同時(shí)提供多個(gè)目錄的 so,雖然此時(shí) SDK 相對(duì)較大疏日,但是被編譯的 so 還是以你在 gradle 里設(shè)置的支持的 ndk 為準(zhǔn):
ndk {
abiFilters ‘a(chǎn)rmeabi-v7a’ // , ‘a(chǎn)rm64-v8a’, ‘x86’, ‘x86_64’
}
查看設(shè)備支持的 CPU 架構(gòu)或者 APP 提供的 CPU 架構(gòu)可以使用 Native Libs Monitor偿洁。
1 查看手機(jī)CPU信息
cmd——adb shell——cd /proc------cat cpuinfo
2 獲取cpu的是arm指令集,armv7指令集沟优、還是neon指令集
[java] view plain copy
/*** * [獲取cpu類型和架構(gòu)]* * @return?
* 三個(gè)參數(shù)類型的數(shù)組涕滋,第一個(gè)參數(shù)標(biāo)識(shí)是不是ARM架構(gòu),第二個(gè)參數(shù)標(biāo)識(shí)是V6還是V7架構(gòu)净神,第三個(gè)參數(shù)標(biāo)識(shí)是不是neon指令集
*/?
public static Object[] getCpuArchitecture() {?
? ? if ((Integer) mArmArchitecture[1] != -1) {?
? ? ? ? return mArmArchitecture;?
? ? }?
? ? try {?
? ? ? ? InputStream is = new FileInputStream("/proc/cpuinfo");?
? ? ? ? InputStreamReader ir = new InputStreamReader(is);?
? ? ? ? BufferedReader br = new BufferedReader(ir);?
? ? ? ? try {?
? ? ? ? ? ? String nameProcessor = "Processor";?
? ? ? ? ? ? String nameFeatures = "Features";?
? ? ? ? ? ? String nameModel = "model name";?
? ? ? ? ? ? String nameCpuFamily = "cpu family";?
? ? ? ? ? ? while (true) {?
? ? ? ? ? ? ? ? String line = br.readLine();?
? ? ? ? ? ? ? ? String[] pair = null;?
? ? ? ? ? ? ? ? if (line == null) {?
? ? ? ? ? ? ? ? ? ? break;?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? pair = line.split(":");?
? ? ? ? ? ? ? ? if (pair.length != 2)?
? ? ? ? ? ? ? ? ? ? continue;?
? ? ? ? ? ? ? ? String key = pair[0].trim();?
? ? ? ? ? ? ? ? String val = pair[1].trim();?
? ? ? ? ? ? ? ? if (key.compareTo(nameProcessor) == 0) {?
? ? ? ? ? ? ? ? ? ? String n = "";?
? ? ? ? ? ? ? ? ? ? for (int i = val.indexOf("ARMv") + 4; i < val.length(); i++) {?
? ? ? ? ? ? ? ? ? ? ? ? String temp = val.charAt(i) + "";?
? ? ? ? ? ? ? ? ? ? ? ? if (temp.matches("\\d")) {?
? ? ? ? ? ? ? ? ? ? ? ? ? ? n += temp;?
? ? ? ? ? ? ? ? ? ? ? ? } else {?
? ? ? ? ? ? ? ? ? ? ? ? ? ? break;?
? ? ? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? ? ? mArmArchitecture[0] = "ARM";?
? ? ? ? ? ? ? ? ? ? mArmArchitecture[1] = Integer.parseInt(n);?
? ? ? ? ? ? ? ? ? ? continue;?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? if (key.compareToIgnoreCase(nameFeatures) == 0) {?
? ? ? ? ? ? ? ? ? ? if (val.contains("neon")) {?
? ? ? ? ? ? ? ? ? ? ? ? mArmArchitecture[2] = "neon";?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? ? ? continue;?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? if (key.compareToIgnoreCase(nameModel) == 0) {?
? ? ? ? ? ? ? ? ? ? if (val.contains("Intel")) {?
? ? ? ? ? ? ? ? ? ? ? ? mArmArchitecture[0] = "INTEL";?
? ? ? ? ? ? ? ? ? ? ? ? mArmArchitecture[2] = "atom";?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? ? ? continue;?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? if (key.compareToIgnoreCase(nameCpuFamily) == 0) {?
? ? ? ? ? ? ? ? ? ? mArmArchitecture[1] = Integer.parseInt(val);?
? ? ? ? ? ? ? ? ? ? continue;?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? }?
? ? ? ? } finally {?
? ? ? ? ? ? br.close();?
? ? ? ? ? ? ir.close();?
? ? ? ? ? ? is.close();?
? ? ? ? }?
? ? } catch (Exception e) {?
? ? ? ? e.printStackTrace();?
? ? }?
? ? return mArmArchitecture;?
}?
調(diào)用的該函數(shù)的示例方法
[java] view plain copy
/*
* 獲取FFpeg解碼庫(kù)的名稱(如果是插件何吝,會(huì)涉及到一個(gè)向下兼容的問(wèn)題,例如:如果當(dāng)前cpu是V7neo鹃唯,而又沒(méi)有neon的解碼庫(kù)爱榕,必須要做向下兼容出來(lái)
* ,如果有V7的庫(kù)就加載V7的庫(kù)坡慌,有V6的庫(kù)就加載V6的)
*/?
public static String getFFmpegLibName(Context context) {?
? ? if (LIB_FFMPEG_NAME != null) {?
? ? ? ? return LIB_FFMPEG_NAME;?
? ? }?
? ? Object[] arch = getCpuArchitecture();?
? ? String libDir = getNativeLibraryDir(context);?
? ? String libSysDir = "/system/lib";?
? ? if ("ARM".equals(arch[0])) {?
? ? ? ? try {?
? ? ? ? ? ? String ffmpeg = String.format("ffmpeg-%d%s", (Integer) arch[1], (String) arch[2]);?
? ? ? ? ? ? if (isFileExist(libDir + "/lib" + ffmpeg + ".so") || isFileExist(libSysDir + "/lib" + ffmpeg + ".so")) {?
? ? ? ? ? ? ? ? return ffmpeg;?
? ? ? ? ? ? } else {?
? ? ? ? ? ? ? ? boolean isV7NeonCpu = "neon".equals(arch[2]);?
? ? ? ? ? ? ? ? boolean isV7 = ((Integer) arch[1]) == 7 && "".equals(arch[2]);?
? ? ? ? ? ? ? ? boolean isV6 = ((Integer) arch[1]) == 6;?
? ? ? ? ? ? ? ? if (isV7NeonCpu) {?
? ? ? ? ? ? ? ? ? ? if (isFileExist(libDir + "/libffmpeg-7neon.so")?
? ? ? ? ? ? ? ? ? ? ? ? ? ? || isFileExist(libSysDir + "/libffmpeg-7neon.so")) {?
? ? ? ? ? ? ? ? ? ? ? ? LIB_FFMPEG_NAME = "ffmpeg-7neon";?
? ? ? ? ? ? ? ? ? ? ? ? return "ffmpeg-7neon";?
? ? ? ? ? ? ? ? ? ? } else if (isFileExist(libDir + "/libffmpeg-7.so")?
? ? ? ? ? ? ? ? ? ? ? ? ? ? || isFileExist(libSysDir + "/libffmpeg-7.so")) {?
? ? ? ? ? ? ? ? ? ? ? ? LIB_FFMPEG_NAME = "ffmpeg-7";?
? ? ? ? ? ? ? ? ? ? ? ? return "ffmpeg-7";?
? ? ? ? ? ? ? ? ? ? } else if (isFileExist(libDir + "/libffmpeg-6.so")?
? ? ? ? ? ? ? ? ? ? ? ? ? ? || isFileExist(libSysDir + "/libffmpeg-6.so")) {?
? ? ? ? ? ? ? ? ? ? ? ? LIB_FFMPEG_NAME = "ffmpeg-6";?
? ? ? ? ? ? ? ? ? ? ? ? return "ffmpeg-6";?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? } else if (isV7) {?
? ? ? ? ? ? ? ? ? ? if (isFileExist(libDir + "/libffmpeg-7.so") || isFileExist(libSysDir + "/libffmpeg-7.so")) {?
? ? ? ? ? ? ? ? ? ? ? ? LIB_FFMPEG_NAME = "ffmpeg-7";?
? ? ? ? ? ? ? ? ? ? ? ? return "ffmpeg-7";?
? ? ? ? ? ? ? ? ? ? } else if (isFileExist(libDir + "/libffmpeg-6.so")?
? ? ? ? ? ? ? ? ? ? ? ? ? ? || isFileExist(libSysDir + "/libffmpeg-6.so")) {?
? ? ? ? ? ? ? ? ? ? ? ? LIB_FFMPEG_NAME = "ffmpeg-6";?
? ? ? ? ? ? ? ? ? ? ? ? return "ffmpeg-6";?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? } else if (isV6) {?
? ? ? ? ? ? ? ? ? ? if (isFileExist(libDir + "/libffmpeg-6.so") || isFileExist(libSysDir + "/libffmpeg-6.so")) {?
? ? ? ? ? ? ? ? ? ? ? ? LIB_FFMPEG_NAME = "ffmpeg-6";?
? ? ? ? ? ? ? ? ? ? ? ? return "ffmpeg-6";?
? ? ? ? ? ? ? ? ? ? }?
? ? ? ? ? ? ? ? }?
? ? ? ? ? ? }?
? ? ? ? } catch (Exception e) {?
? ? ? ? ? ? e.printStackTrace();?
? ? ? ? }?
? ? } else if ("INTEL".equals(arch[0])) {?
? ? ? ? if (isFileExist(libDir + "/libffmpeg-x86atom.so") || isFileExist(libSysDir + "/libffmpeg-x86atom.so")) {?
? ? ? ? ? ? LIB_FFMPEG_NAME = "ffmpeg-x86atom";?
? ? ? ? ? ? return "ffmpeg-x86atom";?
? ? ? ? }?
? ? }?
? ? LIB_FFMPEG_NAME = null;?
? ? return null;?
}?