第一阶段:《嵌入式内存使用和性能优化》
第二阶段:《Systems Performance》(性能之巅)
https://www.cnblogs.com/arnoldlu/p/6874328.html#performance_optimization_method
整个对于Linux代码的优化,应该区分为从整个层面的系统优化,和从模块角度的算法性能优化。最终追寻的优化是原来原理层面的追寻。Linux系统的优化也是,属于系统层面的优化。针对特定的场景要求根据优先级做出取舍关系。
1、系统内存的测量:free用以获得当前系统内存的使用情况。
查看缓存的命令
free -m
清理缓存的命令
echo 1 > /proc/sys/vm/drop_caches
echo 2 > /proc/sys/vm/drop_caches
echo 3 > /proc/sys/vm/drop_caches
2、进程的内存测量
在进程的proc中与内存有关的节点有statm、maps、memmap。
cat /proc/PID(进程号)/statm
cat /proc/PID(进程号)/maps
对于Linux系统内存的回收有一套默认的配置参数,但是对于内存性能较差的设备,我们有时候需要优化该配置。
其主要参数,主要包括上文说的手动清空缓存的drop_caches,也包括min_free_kbytes参数等等
参数 | 说明 | 备注 | |
保证linux有足够的物理内存,可以调整vm的如下参数 | vm.min_free_kbytes | 默认值是3797,保证物理内存有足够空闲空间,防止突发性换页。 如果设置的值小于1024KB,系统很容易崩溃,在负载较高时很容易死锁。如果设置的值太大,系统会经常OOM。 | |
vm.vfs_cache_pressure | 默认是100,增大这个参数设置了虚拟内存回收directory和i-node缓冲的倾向,这个值越大。越易回收 | ||
vm.swappiness | 缺省60,减少这个参数会使系统尽快通过swapout不使用的进程资源来释放更多的物理内存 |
||
改善io系统的性能 | vm.overcommit_memory | 默认值为:0从内核文档里得知,该参数有三个值,分别是:0:当用户空间请求更多的的内存时,内核尝试估算出剩余可用的内存。 1:当设这个参数值为1时,内核允许超量使用内存直到用完为止,主要用于科学计算 2:当设这个参数值为2时,内核会使用一个决不过量使用内存的算法,即系统整个内存地址空间不能超过swap+50%的RAM值,50%参数的设定是在overcommit_ratio中设定。 |
|
vm.overcommit_ratio | 默认值是50,用于虚拟内存的物理内存的百分比。这个参数值只有在vm.overcommit_memory=2的情况下,这个参数才会生效。该值为物理内存比率,当overcommit_memory=2时,进程可使用的swap空间不可超过PM * overcommit_ratio/100 | ||
vm.dirty_ratio | 默认值是40,为了保持稳定,持续的写入,把这个值调整的小一些,经验值是20。增大会使用更多系统内存用于缓冲,可以提高系统的读写性能。当需要持续、恒定的写入场合时,应该降低该数值。 | ||
vm.dirty_background_ratio | 缺省数值是500,也就是5秒,如果系统要求稳定持续的写,可以适当降低该值,把峰值的写操作平均多次,也避免宕机丢失更多的数据 | ||
vm.dirty_expire_centisecs | 缺省是3000,也就是30秒,如果系统写操作压力很大,可以适当减小该值,但也不要太小;建议设置为 1500 | ||
参数作用的介绍(https://blog.csdn.net/jiajiren11/article/details/78822171)
参数使用的介绍(https://blog.csdn.net/wyzxg/article/details/5661489)
vm的相关参数在/proc/sys目录下,相关命令
sysctl -p //修改vm参数后,运行这个命令可以立即生效
sysctl -a //查看所有的vm参数
1.执行文件所占用的内存
2.动态库对内存的影响
3.线程对内存的影响
https://www.cnblogs.com/arnoldlu/p/6874328.html
https://blog.csdn.net/hixiaoxiaoniao/article/details/85982350
性能优化也就是下面的几个策略:
总之,根据2:8原则来说,20%的代码耗了你80%的性能,找到那20%的代码,你就可以优化那80%的性能。
1、算法调优。
过滤算法、哈希算法、分而治之和预处理。
2、代码调优
字符串操作:能用整型最好用整型。
多线程调优:线程不是越多越好,线程间的调度和上下文切换也是很夸张的事,尽可能的在一个线程里干,尽可能的不要同步线程。这会让你有很多的性能。
内存分配:不要小看程序的内存分配。malloc/realloc/calloc这样的系统调非常耗时,尤其是当内存出现碎片的时候。
异步操作:我们知道Unix下的文件操作是有block和non-block的方式的,像有些系统调用也是block式的,如:Socket下的select,Windows下的WaitforObject之类的,如果我们的程序是同步操作,那么会非常影响性能,我们可以改成异步的,但是改成异步的方式会让你的程序变复杂。异步方式一般要通过队列,要注间队列的性能问题,另外,异步下的状态通知通常是个问题,比如消息事件通知方式,有callback方式,等,这些方式同样可能会影响你的性能。但是通常来说,异步操作会让性能的吞吐率有很大提升(Throughput),但是会牺牲系统的响应时间(latency)。这需要业务上支持。
语言和代码库:
参考网址:
http://www.bubuko.com/infodetail-981218.html
LINUX | 描述 | 备注 |
uptime | 平均负载 | |
vmstate | 包括系统范围的CPU平均负载 | |
mpstate | 单个CPU的统计信息 | |
sar | 历史统计信息 | |
ps | 进程状态 | |
top | 监控每个进程/线程CPU用量 | |
pidstat | 每个进程/线程CPU用量分解 | |
time | 给一个命令计时,带CPU用量分解 | |
DTrace, perf | CPU剖析和跟踪 | |
perf | CPU性能计数器分析 |
oProfile是Linux平台上的一个功能强大的性能分析工具,支持两种采样(sampling)方式:基于事件的采样(eventbased)和基于时间的采样(timebased),它可以工作在不同的体系结构上,包括MIPS、ARM、IA32、IA64和AMD。
cpu无端占用高?应用程序响应慢?苦于没有分析的工具?
oprofile利用cpu硬件层面提供的性能计数器(performance counter),通过计数采样,帮助我们从进程、函数、代码层面找出占用cpu的"罪魁祸首"。下面我们通过实例,了解oprofile的具体使用方法。
常用命令
使用oprofile进行cpu使用情况检测,需要经过初始化、启动检测、导出检测数据、查看检测结果等步骤,以下为常用的oprofile命令。
初始化
检测控制
查看检测结果
参考网址:
https://www.cnblogs.com/274914765qq/p/4976415.html
https://www.cnblogs.com/bangerlee/archive/2012/08/30/2659435.html
Perf是内置于Linux内核源码树中的性能剖析工具。它基于事件采样原理,以性能事件为基础,支持针对处理器相关性能指标与操作系统相关性能指标的性能剖析。可用于性能瓶颈的查找与热点代码的定位。
参考网址:
https://blog.csdn.net/kelsel/article/details/52758229
如果代码设计的不够合理,如代码的内存非连续,那么内存访问不在高速缓存中,那么频繁的去DDR处读取数据将导致内存的访问浪费大量的时间,从而最终造成CPU占比升高。(cache miss)
虽然内核已经有较好的内存访问缓存机制,但是如果我们的代码设计的不合理,将会导致设备性能运行变慢。
参考地址:
https://www.jianshu.com/p/8a72f1fede21
ifconfig
TCP调优:TCP链接是有很多开销的,一个是会占用文件描述符,另一个是会开缓存,一般来说一个系统可以支持的TCP链接数是有限的,我们需要清楚地认识到TCP链接对系统的开销是很大的。注意配置KeepAlive参数,这个参数的意思是定义一个时间,如果链接上没有数据传输,系统会在这个时间发一个包,如果没有收到回应,那么TCP就认为链接断了,然后就会把链接关闭,这样可以回收系统资源开销。
UDP调优:UDP的调优,有一些事我想重点说一样,那就是MTU——最大传输单元。
网卡调优
其它网络性能:多路复用技术,也就是用一个线程来管理所有的TCP链接,有三个系统调用要重点注意:一个是select,这个系统调用只支持上限1024个链接,第二个是poll,其可以突破1024的限制,但是select和poll本质上是使用的轮询机制,轮询机制在链接多的时候性能很差,因主是O(n)的算法,所以,epoll出现了,epoll是操作系统内核支持的,仅当在链接活跃时,操作系统才会callback,这是由操作系统通知触发的,但其只有Linux Kernel 2.6以后才支持(准确说是2.5.44中引入的),当然,如果所有的链接都是活跃的,过多的使用epoll_ctl可能会比轮询的方式还影响性能,不过影响的不大。