Linux工具学习

Posted Jocelin47

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux工具学习相关的知识,希望对你有一定的参考价值。

一、linux下性能调优工具OProfile和perf

OProfile 已经存在了几十年,有一段时间是在基于 Linux的系统上进行性能分析的主力军,今天也可以发挥同样的作用。但是,OProfile 不包含在 Red Hat Enterprise Linux (RHEL) 8 beta 中,因此 OProfile 用户开始考虑替代工具可能是谨慎的。在功能、易用性和社区活力方面与OProfile 相比非常有利的类似项目如perf命令。

OProfile 和perf当前在 Linux 内核中使用相同的基本机制来启用事件跟踪:perf_events 基础结构。虽然它主要是一个用户空间工具,perf但从开发的角度来看,该命令是 Linux 内核的一部分,作为 Linux 内核的一部分有优点也有缺点。一个可能的优势是代码更容易维护,因为代码库不会随着时间的推移而分崩离析。一个缺点是版本perf在很大程度上与 Linux 内核的版本有内在联系:获得新功能perf通常意味着获得新内核。

1.1 OProfile

1.1.1 OProfile介绍

OProfile是用于Linux的若干种评测和性能监控工具中的一种,它可以工作在不同的体系结构上,包括MIPS、ARM、IA32、IA64和AMD。
同时OProfile是Linux平台上的一个功能强大的性能分析工具,支持两种采样(sampling)方式:基于事件的采样(eventbased)和基于时间的采样(timebased)。

基于事件的采样是OProfile只记录特定事件(比如L2 cache miss)的发生次数,当达到用户设定的定值时OProfile就记录一下(采一个样)。这种方式需要CPU内部有性能计数器(performace counter)。

基于时间的采样是oProfile借助OS时钟中断的机制,每个时钟中断OProfile都会记录一次(采一次样),引入此种采样方式的目的在于提供对没有性能计数器的CPU的支持,其精度相对于基于事件的采样要低。因为要借助OS时钟中断的支持,对禁用中断的代码OProfile不能对其进行分析。

oProfile在Linux上分两部分,一个是内核模块(oprofile.ko),一个为用户空间的守护进程(oprofiled)。前者负责访问性能计数器或者注册基于时间采样的函数(使用register_timer_hook注册之,使时钟中断处理程序最后执行profile_tick时可以访问之),并采样置于内核的缓冲区内。后者在后台运行,负责从内核空间收集数据,写入文件。

1.1.2 安装OProfile

http://oprofile.sourceforge.net/download/

./configure make & sudo make install
  • ERROR1:configure:error:popt library not found

    下载popt-1.16,下载地址:https://www.linuxfromscratch.org/blfs/view/svn/general/popt.html

    ./configure make & sudo make install
    
  • ERROR2:configure:error: liberty library not found
    下载binutils-2.25,下载地址:http://ftp.gnu.org/gnu/binutils/?C=M;O=D

    ./configure make & sudo make install
    

1.3 使用OProfile

(1) OProfile使用流程

1. opcontrol --init
2. opcontrol --no-vmlinux
3. opcontrol --start
4. ./your_app
5. opcontrol --dump
6. opcontrol --stop
7. opreport -l ./your_app

(2) oprofile初始化

opcontrol --init

该命令会加载oprofile.ko模块,mount oprofilefs。成功后会在/dev/oprofile/目录下导出
一些文件和目录如: cpu_type, dump, enable, pointer_size, stats/

(3) 配置

主要设置计数事件和样本计数,以及计数的CPU模式(用户态、核心态)

opcontrol --vmlinux=/boot/vmlinux-`uname -r` # 监控内核及驱动模块
opcontrol --no-vmlinux # 不监控内核及驱动模块

设置计数事件为CYCLES,即对处理器时钟周期进行计数样本计数为1000,即每1000个时钟周期,oprofile 取样一次。处理器运行于核心态则不计数,运行于用户态则计数。

opcontrol --setup --event=CYCLES:1000::0:1

(4) 清除会话中的数据

opcontrol --reset # 清除当前会话中的数据

(5) oprofile启动监控

opcontrol --start
opcontrol --start-daemon;opcontrol --start # 轻量级,减少启动守护进程对测试结果的影响

(6) 运行测试程序

./test

(7) oprofile停止监控

运行完成后,停止oprofile数据的收集。

opcontrol --stop # 停止监控
opcontrol --shutdown # 停止监控,并结束监控进程(监控的数据默认保存在/var/lib/oprofile/samples)

(8) 查看报告

opreport -l # 如果需要保存信息,可以重定向到文件中,比如opreport -l > 1.txt

(9) 卸载模块

opcontrol --deinit  # 卸载模块

1.2 perf

