《性能之巅:洞悉系统、企业与云计算》-观测工具-笔记

news2024/10/26 10:36:30

《性能之巅:洞悉系统、企业与云计算》第一章(绪论)和第二章(方法)的笔记,请参考Part 1,第三章(操作系统)的笔记,请参考Part 2,本文是第四章——观测工具。

在实践中,工具不能覆盖所有方面,系统性能专家利用推论和解释:用间接的工具和统计来弄清楚系统的活动。

工具类型

工具的一种分类:
在这里插入图片描述
有些工具不止适合一个象限,top(1)有一个系统级别的视图,DTrace也有进程级别的能力。还有一些性能工具是基于剖析(profiling)的,对系统或进程做一系列快照,以此来进行观测。

计数器

内核维护各种统计数据,称为计数器,用于对事件计数。计数器的使用可认为是零开销的,因为它们默认就是开启的,而且始终由内核维护。唯一的使用开销是从用户空间读取它们的时候(可忽略不计)。

系统级别工具:

  • vmstat:虚拟内存和物理内存的统计,系统级别;
  • mpstat:每个CPU的使用情况;
  • iostat:每个磁盘I/O的使用情况,由块设备接口报告;
  • netstat:网络接口的统计,TCP/IP栈的统计,以及每个连接的一些统计信息;
  • sar:各种各样的统计,能归档历史数据。

进程级别工具:

  • ps:进程状态,显示进程的各种统计信息,包括内存和CPU;
  • top:按一个统计数据(如CPU使用)排序,显示排名高的进程。基于Solaris的系统对应的工具是prstat(1M)
  • pmap:将进程的内存段和使用统计一起列出。

进程工具以进程为导向,使用内核为每个进程维护的计数器,从/proc目录读取统计信息。

跟踪

跟踪收集每一个事件的数据以供分析。跟踪框架一般默认是不启用的,因为跟踪捕获数据会有CPU开销,另外还需要不小的存储空间来存放数据。这些开销会拖慢所跟踪的对象,在解释测量时间时需要加以考虑。

日志,包括系统日志,可以认为是一种默认开启的低频率跟踪。日志包括每一个事件的数据,虽然通常只针对偶发事件,如错误和警告。

系统级别工具:

  • tcpdump:网络包跟踪(用libpcap库);
  • snoop:为基于Solaris的系统打造的网络包跟踪工具;
  • blktrace:块I/O跟踪(Linux);
  • iosnoop:块I/O跟踪(基于DTrace);
  • execsnoop:跟踪新进程(基于DTrace);
  • dtruss:系统级别的系统调用缓冲跟踪(基于DTrace);
  • DTrace:跟踪内核的内部活动和所有资源的使用情况(不仅仅是网络和块I/O),支持静态和动态的跟踪;
  • SystemTap:跟踪内核的内部活动和所有资源的使用情况,支持静态和动态的跟踪;
  • perf:Linux性能事件,跟踪静态和动态的探针。

进程级别工具:

  • strace:基于Linux系统的系统调用跟踪;
  • truss:基于Solaris系统的系统调用跟踪;
  • gdb:源代码级别的调试器,广泛应用于Linux系统;
  • mdb:Solaris系统的一个具有可扩展性的调试器。

剖析

剖析,profiling,通过对目标收集采样或快照来归纳目标特征。剖析工具,剖析器profiler,有时会稍微改变这一频率,避免采样与目标活动同一步调,因为这样可能会导致多算或少算。

基于时间+硬件缓存的剖析器:

  • oprofile:Linux系统剖析;
  • perf:Linux性能工具集,包含有剖析的子命令;
  • DTrace:程序化剖析,基于时间的剖析用自身的profile provider,基于硬件事件的剖析用cpc provider;
  • SystemTap:程序化剖析,基于时间的剖析用自身的timer tapset,基于硬件事件的剖析用自身perf tapset;
  • cachegrind:源自valgrind工具集,能对硬件缓存的使用做剖析,也能用kcachegrind做数据可视化;
  • Intel VTune Amplifier XE:Linux和Windows的剖析,拥有包括源代码浏览在内的图形界面;
  • Oracle Solaris Studio:用自带的性能分析器对Solaris和Linux做剖析,拥有包括源代码浏览在内的图形界面。

