您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 企业文化 > 嵌入式linux 性能优化
飞翔Email:loughsky@sina.comblog:嵌入式Linux性能优化2飞翔Email:loughsky@sina.comblog:嵌入式Linux性能优化•性能评价•性能优化的流程•性能评测•优化的基本原则•Shell脚本优化•C和C++程序优化3飞翔Email:loughsky@sina.comblog:性能评价•如何定义快和慢?–快和慢与个人感官密切相关,有的人认为快,有的人认为慢,我们需要在整个开发过程中参与的人员有一个共同的标准。•为每一个用户的操作,定义具体的时间值–一般精度在1/10秒–为一个设备所定义的性能指标,可能达到几十个。2000010000关机3000021000开机版本2版本1下限理想性能4飞翔Email:loughsky@sina.comblog:性能优化的流程•性能优化是一个不断迭代的过程,不要认为一蹴而就。5飞翔Email:loughsky@sina.comblog:性能的评测•摄像头方式(测试人员使用居多)–优点:•使用起来非常简单,不需要熟悉代码。•更加接近用户实际的感受。–缺点:•时间的精确度受摄像头拍摄帧数的限制,一般精度不高,误差在100ms左右。•代码中增加log(开发人员使用居多)–优点:•测试时间的精确度将更高,能够精确到1ms左右。•能够灵活的定位代码中各个部分所占用的时间。–缺点:•在代码中增加时间的log,需要对代码非常的熟悉。•从log中得出的时间,往往因为各种意外情况的出现,往往会与用户的实际感受不一致。6飞翔Email:loughsky@sina.comblog:性能分析•导致程序运行效率低下,主要有下面3种原因:–程序的运算量很大,导致CPU过于繁忙,CPU是瓶颈。–程序需要做大量的I/O,读写文件、内存操作等等,CPU更多的是处于等待,I/O部分称为程序性能的瓶颈。–程序之间相互等待,结果CPU利用率很低,但运行速度依然很慢,事务间的共享与死锁制约了程序的性能。7飞翔Email:loughsky@sina.comblog:性能分析•对于大量IO操作所引起的性能问题,我们可以考虑使用异步IO方式来提高程序性能。推荐一篇文章:•后面所有的内容,主要针对程序量大,CPU是瓶颈的问题。8飞翔Email:loughsky@sina.comblog:优化的原则•等效原则:优化前后程序实现的功能一致。•有效原则:优化后要比优化前运行速度快或占用存储空间小,或二者兼有。•经济原则:优化程序要付出较小的代价,取得较好的结果。9飞翔Email:loughsky@sina.comblog:脚本优化•在Linux系统中,我们会经常使用到shell脚本,我这里只介绍由busybox实现shell引擎的脚本优化。•在busybox中,命令分为三种类型:–APPLET:也即我们所说的applets,它由busybox创建一个fork出一个子进程,然后调用exec执行相应的功能,待执行完毕后,返还控制给父进程。–APPLET_NOEXEC:系统将调用fork创建子进程,然后执行busybox中对应的功能,在执行完毕后,返回控制给父进程。–APPLET_NOFORK:它相当于builts-in,只是执行busybox的内部函数,不必创建子进程,所以其效率昀高。10飞翔Email:loughsky@sina.comblog:脚本优化•在Linux中调用fork、exec是很花时间的,所以我们应该使用APPLET_NOFORK命令,其次是APPLET_NOEXEC,昀后APPLET。•在busybox1.9中,属于APPLET_NOFORK的功能有:[basenamecatdirnameechofalsehostidlengthlognamemkdirpwdrmrmdirseqsleepsynctouchtrueusleepwhoamiyes•属于APPLET_NOEXEC的功能有:awkchgrpchmodchowncpcutddfindhexdumplnsorttestxargs例如:printf“helloworld\n”echo“helloworld\n”11飞翔Email:loughsky@sina.comblog:脚本优化•在bash脚本中命令,还有一些特殊的约定:–包含在pipe中的builts-in将被创建子进程来执行。–包含在`的命令将创建子进程来执行。•优化busyboxbash脚本–去掉无用的脚本–尽可能使用busybox内部实现的命令–尽量不要使用pipe–减少pipe中的命令数–尽量不要使用`我们可以参考:。12飞翔Email:loughsky@sina.comblog:进程启动速度•查看进程启动速度–#strace-tt./hello23:31:02.618348execve(./hello,[./hello],[/*9vars*/])=023:31:02.624391uname({sys=Linux,node=(none),...})=023:31:02.628785brk(0)=0x1100023:31:02.631655access(/etc/ld.so.preload,R_OK)=-1ENOENT(Nosuchfileordirectory)23:31:02.634035open(/etc/ld.so.cache,O_RDONLY)=-1ENOENT(Nosuchfileordirectory)23:31:02.636079open(/lib/tls/v6l/libc.so.6,O_RDONLY)=-1ENOENT(Nosuchfileordirectory)…….……23:31:02.664339close(3)=023:31:02.667817mprotect(0x412b8000,4096,PROT_READ)=023:31:02.670321fstat64(1,{st_mode=S_IFCHR|0600,st_rdev=makedev(136,1),...})=023:31:02.672884mmap2(NULL,4096,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0)=0x4000000013飞翔Email:loughsky@sina.comblog:进程启动速度•查看进程启动过程–#LD_DEBUG=libs./hello432:findlibrary=libc.so.6;searching432:searchcache=/etc/ld.so.cache432:searchpath=/lib/tls/v6l:/lib/tls:/lib/v6l:/lib:/usr/lib/tls/v6l:/usr/lib/tls:/usr/lib/v6l:/usr/lib(systemsearchpath)…………432:tryingfile=/lib/libc.so.6432:callinginit:/lib/libc.so.6432:initializeprogram:./hello432:transferringcontrol:./hello–#LD_DEBUG=help./helloValidoptionsfortheLD_DEBUGenvironmentvariableare:libsdisplaylibrarysearchpathsrelocdisplayrelocationprocessingfilesdisplayprogressforinputfile……….–helpdisplaythishelpmessageandexit14飞翔Email:loughsky@sina.comblog:进程启动速度•进程启动过程–搜索其所依赖的动态库。–加载动态库–初始化动态库–初始化进程–将程序的控制权,移交给main函数。15飞翔Email:loughsky@sina.comblog:进程启动速度•减少加载动态库的数量–使用dlopen,将启动时不需要的动态库,延后加载–将一些动态库,改为静态库•优点:–减少了加载动态库的数量。–在与其他动态库(或进程)合并之后,动态库内部之间的函数调用不必再进行动态链接、符号查找,从而提高速度。•缺点:–该动态库如果被多个动态库或进程所依赖的话,那么该动态库将被复制多份合并到新的动态库中,导致整体的文件大小增加,占用更多的flash。–失去了动态库原有的代码段内存共享,因此可能会导致内存使用上的增加。16飞翔Email:loughsky@sina.comblog:进程启动速度•加载动态库时的搜索路径:–HWCAP机制–DT_NEED入口中包含的路径–DT_RPATH入口给出的路径(存在的话)–环境变量LD_LIBRARY_PATH路径(setuid类的程序排除)–LD_RUNPATH入口给出的路径(存在的话)–库高速缓存文件ld.so.conf中给出的路径–/lib/usr/lib17飞翔Email:loughsky@sina.comblog:进程启动速度•HWCAP机制–在各个不同的系统种,系统的硬件功能是不一致的,有的系统支持浮点运算,有的则不支持。这样,由于系统硬件功能的不同,软件需要加载不同的共享库,glibc的HWCAP就是为了这个功能所设计的。根据不同的硬件特性,到不同的目录去搜索动态库,来实现前面提到的需求。•禁止HWCAP–#exportLD_HWCAP_MASK=0x0000000018飞翔Email:loughsky@sina.comblog:进程启动速度•优化动态库搜索路径–设置LD_HWCAP_MASK,禁掉一些不用的硬件特性。–将所有的动态库都放在一个目录下,并将该目录放在LD_LIBRARY_PATH的开始。–不能放在一个目录的,在进程中加入-rpath选项,指定搜索路径。19飞翔Email:loughsky@sina.comblog:进程启动速度•动态库的初始化–动态库的构造和析构函数机制。–动态库的全局变量初始化工作。20飞翔Email:loughsky@sina.comblog:
本文标题:嵌入式linux 性能优化
链接地址:https://www.777doc.com/doc-4805455 .html