android ndk profiler 分析本地代碼

寫一寫前兩天用android ndk profiler 分析本地代碼的過程,在此記錄一下,防止之後忘記 步驟:html

一、官網下載android ndk profile :https://code.google.com/p/android-ndk-profilerjava

二、更改Android.mk, 加載android ndk profiler模塊。 其實這個步驟的詳細過程官網已經有了,基本按官網的說明來作就能夠了:http://code.google.com/p/android-ndk-profiler/wiki/Usagelinux

<!-- lang: shell -->
# compile with profiling
LOCAL_CFLAGS := -pg
LOCAL_STATIC_LIBRARIES := android-ndk-profiler

# at the end of Android.mk
$(call import-module,android-ndk-profiler)

看個人android.mk:android

<!-- lang: shell -->
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

# compile with profiling
LOCAL_CFLAGS := -pg
LOCAL_STATIC_LIBRARIES := android-ndk-profiler

LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c

include $(BUILD_SHARED_LIBRARY)

# at the end of Android.mk
$(call import-module,android-ndk-profiler)

三、3 在啓動和結束函數裏,加入監視代碼。默認會產生sdcard/gmon.out文件。因此你須要在sdcard上的寫權限,修改AndroidManifest.xml,加上:shell

<!-- lang: java -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

四、修改本地代碼,在本地代碼須要調試的起始位置和結束位置加上監視函數:ubuntu

<!-- lang: cpp -->
/* in the start-up code */
monstartup("your_lib.so");

/* in the onPause or shutdown code */
moncleanup();

個人例子的代碼:ide

<!-- lang: cpp -->
#include<string.h>
#include<stdio.h>
#include<math.h>
#include <memory.h>
#include<jni.h>


jstring Java_com_wxg_ndkdemo_MainActivity_stringFromJNI(JNIEnv *env ,jobject thiz)
{
	int i ;

	setenv("CPUPROFILE_FREQUENCY", "500", 1); /* Change to 500 interrupts per second */
	monstartup("libhello-jni.so");

	test();
//	setenv("CPUPROFILE", "/sdcard/gmon.out", 1);

	moncleanup();
	return (*env)->NewStringUTF(env,"Hello from JNI !");

}

jint add()
{

	int i=10000,j=0;
	for(i=0;i<10000;i++)
	{
		for(j=0;j<10000;j++)
		{
			i*j;
		}
	}
	return i+j;
}

jint test()
{
	add();
//	int i;
//	char buffer[] = "Hello world/n";
//	printf("Buffer before memset: %s/n", buffer);
//	memset(buffer, '*', strlen(buffer) );
//	printf("Buffer after memset: %s/n", buffer);
//
//	FILE *fp = fopen("/sdcard/a.txt","at");
//
//	fprintf(fp,"%s\n",buffer);
//
//	for(i=0;i<100000;i++)
//	{
//		char ch[30];
//		sprintf(ch,"the number is %d\n",i);
//		char str[30];
//		memcpy(str,ch,strlen(ch));
//		fputs(ch,fp);
////		fprintf(fp,"%s\n",ch);
//	}
//
//	fclose(fp);

	int i,j;
	double  s = 0,temp=1.0;
	for(i=1;i<=5000000;i++)
	{
		s += sqrt(temp);
		temp = s;
	}

	return 0;
}

五、使用ndk-build編譯本地代碼函數

<!-- lang: shell -->
ubuntu@ubuntu:~/workspace/NDKDemo$ ndk-build NDK_MODULE_PATH=~/android/
Install        : libhello-jni.so => libs/armeabi/libhello-jni.so

其中ui

<!-- lang: shell -->
NDK_MODULE_PATH=~/android/

指向的是包含android_ndk_profiler文件夾的目錄,看個人google

<!-- lang: shell -->
ubuntu@ubuntu:~/android$ ls android-ndk*
android-ndk-profiler:
Android.mk  armeabi  armeabi-v7a  prof.h

android-ndk-r8e:
build  documentation.html  ndk-build      ndk-gdb     ndk-gdb.py      ndk-stack  platforms  README.TXT   samples  tests
docs   GNUmakefile         ndk-build.cmd  ndk-gdb-py  ndk-gdb-py.cmd  ndk-which  prebuilt   RELEASE.TXT  sources  toolchains

六、運行程序,最後查看結果

使用gprof命令產生結果,須要先用adb pull命令將gmon.out文件拷貝到本身的PC上

先進入你android的NDK項目的obj目錄下的objs下的子目錄下:

<!-- lang: shell -->
ubuntu@ubuntu:~/workspace/NDKDemo/obj/local/armeabi/objs/hello-jni$ ls
hello-jni.o  hello-jni.o.d
ubuntu@ubuntu:~/workspace/NDKDemo/obj/local/armeabi/objs/hello-jni$ adb pull /sdcard/gmon.out
355 KB/s (16463 bytes in 0.045s)
ubuntu@ubuntu:~/workspace/NDKDemo/obj/local/armeabi/objs/hello-jni$ ls
gmon.out  hello-jni.o  hello-jni.o.d

最後使用NDK的gprof查看結果

<!-- lang: shell -->
ubuntu@ubuntu:~/workspace/NDKDemo/obj/local/armeabi/objs/hello-jni$ ~/android/android-ndk-r8e/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gprof hello-jni.o
相關文章
相關標籤/搜索