监视sar

最广泛用于监视单一操作系统的工具是sar(1),基于计数器的,在预定的时间(通过cron)执行以记录系统计数器的状态。读取自己统计信息的归档数据(若开启)来打印历史统计信息。

在Linux中,sar(1)是通过sysstat包提供的。

类似工具:System Data Recorder和Collectl。

观测来源

系统性能统计的主要来源是:/proc/sys和kstat。一份比较完整的观测来源清单如下表:

TypeLinuxSolaris
进程级计数器/proc/proc,lxproc
系统级计数器/proc,/syskstat
设备驱动和调试信息/syskstat
进程级跟踪ptrace,uprobesprocfs,dtrace
性能计数器perf eventlibcpc
网络跟踪libpcaplibdlpi,libpcap
进程级延时指标延时核算微状态核算
系统级跟踪tracepoints,kprobes,ftracedtrace

/proc

一个提供内核统计信息的文件系统接口。/proc由内核动态创建,不需要任何存储设备(在内存中运行)。多数文件是只读的,为观测工具提供统计数据。一部分文件是可写的,用于控制进程和内核的行为。

Linux中/proc的文件系统类型是proc,Solaris则是procfs

Linux中与进程性能观测相关的文件:

  • limits:实际的资源限制;
  • maps:映射的内存区域;
  • sched:CPU调度器的各种统计;
  • schedstat:CPU运行时间、延时和时间分片;
  • smaps:映射内存区域的使用统计;
  • stat:进程状态和统计,包括总的CPU和内存的使用情况;
  • statm:以页为单位的内存使用总结;
  • status:stat和statm的信息,用户可读;
  • task:每个任务的统计目录。

Linux中与性能观测相关的系统级别的文件:

  • cpuinfo:物理处理器信息,包含所有虚拟CPU、型号、时钟频率和缓存大小;
  • diskstats:对于所有磁盘设备的磁盘I/O统计;
  • interrupts:每个CPU的中断计数器;
  • loadavg:负载平均值;
  • meminfo:系统内存使用明细;
  • net/dev:网络接口统计;
  • net/tcp:活跃的TCP套接字信息;
  • schedstat:系统级别的CPU调度器统计;
  • self:关联当前进程ID路径的符号链接,为了使用方便;
  • slabinfo:内核slab分配器缓存统计;
  • stat:内核和系统资源的统计,CPU、磁盘、分页、交换区、进程;
  • zoneinfo:内存区信息。

Solaris下,/proc只有进程状态的统计。系统级别的观测采用其他框架,主要是kstat。与性能观测相关的文件:

  • map:虚拟地址空间映射;
  • psinfo:进程的各种信息,包括CPU和内存的使用;
  • status:进程状态信息;
  • usage:扩展的进程活动统计,包括进程微状态、错误、块、上下文切换,以及系统调用计数;
  • lstatus:与status相似,但包含的是每一个线程的统计;
  • lpsinfo:与psinfo相似,但包含的是每一个线程的统计;
  • lusage:与usage相似,但包含的是每一个线程的统计;
  • lwpsinfo:针对代表性LWP(目前最活跃)的轻量级进程(线程)统计,还有lwpstatus和lwpsinfo文件;
  • xmap:扩展的内存映射统计(尚无文档);

sys

kstat

Solaris上有一个为系统级别的观测工具所用的内核统计框架(kstat)。kstat包含绝大多数资源的统计,一个典型的系统在kstat里能有上万计的可用统计。与/proc/sys不同,kstat没有伪文件系统,要用ioctl()从/dev/kstat读取。一般是调用libkstat库里的函数来执行这一操作,或用Sun::Solaris::Kstat,该Perl库具有同样的功能(虽然一些偏好libkstat的发行版里取消对该Perl库的支持)。命令行工具kstat(1M)也能提供统计数据,还能用在shell脚本里。

kstat是四元组的结构:
module:instance:name:statistic

  • module:一般指的是创建统计数据的内核模块,如sd指SCSI磁盘驱动,zfs指的是ZFS;
  • instance:某些模块是以多个实例的形式存在的,例如对每一个SCSI磁盘都有一个sd模块。instance是一个枚举值;
  • name:一组统计数据的名字;
  • statistic:单个的统计值名;

延时核算

