热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

嵌入式Linux系统性能提升的关键切入点与优化策略

在嵌入式Linux系统中,性能低下通常由CPU、内存和I/O三个关键因素引起。为了有效提升系统性能,首先需要识别并定位性能瓶颈。通过综合分析这些瓶颈,可以采取针对性的优化措施,如调整内核参数、优化算法和改进数据结构等,从而显著提高系统的整体性能。

   系统软件性能低下的问题,主要与三种因数有关:CPU、内存、IO。
   如何优化系统的性能?
   第一步,找出系统性能的瓶颈。
(1)程序的运算量很大,CPU过于繁忙,CPU是瓶颈。
    可以通过top命令观察CPU的利用率情况。
(2)过多或过于频繁的读写文件、内存等I/O操作,CPU更多的是处于等待,(存储设备、网络设备、异步IO)等I/O操作是性能瓶颈。
(3)内存不够。物理内存不够时会使用交换内存, 使用交换内存会带来磁盘IO和CPU的开销增加.交换空间是专门用于临时存储内存的一块磁盘空间,通常在页面调度和交换进程数据时使用.调页算法是将内存中最近不常使用的页面换到磁盘上,把常使用的页面(活动页面)保留在内存中供进程使用。当程序运行需要的内存大于物理内存时,linux系统采用了调页机制,即系统copy一些内存中的页面到磁盘上,腾出来空间供进程使用。
大多数系统可以忍受偶尔的调页,但是频繁的调页会使系统性能急剧下降。

  (4) 带宽。如网络带宽、系统总线带宽等

(5)文件系统性能(大文件优化、小文件优化、写优化、读优化、网络文件系统)。

  (6) 多线程性能

 

   一些经验:

1.   小文件读写的性能瓶颈是磁盘的寻址(随机读写性能更差),评估的标准是tps

2.   大文件读写的性能瓶颈是带宽,评估的标准是持续的读写速度

3.   Linux可以利用空闲内存作文件系统访问的cache,因此系统内存越大存储系统的性能也越好

 

   第二步,着手进行优化

1.堆内存和数据段内存的优化:

   malloc一般会实现一个内存堆来管理这些内存,malloc分配的内存都会以若干chunk的方式放到内存堆中。每次用户调用malloc动态分配内存的时候,malloc会先到内存堆里进行查找,如果内存堆里没有合适的空闲chunk,再利用brk/malloc系统调用分配一大块内存,然后把新分配的大块内存放到内存堆中,并生成一块合适的chunk块返回给用户。
   


当用户用free释放chunk的时候,可能并不立即使用系统调用释放内存,而是将释放的chunk作为空闲chunk加入内存堆中,和其他的空闲chunk合并,便于下次分配的时候再次使用。
   
   一般说来,释放的chunk如果标记为mmap申请的,则使用munmap释放。如果是brk申请的,进一步判断堆顶之下的空闲chunk是否大于128KB,如果是,则使用brk()释放。如果小于128KB,仍由内存堆维护。这样对brk()的使用就会有个问题,当brk()释放的内存块在堆顶之下,且内存块到堆顶之间还有未释放的内存。那么这块内存的释放将不会成功,从而形成内存空洞。 

glibc管理的内存唯一释放的条件是堆顶存在128k(M_TRIM_THRESHOLD)或以上的空闲区时才会释放.这样就会形成内存空洞。

内存空洞:当存在内存空洞时,它会从空洞中分配,并不会导致内存使用的增加;

内存泄露:当libc收到内存分配请求时,只能占用更多内存。

针对大块内存的申请和释放不会导致内存空洞的形成。

 

堆内存的优化:

(1)glibc管理的内存绝大多数情况下不会释放。
     因此编程时如果是小内存分配要尽快使用,尽快用完,尽快释放(变成空闲chunk),不要停留,否则一直摞着,线性地址后面的就形成了空洞。


(2)如果是想内存总在控制中,可以分配大内存,自行管理释放和分配。不用的时候可以释放地很干净
(3)不要分配很小的内存比如几个字节,因为一次malloc至少分配16个字节,如果每次分配都很小,就太亏了。
所以尽量减少小块内存的申请,避免内存浪费。

(4)降低M_MMAP_THRESHOLD,可以让更多的分配走mmap,避免brk的种种问题,特别是64位机器的情况下。
(5)降低M_TRIM_THRESOLD,让堆顶的空闲内存更容易释放。

   以上(4)(5)都不可避免会增加系统调用的机会,使用中需要慎重。

 

数据段内存的优化:

(1)将只读的全局变量,加上const,从而使其转移到代码段;

(2)去除不必要的全局变量;

(3)减少全局变量的尺寸;

可以通过nm,查找到所有在数据段的符号,从而想办法修改它。

 

动态库的使用:

(1)静态加载:无法按需动态卸载动态库

(2)dlopen:可按需卸载动态库,从而节省了内存,但程序在启动时,需要查找定位代码,从而会降低性能。

 

代码优化的一些经验:

(1)运算处理优化:简化数学表达式、用移位运算代替乘除运算、乘法运算比除运算快、使用增量和减量运算符等;

(2)算法优化:根据发生频率对switch语句进行排列、将大的switch语句简化为嵌套switch语句等、用指针取代数组、使用宏函数取代函数。



推荐阅读
author-avatar
高玉成
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有