1.2.1 perf介绍

Perf是Linux内核自带的系统性能优化工具,原理是:CPU的PMU registers(性能监控单元寄存器)中Get/Set performance counters来获得诸如instructions executed, cache-missed suffered, branches mispredicted(预测失准的分枝)等信息。

通过Perf,应用程序可以利用 PMU,tracepoint 和内核中的特殊计数器来进行性能统计。使用 perf可以分析程序运行期间发生的硬件事件,比如 cache miss等;也可以分析软件事件,比如 page fault 和进程切换。

1)PMU:性能监控单元(Performance Monitor Unit), CPU提供的一个性能监视单元,用于统计CPU性能数据;
2)Tracepoint:散落在内核源代码中的一些 hook,它们可以在特定的代码被运行到时被触发,这一特性可以被各种 trace/debug 工具所使用。
3)内核运行状态计数,例如: 1) 进程切换 2) Page fault 3) 中断计数

Perf的基本原理就是对被监测对象进行采样,在采样点里判断程序当时的上下文。假如一个程序 90% 的时间都花费在函数 foo() 上,那么 90% 的采样点都应该落在函数 foo() 的上下文中。运气不可捉摸,但若想只要采样频率足够高,采样时间足够长,那么以上推论就比较可靠。因此,通过 TIck 触发采样,我们便可以了解程序中哪些地方最耗时间,从而重点分析。

Perf是运行在用户态,它通过RingBuffer数据结构(覆盖方式)与内核态进行交互,每次woken up的时候就是在读RingBuffer中的数据

Perf的使用流程和OProfile很像。所以如果你会用OProfile的话,用Perf就很简单。

1.2.2 安装perf

sudo apt install linux-tools-common

sudo apt install linux-tools-5.4.0-58-generic
sudo apt install linux-cloud-tools-5.4.0-58-generic

1.2.3 使用perf

(1) Perf事件处理常用的参数:

record : 记录到文件perf.data
report: 读取perf.data并以CUI方式展示
stat :统计事件个数
script:脚本自定义处理
trace : live输出事件(strace) ==> (比ptrace更高效的机制)
probe :自定义软件事件
top:类似top命令
list :列出事件
perf record后会将数据保存到perf.data中

perf stat 不会收集数据,只是展示出来通用事件

(2) 实例代码


#include<stdio.h>

 void longa() 
  
   int i,j; 
   for(i = 0; i < 1000000; i++) 
   j=i; //am I silly or crazy? I feel boring and desperate. 
  
 
 void foo2() 
  
   int i; 
   for(i=0 ; i < 10; i++) 
        longa(); 
  
 
 void foo1() 
  
   int i; 
   for(i = 0; i< 100; i++) 
      longa(); 
  
 
 int main(void) 
  
   foo1(); 
   foo2(); 
   return 0;
 

(3) record 记录到perf.data文件

gcc -o test -g test.c 

带上-g选项,加入调试和符号表信息。

sudo perf record -e cycles ./test

带上-e cycles可以不加默认是给我们加上的

perf唤醒内核1次去写(通过信号),与内核交互的ringbuffer交互次数为1次。

perf report


进入可以看到函数的用时占比

(4) stat统计事件个数

sudo perf stat ./test

将通用的事件展示出来

Performance counter stats for './test':

            403.33 msec task-clock                #    0.985 CPUs utilized          
                20      context-switches          #    0.050 K/sec                  
                 0      cpu-migrations            #    0.000 K/sec                  
                45      page-faults               #    0.112 K/sec                  
   <not supported>      cycles                                                      
   <not supported>      instructions                                                
   <not supported>      branches                                                    
   <not supported>      branch-misses                                               

       0.409406795 seconds time elapsed

       0.380006000 seconds user
       0.024000000 seconds sys

(5) probe自定义软件事件

在test中加入一个probe,在longa函数上。可以统计调用longa调用的次数

sudo perf probe -x ./test longa

sudo perf record -e probe_test:longa ./test

此时的事件-e就不是cycles了,指定的是probe_test

sudo perf report

可以看到有110个事件

也可以通过-d参数删除事件

sudo perf probe -d longa # 删除这个事件,才能再次运行

(6) script 查看调用详细的次数

sudo perf script # 可以看到调用输出的次数

可以看到函数调用的次数。

sudo perf stat -e probe_test:longa ./test

在使用前面用的stat命令,可以看到直接输出了调用次数

二、/proc/cpuinfo文件使用

2.1 /proc/cpuinfo涉及的内容介绍

在linux系统中,提供了/proc目录下文件,显示系统的软硬件信息。如果想了解系统中CPU的提供商和相关配置信息,则可以查/proc/cpuinfo。但是此文件输出项较多,不易理解。例如我们想获取,有多少颗物理CPU,每个物理cpu核心数,以及超线程是否开启等信息。