开启CONFIG_TASK_DELAY_ACCT选项的Linux系统按以下状态跟踪每个任务的时间:

  • 调度器延时:等待轮到上CPU;
  • 块I/O:等待块I/O完成;
  • 交换:等待换页(内存压力);
  • 内存回收:等待内存回收例程;

微状态核算

Solaris上有线程级别和CPU级别的微状态核算(microstate accounting),针对预先定义好的状态可以记录高精度的时间。相较基于tick的指标,精确度有很大的提升,还提供一些附加的状态,用于性能分析。

CPU级别的指标是通过kstat暴露给用户空间工具,而进程级别的指标是通过/proc

mpstat(1M)可用于输出CPU的微状态,如usr、sys和idl列,分别对应内核代码中的CMS_USER、CMS_SYSTEM和CMS_IDLE。

prstat -m可用于打印线程的微状态,如USR、SYS。

其他观测源

其他:

  • CPU性能计数器:可编程的硬件寄存器,提供低层级的性能信息,包括CPU周期计数、指令计数、停滞周期等。在Linux上是通过perf_events接口,或系统调用perf_event_open(),或perf(1)来访问这些计数器。Solaris里是通过libcpc,或包括cpustat(1M)在内的工具来访问的;
  • 进程级别跟踪:跟踪的是用户级别软件事件,如系统调用和函数调用。一般执行的代价较高,会拖慢跟踪的目标。Linux上有系统调用ptrace()来控制进程跟踪,strace(1)用来跟踪系统调用,uprobes来做用户级别的动态跟踪。Solaris的系统用procfs和truss(1)来跟踪系统调用,DTrace做动态跟踪;
  • 内核跟踪:Linux中,tracepoints提供静态的内核探针(原先叫做内核标记,kernel markers),kprobes提供动态探针。工具ftrace、perf(1)、DTrace和SystemTap都用到这两项。Solaris系统,静态和动态的探针都由dtrace内核模块提供。DTrace、SystemTap都用到内核跟踪;
  • 网络嗅探:网络嗅探提供一种从网络设备上抓包的方法,能对数据包和协议的性能做详细的调查。在Linux上,嗅探的功能是通过libpcap库和/proc/net/dev提供的,命令行工具则有tcpdump(8)。Solaris上,嗅探功能是通过libdlpi库和/dev/net提供的,命令行工具是snoop(1M)。往Solaris系统移植的libpcap库和tcpdump(8)还在开发中。捕获和检查所有的数据包其实无论对于CPU还是存储都是有开销的;
  • 进程核算:进程核算可以追溯到大型机时代,那时候要对使用计算机的部门和用户收费,是基于进程的执行和运行时间计费的。现在它以某种形式存在于Linux和基于Solaris的系统上,有时能在进程级别对性能分析有所帮助。工具atop(1)用进程核算能捕捉到短暂存活的进程并显示其信息,而用/proc快照的办法很可能无法觉察到这件事;
  • 系统调用:一些可用的系统调用和库函数调用能提供某些性能指标。其中包括getrusage(),这个函数调用是为进程拿到自己资源的使用统计,包括用户时间、系统时间、错误、消息,以及上下文切换。Solaris用的是swapctl(),这个系统函数用于swap 设备的管理和统计(Linux对应的是/proc/swap)。

其他:

  • Linux:I/O核算、blktrace、timer_stats、lockstat、debugfs;
  • Solaris:扩展核算(extended accounting)、流核算(flow accounting)、Solaris审计。

最后,可用工具打开/dev/mem//dev/kmem直接读取内核内存。

DTrace

DTrace的设计是生产环境安全的,拥有最小的性能开销。

静态和动态跟踪

静态跟踪:在编译之前加进代码里的静态探针
动态跟踪:在编译之后软件运行时加入的动态探针

int指令引发一个软中断,该软中断已经接到指示执行动态跟踪的action。当动态跟踪被禁用时,指令会回到原来的状态。这是内核地址空间的现场修改(live patching),所采用的技术会因处理器类型的不同而有所不同。

只有当动态跟踪开启后,才能插入指令。没开启时,是没有附加指令的,因此也没有任何探针效果。这就是不使用时零开销(zero overhead when not in use)。使用时来自附加指令的开销是与探针触发的频率成比例的:跟踪事件的频率和所执行的action。

