zoukankan      html  css  js  c++  java
  • Cocos2d-x性能分析-Android版本之Gprof

    在 iOS 平台下我们可以用 Xcode 自带的 Profile 工具来测试我们程序的性能,Android 平台使用的 gprof

    这里整理了一下具体的cocos2dx 使用gprof进行性能分析的具体步骤、 遇到的问题及解决方案

    因为 Android 本来就是基于 Linux 的,所以这里用 gprof 来做性能测试是没什么问题的。不过需要注意的是,这里所说的性能测试是针对 NDK 编译的 C++ 代码的。就想 Cocos2d-x 这样的 C++ 实现的游戏引擎就可以通过 gprof 来分析。下面我们来说说搞法

    一.准备工作

    1.参考资料

    网上有很多前辈写的比较好的帖子,这里先贴出来让大家看看。

    教程:

    http://leenjewel.github.io/blog/2015/04/17/android-ping-tai-yong-gprof-gei-cocos2d-x-zuo-xing-neng-fen-xi/

    http://www.cnblogs.com/tibetanmastiff/p/3625569.html

    http://www.cnblogs.com/anxin1225/p/6151092.html

    http://blog.csdn.net/kesaihao862/article/details/7313679

    http://www.cnblogs.com/feisky/archive/2010/03/09/1681997.html

    本文主要依据 Android 平台用 Gprof 给 Cocos2d-x 做性能分析 。

    2.环境

    Mac  下,Cocos2d-x 3.11.1,只不过是编译出的 so 文件有所不同罢了。

    只要是 NDK 的代码都可以用 gprof 来做性能分析的。

    2.android-ndk-profiler 下载Gprof

    要想生成 gprof 的性能分析报告,我们优先要把一个叫做 android-ndk-profiler 的模块集成到我们的项目中。

    原文提到的第一种下载:

    android-ndk-profiler 模块的源代码在 GitHub 上面,首先要把模块代码 clone 下来

    1
    
    git clone git@github.com:richq/android-ndk-profiler.git

    android-ndk-profiler 的项目自带了一篇文档说明教授如何集成和使用,但是写的比较简单,我来详细的说一下。android-ndk-profiler 项目 clone 下来后进到项目目录可以看到如下结构

    1
    2
    3
    4
    
     |-docs
     |-example
     |-jni
     |-test

    而我们需要的就是jni这个目录下面的文件。

    2、我这里使用的别的方式

    下载地址 :
    https://github.com/richq/android-ndk-profiler

    解压缩之后:

    需要的就是jni这个目录下面的文件。

    3.项目中集成

    1、来到我们自己的 Cocos2d-x 项目目录中,新建一个叫做 android-ndk-profiler 的文件夹,将刚刚克隆的 android-ndk-profile 模块的 jni 目录中的所有文件拷贝到我们刚刚建立的文件夹中。

    比如我这里

     

    2.Android.mk

    打开 proj.android/jin/Android.mk 文件,

    #*注意* YOUR_ANDROID_NDK_PROFILER_PATH 是你 cocos2d-x 项目中 android-ndk-profiler 目录的位置
    
    $(call import-add-path,$(YOUR_ANDROID_NDK_PROFILER_PATH))
    
    # 加入头文件
    LOCAL_C_INCLUDES += $(YOUR_ANDROID_NDK_PROFILER_PATH)
    
    APP_DEBUG := $(strip $(NDK_DEBUG))
    
    # 如果是 Debug 模式,则引入 android-ndk-profiler
    ifeq ($(APP_DEBUG),1)
      LOCAL_CFLAGS := -pg
      LOCAL_STATIC_LIBRARIES += android-ndk-profiler
    endif
    
    ifeq ($(APP_DEBUG),1)
      $(call import-module,YOUR_ANDROID_NDK_PROFILER_PATH)
    endif

    根据上面配置的路径,这里可以添加一下代码

    proj.android/jin/Android.mk
    
    #*注意* YOUR_ANDROID_NDK_PROFILER_PATH 是你 cocos2d-x 项目中 android-ndk-profiler 目录的位置
    
    $(call import-add-path, $(LOCAL_PATH)/../../../cocos2d-x/external/android-ndk-profiler)
    
    # 加入头文件
    LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../cocos2d-x/external/android-ndk-profiler
    
    LOCAL_CFLAGS := -pg
    LOCAL_STATIC_LIBRARIES += android-ndk-profiler
    
    $(call import-module, android-ndk-profiler)
    c
    注意:具体路径根据你自己的项目进行配置,这里不做解释

    3.编辑 AppDelegate.cpp 文件

    只需要引入一个头文件,添加两个函数调用即可

     

    // 引入头文件
    #if (COCOS2D_DEBUG>0 && CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    #include "prof.h"
    #endif
    
    bool AppDelegate::applicationDidFinishLaunching()
    {
    #if (COCOS2D_DEBUG>0 && CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
      monstartup("libcocos2dlua.so");
    #endif
      // 其他已有逻辑代码......
    }
    
    void AppDelegate::applicationDidEnterBackground()
    {
      // 其他已有逻辑代码......
    #if (COCOS2D_DEBUG>0 && CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        moncleanup();
    #endif
    }

     

    这里只需要注意两点。

    WRITE_EXTERNAL_STORAGE 写的权限

    AndroidManifest.xml 因为要生成性能分析报告,所以要赋予你的 Android 程序 WRITE_EXTERNAL_STORAGE 权限,即

    1
    
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    

    libcocos2dlua.so 这个 so 文件会根据你的 Cocos2d-x 项目的类型不同名字上会有所不同,比如我们是 Lua 项目,所以 NDK 编译生成的 so 文件就叫 libcocos2dlua.so ,具体的文件名请自行到 proj.android/libs/armeabi 目录下查看。

    4.编译打debug包

     

    编译失败:

    1.找不到 prof.h

    可以在 proj.android/jin/Android.mk 上面添加

     

    LOCAL_C_INCLUDES := 
    $(LOCAL_PATH)/../../../cocos2d-x/external/android-ndk-profiler 

     

    2.
    ucontext_t 不识别。 ucontext_t这个是在 ndk里面

    由于我的 android-ndk-r9d没有,所以 换成了 android-ndk-r10e

    打包成功之后运行会生成gmon.out

    引用别人的原文,解释下原理:

    生成 gmon.out 性能分析报告

    项目编译完成后生成 apk 文件,将 apk 文件安装到 Android 设备上。通过上一小节我们对 AppDelegate.cpp 文件的修改不难看出,当程序在 Android 设备上运行的时候,调用了 monstartup 函数开始性能分析,当程序退到后台时调用了 moncleanup 函数生成性能分析报告。性能分析报告文件默认存储到 Android 设备的 /sdcard/gmon.out 位置,我们用 adb 工具可以把文件拉到电脑上面。

    1
    
    adb pull /sdcard/gmon.out .
    

    当然官方文档里面也提了,如果想要自定义性能分析报告存放的位置,可以在调用 moncleanup 函数前指定要保存的位置。

    1
    2
    
    setenv("CPUPROFILE", "/data/data/com.example.application/files/gmon.out", 1);
    moncleanup();
    

    解读性能分析报告 gmon.out

    生成的性能分析告报 gmon.out 是不能直接通过文本编辑器打开来读的,它是个二进制文件,需要专门的工具来生成可读的文本文件。这个工具在 NDK 中已经提供了,以我使用的 android-ndk-r10d 为例:

    1
    2
    3
    4
    5
    
    cd android-ndk-r10d/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/
    
    ./arm-linux-androideabi-gprof 
      你的项目路径/proj.android/obj/local/armeabi/libcocos2dlua.so
      你的gmon.out存放路径/gmon.out > gmon.txt
    

    这里只解释一点。

    libcocos2dlua.so 细心的读者发现这里使用的 so 文件并不是之前的那个放在 proj.android/libs/armeabi/libcocos2dlua.so 下面的那个 so 文件。这是因为最终随 apk 一起打包的那个 libcocos2dlua.so 文件(也就是 proj.android/libs/armeabi 目录下的)是不包含符号表的,而存放在 proj.android/obj/local/armeabi 目录下的是带符号表的版本。而什么是符号表,这是一个编译链接中的概念,请自行 Google 一下,或者读一读《程序员的自我修养》这本书,再次强烈推荐这本书。

    咱们自己的代码

    对于生成 的gmon.out分析,命令行:

    分析 gmon.out
    $ cd /Users/hanyundi/Documents/ZFT_SDK/android/android-ndk-r10e/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin 
    
    $ ./arm-linux-androideabi-gprof libcocos2dlua.so的位置 gmon.out的位置 > mygmon.txt

     mygmon.txt输出到了 arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin下,你可以放到你想放的地方

     android-ndk-r10e(这个其他版本也可以。我试了几个)

    遇到的问题

    一开始使用的魅族手机,生成了gmon.out,但是解读的时候报错,换了一台华为的手机就可以了。

    具体的gmon.out分析,可以自行百度。。。共勉之。。。

    啰里啰嗦了半天。。。

     

    lua代码分析的,推荐我哥们的一篇文章:

    http://www.cnblogs.com/anxin1225/p/6151092.html

  • 相关阅读:
    codeforces_Codeforces Round #541 (Div. 2)_abc
    小米 OJ 编程比赛 01 月常规赛_灯_找规律
    codeforces_A. Salem and Sticks_数组/暴力
    航班座位_hihocoder
    canvas
    你所必须知道的HTML
    表单及表单新增元素
    HTML5新增的结构元素
    jQuery菜单,导航与标签页
    JavaScript的DOM对象
  • 原文地址:https://www.cnblogs.com/zhangfeitao/p/6742852.html
Copyright © 2011-2022 走看看