使用cat /proc/cpuinfo可以查看到cpu的信息:

processor	: 0
vendor_id	: GenuineIntel
cpu family	: 6
model		: 61
model name	: Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz
stepping	: 4
microcode	: 0x2d
cpu MHz		: 2196.822
cache size	: 3072 KB
physical id	: 0
siblings	: 2
core id		: 0
cpu cores	: 2
apicid		: 0
initial apicid	: 0
fpu		: yes
fpu_exception	: yes
cpuid level	: 20
wp		: yes
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc cpuid pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti ssbd ibrs ibpb stibp fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid rdseed adx smap xsaveopt arat md_clear flush_l1d arch_capabilities
bugs		: cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit srbds
bogomips	: 4393.64
clflush size	: 64
cache_alignment	: 64
address sizes	: 43 bits physical, 48 bits virtual
power management:

其中关键字表示的意思如下:

processor :系统中逻辑处理核心数的编号,从0开始排序。

vendor_id :CPU制造商

cpu family :CPU产品系列代号

model   :CPU属于其系列中的哪一代的代号

model name:CPU属于的名字及其编号、标称主频

stepping  :CPU属于制作更新版本

cpu MHz  :CPU的实际使用主频

cache size :CPU二级缓存大小

physical id :单个物理CPU的标号

siblings :单个物理CPU的逻辑CPU数。siblings=cpu cores [*2]。

core id :当前物理核在其所处CPU中的编号,这个编号不一定连续。

cpu cores :该逻辑核所处CPU的物理核数。比如此处cpu cores 是4个,那么对应core id 可能是 1、3、4、5。

apicid :用来区分不同逻辑核的编号,系统中每个逻辑核的此编号必然不同,此编号不一定连续

fpu :是否具有浮点运算单元(Floating Point Unit)

fpu_exception :是否支持浮点计算异常

cpuid level :执行cpuid指令前,eax寄存器中的值,根据不同的值cpuid指令会返回不同的内容

wp :表明当前CPU是否在内核态支持对用户空间的写保护(Write Protection)

flags :当前CPU支持的功能