DTrace能动态跟踪函数的入口和返回,以及任何在用户空间的指令。由于这是在CPU指令上动态建立探针,而CPU指令在软件不同版本时会发生变化,所以这是一个不稳定接口(unstable interface)。在跟踪的软件版本更新时可能需要变更所有的Dtrace单行命令和脚本。

探针

DTrace探针是以四元组命名的,provider:module:function:name,provider是相关探针的集合。module和function是动态产生的,标记探针指示的代码位置。name是探针的名字。

provider

可用的DTrace provider取决于你的DTrace和操作系统的版本,包括:

  • syscall:系统调用自陷表;
  • vminfo:虚拟内存统计;
  • sysinfo:系统统计;
  • profile:任意频率的采样;
  • sched:内核调度事件;
  • proc:进程级别事件,创建、执行、退出;
  • io:块设备接口跟踪(磁盘I/O);
  • pid:用户级别动态跟踪;
  • tcp:TCP协议事件,连接、发送和接收;
  • ip:IP协议事件,发送和接收;
  • fbt:内核级别动态跟踪。

很多provider都是用静态跟踪来实现的,好处是接口稳定,代价(缺点)是监测视野有点限制。为了确保对目标软件的不同版本都能适用,尽量用静态provider来编写脚本。

参数

探针通过一组称为参数的变量来提供数据。参数的使用取决于provider。系统调用的provider给每一个系统调用都做入口和返回的探针。

D语言

D语言与awk类似,能用作单行命令也能写脚本。语句形式如下:
probe_description /predicate/ {action}
action是一系列以分号间隔的语句,当探针触发时执行。predicate是可选的过滤表达式。

例句:proc:::exec-success /execname=="httpd"/{trace(pid);}

解读:如果进程名是"httpd",会跟踪proc provider中的exec-success探针并执行trace(pid)这一action。exec-success探针常常用于跟踪新进程的创建和系统调用exec()的执行。当前的进程名是用内置变量execname检索出来的,而当前的进程ID则是通过pid。

内置变量

内置变量是用来做计算和判断的,可以通过action打印出来。常用内置变量如下表所示。

变量描述
execname执行在CPU上进程的名字(字符串)
uid执行在CPU上的用户ID
pid执行在CPU上的进程ID
timestamp当前时间,自启动以来的纳秒数
vtimestampCPU上的线程时间,单位是纳秒
arg0..N探针参数(uint64_t)
args[0]..[N]探针参数(类型化的)
curthread指向当前线程内核结构的指针
probefunc探针描述(字符串)的函数组件
probename探针描述(字符串)的命名组件
curpsinfo当前进程信息

action

常用的action见下表

action描述
trace(arg)打印arg
printf(format, arg, ...)打印格式化的字符串
stringof(addr)返回来自内核空间的字符串
copyinstr(addr)返回来自用户空间地址的字符串(需要内核执行一次从用户空间到内核空间的复制操作)
stack(count)打印内核级别的栈跟踪,如果有count,按count截断
ustack(count)打印用户级别的栈跟踪,如果有count,按count截断
func(pc)从内核程序计数器(pc),返回内核函数名
ufunc(pc)从用户程序计数器(pc),返回用户函数名
exit(status)退出DTrace并返回状态
trunc(@agg, count)截断聚合变量,或是全部(删除所有的键),或按照指定键的数目(count)做截断
clear(@agg)删除聚合变量的值(键保留)
printa(format, @agg)格式化地打印聚合变量

最后三个action使用一种特殊的称为聚合型(aggregation)的变量类型。

变量类型

变量类型表如下,按照使用偏好排列(先是聚合变量,然后按开销从低到高)。

类型前缀作用域开销多CPU安全赋值示例
聚合变量@全局@x=count();
带键的聚合变量@[]全局@x[pid]=count();
从句局部变量this->从句实例非常低this->x=1;
线程局部变量self->线程内中等self->x=1;
标量全局中下x=1;
关联数组全局中上x[y]=1;

解读:

  • 线程局部变量的作用域是在线程内;
  • 子句局部变量用于中间计算,只在针对同一探针描述的action子句中有效;
  • 多个CPU同时对同一个标量做写入会损坏变量状态,这不大可能,但确实会发生,对于字符串标量也要同样小心(字符串损坏)。

聚合变量(aggregation)是一类特殊的变量类型,可以由CPU单独计算汇总之后再传递到用户空间。该变量类型拥有最低的开销,是另一种数据汇总的方法。

用于填充聚合变量的action见下表

聚合Action描述
count()发生计数
sum(value)对value求和
min(value)记录value的最小值
max(value)记录value的最大值
quantize(value)用2的幂次方直方图记录value
lquantize(value, min, max, step)用给定最小值、最大值和步进值做线性直方图记录value
llquantize(value, factor, min_magnitude, max_magnitude, steps)用混合对数/线性直方图记录value

单行命令

跟踪系统调用open(),打印进程名和文件路径名:
dtrace -n 'syscall::open:entry { printf("%s %s", execname, copyinstr(arg0)); }'

Oracle Solaris 11很大程度上修改系统调用自陷表(系统调用的provider是构建在此之上的),这样在该系统上跟踪open()就变成:
dtrace -n 'syscall::openat:entry { printf("%s %s", execname, copyinstr(arg1)); }'

按进程名归纳所有CPU的交叉调用:
dtrace -n 'sysinfo:::xcalls { @[execname] = count(); }'

按99Hz采样内核级栈:
dtrace -n 'profile:::profile-99 { @[stack()] = count(); }'

脚本

例如来自DTraceToolkit脚本集合的脚本bitesize.d,GitHub,根据进程名显示请求的磁盘I/O大小:

#!/usr/sbin/dtrace -s  /* 解释器行,表示脚本文件可从命令行执行 */
#pragma D option quiet  /* 设置安静模式,压缩DTrace的默认输出 */
/* 打印头 */
dtrace:::BEGIN
{
   printf("Tracing... Hit Ctrl-C to end.\n");
}
/* 进程io启动 */
io:::start
{
   /* fetch details */
   this->size = args[0]->b_bcount;
   /* store details */
   @Size[pid, curpsinfo->pr_psargs] = quantize(this->size);
}
/* 打印最终报告 */
dtrace:::END
{
   printf("\n%8s %s\n", "PID", "CMD");
   printa("%8d %S\n%@d\n", @Size);
}

开销

DTrace通过利用每个CPU的内核缓冲区和内核的聚合总结,减小跟踪的开销。默认状态下,DTrace以每秒一次这样一个温和的频率,从内核空间往用户空间传递数据。还有其他减小开销和提高安全性的各种功能,比如有的例程如果发现系统不能响应就会终止跟踪。

跟踪执行的开销是与跟踪的频率和所执行的action息息相关的。跟踪块设备I/O的频率通常不高(1000 I/O每秒或更少),开销是可以忽略的。另一方面,跟踪网络I/O时,当包的速率达到每秒百万次时,就会引起显著的开销。

action也是有代价的。

把数据存入变量也是有开销的,特别是关联数组。

文档和资源

书:

  • Dynamic Tracing Guide
  • DTrace: Dynamic Tracing in Oracle Solaris, Mac OS X and FreeBSD

资源:

  • DTraceToolkit-GitHub
  • https://www.brendangregg.com,本书作者的个人网站

基于DTrace封装的工具:

  • execsnoop
  • Oracle的ZFS Appliance Analytics
  • Joyent公司的Cloud Analytics

SystemTap

SystemTap是专为Linux打造的,对用户级和内核级的代码都提供静态和动态跟踪的功能,采用其他的内核框架做源:静态探针用tracepoints、动态探针用kprobes、用户级别的探针用uprobes。

不足:稳定性问题,一些版本会导致内核崩溃或挂起;启动较慢、错误信息难懂、隐式功能无文档、语言还不够精炼。

将DTrace移植到Linux:Oracle的Oracle Enterprise Linux。

探针

探针:由句号分隔,可选的内置选项(放在括号中),如:

  • begin:程序开始;
  • end:程序结束;
  • syscall.read:系统调用read()的开始;
  • syscall.read.return:系统调用read()的结束;
  • kernel.function(“sys_read”):内核函数sys_read()的开始;
  • kernel.function(“sys_read”).return:内核函数sys_read()的结束;
  • socket.send:发送包;
  • timer.ms(100):对单一CPU每100ms触发一次的探针;
  • timer.profile:按内核时钟频率对所有的CPU都触发的探针,用于采样/剖析;
  • process(“a.out”).statement(“*@main.c:100”):跟踪目标进程,可执行文件a.outmain.c的第100行。