bogomips:在系统内核启动时粗略测算的CPU速度(Million Instructions Per Second

clflush size :每次刷新缓存的大小单位

cache_alignment :缓存地址对齐单位

address sizes :可访问地址空间位数

power management :对能源管理的支持

2.2 快速的查看具体的内容

  • 查询系统有几颗物理CPU:

    cat  /proc/cpuinfo | grep "physical id" |sort |uniq
    
  • 查询系统每颗物理CPU的核心数

    cat /proc/cpuinfo | grep "cpu cores" | uniq
    
  • 查询系统的每颗物理CPU核心是否启用超线程技术。

    如果启用此技术那么,每个物理核心又可分为两个逻辑处理器。

    cat /proc/cpuinfo | grep -e "cpu cores"  -e "siblings" | sort | uniq
    

    如果cpu cores数量和siblings数量一致,则没有启用超线程,否则超线程被启用。

  • 查询系统具有多少个逻辑CPU

    cat /proc/cpuinfo | grep "processor" | wc -l
    

三、Top工具使用

3.1 top命令介绍

top 命令是 Linux 系统下常用的系统监控工具,通过 top 命令我们可以获取到系统动态运行的信息,包括内存使用情况,系统负载情况,进程的运行情况等等。

3.2 top命令用法

使用top命令后,可以在界面进行交互操作,参数h可以看到帮助命令

-d:number代表秒数,表示top命令显示的页面更新一次的间隔。默认是5秒。要手动刷新,用户可以输入回车或者空格

-b:以批次的方式执行top。
-n:与-b配合使用,表示需要进行几次top命令的输出结果,到达指定次数后 top 退出

top 命令的批处理模式(Batch-mode)可以区别于正常使用的交互模式(Interactive-mode),在批处理模式下top 只会不断打印系统状态,无法接受其他交互模式下的命令。如果配合-n 选项指定刷新次数的话,可以通过批处理模式将系统状态不断打印到日志中,实现实时监控的效果。

-p:指定特定的pid进程号进行观察。

-u: user 只显示指定用户启动的进程
示例: top -u root(只显示以root用户启动的进程)

-B:重要内容加粗

-H:切换到线程状态

-k:结束指定进程

-m:切换内存使用量的显示样式

-e:调整内存的计量单位

F:命令指定字段过滤

通过选中MEM字段右移调序到CPU上面后,优先以MEM排序;
通过空格可以选择是否显示该字段

-c:切换是否显示进程启动时的完整路径和程序名。

-o:命令执行过滤
命令的格式如下:

<!> <字段名称> <操作符> <包含值/排除值>

支持>,<,=这三类操作符

例子:显示PID>100的可以使用PID>100或者!PID<100
通过COMMAND=top,可以查看到top进程

使用 Ctrl+o 显示当前生效的过滤器
使用 =重置当前窗口的过滤器
使用 +重置全部窗口的过滤器

3.3 top界面参数说明

3.3.1 top前五行信息说明

top - 22:33:04 up 2 min,  1 users,  load average: 0.85, 0.62, 0.25
Tasks: 155 total,   2 running, 153 sleeping,   0 stopped,   0 zombie
%Cpu(s):  3.4 us,  1.4 sy,  0.0 ni, 95.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  2967536 total,  2249804 free,   303732 used,   414000 buff/cache
KiB Swap:  4194300 total,  4194300 free,        0 used.  2509432 avail Mem 

前五行是系统整体的统计信息。
第一行是任务队列信息,同 uptime 命令的执行结果。含义如下:

22:39:11当前时间
up 8 min系统运行时间
1 user当前登录用户数
load average: 0.00, 0.17, 0.16系统负载,即任务队列的平均长度。 三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。top - 22:33:04 up 2 min, 2 users, load average: 0.85, 0.62, 0.25

第二、三行为进程和CPU的信息。当有多个CPU时,这些内容可能会超过两行。
第二行内容及含义如下:

Tasks: 155 total,   2 running, 153 sleeping,   0 stopped,   0 zombie
内容含义
total进程总数
running正在运行的进程数
sleeping睡眠的进程数
stopped停止的进程数
zombie僵尸进程数

第三行内容及含义如下:(可以按1查看所有CPU的信息)

%Cpu(s):  3.4 us,  1.4 sy,  0.0 ni, 95.2 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
内容含义
us用户空间占用CPU百分比
sy内核空间占用CPU百分比
ni用户进程空间内改变过优先级的进程占用CPU百分比
id空闲CPU百分比
wa等待输入输出的CPU时间百分比
hi硬中断(Hardware IRQ)占用CPU的百分比
si软中断(Software Interrupts)占用CPU的百分比
st(Steal time) 是当 hypervisor 服务另一个虚拟处理器的时候,虚拟 CPU 等待实际 CPU 的时间的百分比。

最后两行为内存信息。
第四行的内容及含义如下:

KiB Mem :  2967536 total,  2249804 free,   303732 used,   414000 buff/cache
内容含义
KiB Mem使用的物理内存总量
used使用的内存总量
buff/cache用作内核缓存的内存量

第五行的内容及含义如下:

KiB Swap:  4194300 total,  4194300 free,        0 used.  2509432 avail Mem
内容含义
KiB Swap交换区总量
avail Mem代表可用于进程下一次分配的物理内存数量

上表中的缓冲交换区总量含义为:内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,该数值即为这些内容已存在于内存中的交换区的大小。相应的内存再次被换出时可不必再对交换区写入

3.3.2 进程信息说明

列名含义
PID进程id
PPID父进程id
RUSERReal user name
UID进程所有者的用户id
USER进程所有者的用户名
GROUP进程所有者的组名
TTY启动进程的终端名。不是从终端启动的进程则显示为 ?
PR优先级
NInice值,负值表示高优先级,正值表示低优先级
P最后使用的CPU,仅在多CPU环境下有意义
%CPU上次更新到现在的CPU时间占用百分比
TIME进程使用的CPU时间总计,单位秒
TIME+进程使用的CPU时间总计,单位1/100秒
%MEN进程使用的物理内存百分比
VIRT进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
SWAP进程使用的虚拟内存中,被换出的大小,单位kb
RES进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
CODE可执行代码占用的物理内存大小,单位kb
DATA可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
SHR共享内存大小,单位kb
nFLT页面错误次数
nDRT最后一次写入到现在,被修改过的页面数。
S进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
COMMAND命令名/命令行
WCHAN若该进程在睡眠,则显示睡眠中的系统函数名
Flags任务标志

参考链接:

  • OProfile
    https://www.jianshu.com/p/a5f28ccff7cd
  • perf
    https://developer.ibm.com/tutorials/migrate-from-oprofile-to-perf/
    性能分析工具Linux perf使用经验
  • /cpu/info
    http://t.zoukankan.com/wxxjianchi-p-10522049.html
  • top
    https://blog.csdn.net/Luckiers/article/details/123909819

以上是关于Linux工具学习的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核版本代号

活动排序工具之双代号网络(AOA)与单代号网络(AON)[cont.]

如何查看linux系统版本

代号一:带图像的样式工具栏

将按钮添加到代号一工具栏

你知道用Woof创建的Linux吗?