tapset

tapset:一组相关的探针。tapset还能附带用来执行action。tapset举例:

  • syscall:系统调用;
  • ioblock:块设备接口和I/O调度器;
  • scheduler:内核CPU调度器事件;
  • memory:进程和虚拟内存的使用;
  • scsi:SCSI目标的事件;
  • networking:网络设备事件,包括接收和传输;
  • tcp:TCP协议事件,包括发送和接收事件;
  • socket:套接字事件。

action和内置变量

SystemTap还提供许多的action和内置变量:

  • execname():可获取进程名;
  • pid():可获取当前进程ID;
  • print_backtrace():可打印内核栈的回溯信息。

示例

stap -ve 'global stats; probe syscall.read.return { stats <<< $return; }
   probe end { printf("\n\trval (bytes)\n"); print(@hist_log(stats)); }'

解读:

  • 单行命令跟踪系统调用read(),将返回读取的大小结果保存成一张2的幂次方的直方图;
  • 选项-v会打印出编译阶段的详细信息,通知用户跟踪已经开启;
  • 单行命令以声明全局变量stats作为开始,这是SystemTap所要求的预声明;
  • 探针的定义用关键词probe作为开头,匹配系统调用read()的返回;
  • action是用变量stats记录返回值$return的,用的统计操作符是<<<。采用这样通用的数值记录方式,之后可以用于不同的数据汇总中;
  • end探针把统计数据作为直方图打印出来;
  • 如果不输出直方图,SystemTap在退出时也会打印一个基本的数字总结;
  • read()的$return值有些是负值,这代表的是返回的错误码errno。

SystemTap对比DTrace

两条等价的单行命令:

stap -e 'global stats; probe syscall.read.return { stats <<< $return; }
   probe end { printf("\trval (bytes)\n"); print(@hist_log(stats)); }'
dtrace -n 'syscall::read:return { @["rval(bytes)"] = quantize(arg0); }'

SystemTap脚本举例:

stap -e 'global s; probe syscall.read.return {
   if ($return >= 0) { s[execname()] <<< $return; }
}
probe end {
   printf("\n%-36s %8s %8s %10s\n", "EXEC", "CALLS", "AVGSZ", "TOTAL");
   foreach(k in s+) {
      printf("%-36s %8d %8d %10d\n", k, @count(s[k]), @avg(s[k]), @sum(s[k]));
   }
} '

解读:这个单行命令根据进程名给出读操作返回大小的统计数据。用三个不同的函数给调用次数CALLS、平均大小AVGSZ(字节)和总大小TOTAL提供数据。若用DTrace来做这件事,需要三个不同的聚合变量,一种类型一个。

区别:

  • DTrace不提供if,用谓词作为分支;
  • DTrace当前没有循环能力,除了展开循环,出于安全考虑不执行回跳;SystemTap 为循环设置上界,脚本里的无限循环不会在内核上下文里挂起;
  • SystemTap可直接访问统计数值,如s[k],而DTrace的聚合变量的打印只能依靠自己或用聚合函数来处理。

开销

当程序首次执行时,SystemTap在编译阶段会消耗几秒CPU资源。SystemTap会将程序缓存下来,这样开销不会每次使用时都发生。还可以在不同的系统上编译SystemTap程序,然后将缓存的结果传输给目标系统。

另一个额外开销是内核分析的内核调试信息,通常不包括在Linux的发行版中(可能是几百兆字节大小)。

文档和资源

书:SystemTap Language Reference。

perf

LPE,Linux Performance Events,Linux性能事件,简称perf,现在所支持的性能观测的范围已相当宽泛。虽然没有DTrace和SystemTap那样的实时编程能力,但perf可执行静态和动态跟踪(基于tracepoint、kprobe和uprobe)、profiling、检查栈跟踪、局部变量和数据类型。已成为Linux内核主线的一部分,最容易使用的(如果已安装),所提供的观测能力足够满足大多数问题排查。

观测工具的观测

观测工具和构建其上的统计都是由软件实现的,而所有的软件都是潜在有Bug的。存在以下问题:

  • 工具不总是正确的;
  • Man手册页不总是正确的;
  • 能用的指标可能不完整;
  • 能用的指标可能设计得很差;

当多个观测工具覆盖的范围有重叠时,就能用它们来互相检查。

另一个验证的技术是施加已知的负载,看看观测工具表现得是否与你预计的结果相同。可以用微基准测试工具,用它们的报告结果做比较。

缺少指标比用不合适的指标更难发现。

练习

  • 什么是剖析?
  • 什么是跟踪?
  • 静态跟踪和动态跟踪有什么区别?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2223924.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙开发融云demo发送文本消息

鸿蒙开发融云demo发送文本消息 融云鸿蒙版是不带UI的&#xff0c;得自己一步步搭建。 这次说如何发送文本消息&#xff0c;并且显示文本消息 一、思路 发送用&#xff1a;IMEngine.getInstance().sendMessage 显示文本&#xff1a; Text(ImUtils.dealMyTextContent(this.ms…

Linux:磁盘深潜:探索文件系统、连接之道与库的奥秘

✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来! 文章目录 目录 文章目录 前言 一 磁盘 1.1 磁盘的物理结构 1.2 磁盘的存储结构 1.3 磁盘的逻辑结构 ​编辑二 文件系统 2.1 简单了解 2.2 inode 2.3 文件描述符&#xff0c;进程与文件系统的关系 ​编辑2…

格姗知识圈博客网站开源了!

格姗知识圈博客 一个基于 Spring Boot、Spring Security、Vue3、Element Plus 的前后端分离的博客网站&#xff01;本项目基本上是小格子一个人开发&#xff0c;由于工作和个人能力原因&#xff0c;部分技术都是边学习边开发&#xff0c;特别是前端&#xff08;工作中是后端开…

模型选择拟合

1.通过多项式拟合交互探索概念 import math import numpy as np import torch from torch import nn from d2l import torch as d2l 2.使用三阶多项式来生成训练和测试数据的标签 max_degree 20 # 多项式的最大阶数 n_train, n_test 100, 100 # 训练和测试数据集大小 true…

SQL Server 当前日期及其未来三天的日期

当前日期及其未来三天的日期&#xff0c;并分别以 YYYY-MM-DD 和 yyyyMMdd 的格式展示 1、当前日期及其未来三天的日期&#xff0c;以 YYYY-MM-DD的格式展示 WITH CurrentDate AS (SELECT GETDATE() AS 当前日期 ) -- 使用 CONVERT 函数 SELECTCONVERT(VARCHAR(10), 当前日期,…

【论文笔记】MLSLT: Towards Multilingual Sign Language Translation

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: MLSLT: Towards Multiling…

springboot医疗物品采购系统-计算机设计毕业源码10210

摘 要 本文基于Spring Boot框架&#xff0c;设计并实现了一个医疗物品采购系统。该系统旨在解决医疗物品采购中的管理和信息化问题&#xff0c;提供便捷的服务和支持。通过系统的设计与实现&#xff0c;实现了医疗物品的供应商家管理、物品类型管理、物品仓库管理、采购计划管…

小渡Ai论文写作:文献综述黑科技LitMaps30s找到所有文献

✨Litmaps 究竟是什么呢&#xff1f; Litmaps 是一款极为强大的文献搜索与追踪工具&#xff01; 它不但能够助力你找到相关的研究文献&#xff0c;还能够依据你提供的文献生成一张学术地图&#xff0c;清晰地展现文献之间的引用链以及研究发展趋势。 恰似一张璀璨的星空图&a…

Linux中安装配置SQLite3,并实现C语言与SQLite3的交互。

前言 SQLite 是一个软件库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。本次实验介绍在Linux上实现C语言和SQLite3的交互&#xff0c;利用C语言编写相关语句&#xff0c;连接数据库、操作数…

python实战(三)——文本向量化/文本表示

一、概念 文本向量化是自然语言处理领域的重要环节&#xff0c;也是现在大语言模型开发重要基础。计算机程序无法理解文字信息&#xff08;实际上非数值类型的信息都无法理解&#xff09;&#xff0c;因此我们需要将文字信息转换成计算机程序可理解的数值类型。通俗来说就是我们…

Python 精品学习资料收藏下载,Python 字符串处理备忘单

重点在这&#xff1a; &#xff08;请移步图中作者处&#xff0c;获取高清大图下载链接&#xff09; Python 中的字符串&#xff08;String&#xff09;是一种用于表示文本的数据类型。字符串是不可变的&#xff0c;这意味着一旦创建&#xff0c;你不能改变字符串中的字符&am…

【学习AI-相关路程-mnist手写数字分类-python-硬件:jetson orin NX-自我学习AI-基础知识铺垫-遇到问题(1) 】

【学习AI-相关路程-mnist手写数字分类-python-硬件&#xff1a;jetson orin NX-自我学习AI-基础知识铺垫-遇到问题&#xff08;1&#xff09; 】 1、前言2、先行了解&#xff08;1&#xff09;学习基础知识-了解jetson orin nx 设备&#xff08;2&#xff09;学习python&AI…

ClickHouse在百度MEG数据中台的落地和优化

导读 百度MEG上一代大数据产品存在平台分散、质量不均和易用性差等问题&#xff0c;导致开发效率低下、学习成本高&#xff0c;业务需求响应迟缓。为了解决这些问题&#xff0c;百度MEG内部开发了图灵3.0生态系统&#xff0c;包括Turing Data Engine(TDE)计算引擎、Turing Dat…

从0到1,搭建vue3项目

一 Vite创建Vue3项目 1.1.创建Vue3项目 1.1.1.运行创建项目命令 # 使用 npm npm create vitelatest 1.1.2、填写项目名称 1.1.3、选择前端框架 1.1.4、选择语法类型 1.1.5、按提示运行代码 1.1.6浏览器问 localhost:5173 预览 1.2项目结构 1.2.1vite.config.ts 1.2.2 pac…

基于线性回归(Linear Regression)的房屋价格预测

基于线性回归&#xff08;Linear Regression&#xff09;的房屋价格预测 一元线性回归加载数据假设函数损失函数&#xff08;代价函数&#xff09;梯度下降函数完整代码 多变量线性回归加载数据集特征缩放假设函数损失函数梯度下降函数算法步骤完整代码 线性回归是统计学中的一…

【二轮征稿启动】第三届环境工程与可持续能源国际会议持续收录优质稿件

第三届环境工程与与可持续能源国际会议&#xff08;EESE 2024&#xff09;由中南林业科技大学主办&#xff0c;湖南农业大学协办&#xff0c;将于2024年12月20日-22日在湖南长沙召开。 大会邀请到国家杰出青年科学基金获得者、华中科技大学能源与动力工程学院冯光教授&#xf…

R实验——logistic回归、LDA、QDAKNN

数据集介绍&#xff1a; mpg&#xff0c;miles per gallon即油耗&#xff0c;这个数据集来自卡内基梅隆大学维护的StatLib库。1983年美国统计协会博览会使用了该数据集。这个数据集是对StatLib库中提供的数据集稍加修改的版本。根据Ross Quinlan(1993)在预测属性“mpg”中的使…

计算机网络原理总结C-网络层

网络层 网络层提供的两种服务网际协议IP 虚拟互连网络IP地址子网掩码&#xff08;无分类编址CIDR&#xff09;IP地址和MAC地址IP数据报格式&#xff08;路由&#xff09;转发分组的流程 因特网的路由选择协议&#xff08;动态路由协议&#xff09; 网际控制报文协议ICMPIP多播…

认识CSS语法

CSS&#xff08;网页美容&#xff09; 重点&#xff1a;选择器、盒子模型、浮动、定位、动画&#xff0c;伸缩布局 Css的作用&#xff1a; 美化网页&#xff1a;CSS控制标签的样式 网页布局&#xff1a;CSS控制标签的位置 概念&#xff1a;层叠样式表&#xff08;级联样式表…

UE5 第一人称示例代码阅读0 UEnhancedInputComponent

UEnhancedInputComponent使用流程 我的总结示例分析firstthenand thenfinally&代码关于键盘输入XYZ 我的总结 这个东西是一个对输入进行控制的系统&#xff0c;看了一下第一人称例子里&#xff0c;算是看明白了&#xff0c;但是感觉这东西使用起来有点绕&#xff0c;特此梳…