异常检测分析(预览)
使用异常检测来识别频繁重复的代码间隔(如循环迭代)中的性能异常。在微秒和纳秒级别执行细粒度分析。
应用程序性能有时会受到性能异常的影响。性能异常是任何短暂的、偶发的问题,会导致不可恢复的后果。这些问题在统计上可能无法辨别,但它们会造成糟糕的用户体验,并且修复起来可能非常昂贵。当您的应用程序的性能需要为同一任务的实例执行不同数量的工作时,或者当它在一个循环的单个/几个迭代中显示变化时,这些都是您的应用程序中异常行为的症状。
使用异常检测分析来识别应用程序中难以隔离的性能异常。这种分析类型使用英特尔® 处理器跟踪(英特尔® PT)技术来执行跟踪数据收集和细粒度的时间和事件测量。英特尔® PT 是英特尔® 架构的扩展,它使用专用硬件捕获有关软件执行的信息。硬件只会对被跟踪的软件造成最小的性能干扰。
这是一个
预览功能
. 预览功能可能会或可能不会出现在未来的生产版本中。它可供您使用,希望您能就其有用性提供反馈并帮助确定其未来。使用预览功能收集的数据不能保证向后兼容未来的版本。
英特尔® PT 中的控制流跟踪功能会生成各种数据包,当通过后处理工具与程序的二进制文件结合时,可以使用这些数据包生成精确的执行跟踪。数据包记录流信息,例如指令指针 (IP)、间接分支目标和连续代码区域(基本块)内的条件分支的方向。有关英特尔® PT 中关键概念的描述,请参阅 英特尔软件开发人员手册(第 3C 卷):系统编程指南的第 35 章。
使用以下方法检测软件性能异常
VTune
探查器
,您使用 Instrumentation and Tracing Technology (ITT) API来指定感兴趣的特定代码区域,然后运行异常检测分析。
常见的性能异常
这些是软件应用程序中性能异常的典型示例。
- 处理时间异常长的金融交易。
- 视频游戏 UI 中的故障,例如慢速或跳过的视频帧。
- 具有 SPDK/DPDK 循环的大型应用程序中的数据包丢失。
- 处理速度至关重要且某些迭代运行速度比其他迭代慢的高频应用程序。
在观察到的应用程序行为在某些迭代中偏离预期行为的其中一种情况下运行异常检测。
性能异常的原因
控制流的变化: 同一任务的不同实例需要不同的工作量。
不寻常的观察: 错误或内存/存储重新分配的昂贵处理。
上下文切换: 同步或抢占。
意外的内核活动: 中断或页面错误。
微架构问题: 缓存未命中或不正确的分支预测。
频率下降: CPU 利用率低、散热问题或代码中包含英特尔® 高级矢量扩展(英特尔® AVX)指令。
异常检测分析工作流程
当您观察到应用程序性能异常时,请使用异常检测进行详细调查。
- 准备您的应用程序进行分析。
- 定义将您的代码分成更小的感兴趣区域的参数。决定要模拟每个区域的时间。
- 运行异常检测。
- 详细查看异常:
- 在“自下而上”视图中为每个异常加载处理器的跟踪数据,以检查感兴趣的代码区域。
- 打开跟踪数据以查看特定区域的频率信息。
- 检查源视图和装配视图以查看循环迭代的数量。
配置和运行分析
准备您的申请
大型应用程序可以通过分析运行生成大量数据。这反过来又会导致处理结果的显着延迟。您可能只想关注代码中特定操作的异常情况。通过将其定义为感兴趣的代码区域来标记此部分。为此目的使用 ITT API。
注册您计划分析的代码区域的名称:
__itt_pt_region 区域 = __itt_pt_region_create("区域");
使用此名称标记应用程序中的目标循环:
为了(…;…;…) { __itt_mark_pt_region_begin(区域); <代码处理你的任务> __itt_mark_pt_region_end(区域); }
运行分析
在欢迎屏幕上,单击
配置分析 .
在分析树中,选择
异常检测 分析类型在 算法 团体。
在里面
什么 窗格中,指定您的应用程序和任何相关的应用程序参数。
在里面
如何 窗格中,指定分析参数。
范围 | 描述 | 范围 | 推荐值 |
用于详细分析的最大代码区域数 | 为您的应用程序指定代码区域的数量。 | 10-5000 | 为了更快地加载详细信息,请选择不超过 1000 的值。 |
每个代码区域的最大分析持续时间 | 指定要在每个代码区域上花费的分析时间 (ms) 的持续时间。 | 0.001-1000 | 任何低于 1000 毫秒的值。 |
单击- 开始按钮运行分析。
要 从命令行运行异常检测,请使用
底部的命令行按钮。
查看数据
分析完成后,
VTune
探查器
显示结果
概括
窗户。
经过时间 表示在所有感兴趣的代码区域上花费的总时间。
代码感兴趣区域持续时间直方图 根据指定的持续时间(或延迟)绘制性能关键任务实例的数量。查看 Fast 和 Slow 区域中的特定代码区域以了解持续时间更改的原因。
收藏和平台信息 显示有关系统的相关详细信息、有关收集平台的数据以及结果集大小。
查看不同系统上的数据
当您在收集数据的同一系统上处理分析结果时,上述过程很有用。如果您想在查看之前将收集的数据传输到其他系统,请运行
档案
数据收集后的命令将基本二进制文件复制到结果文件夹。您必须在将结果传输到新系统之前完成此步骤,才能顺利加载集合详细信息。
运行
档案
命令:
如上所述收集结果。
在命令行中,键入:
vtune.exe --archive -r r001ad
在哪里
r001ad
是分析结果的一个例子。
要查看不同系统上收集的数据,您必须复制所有二进制文件,包括链接到主二进制文件并在收集期间访问的系统和编译器运行时二进制文件。这
档案
命令对此很有用,因为手动复制这些二进制文件并不容易。
下一步
有关以这些方式解释收集的数据的信息, 请参阅 异常检测视图:
为每个分析加载跟踪详细信息
自下而上 窗户。
寻找意外的内核活动。查看应用程序是否进入了某些在分析过程中不应该被激活的内核。
使用源代码和汇编视图比较直方图的快速和慢速区域中感兴趣的代码区域。
异常检测视图
在对您的应用程序执行异常检测分析后解释结果。通过检查感兴趣的代码区域来识别性能异常。
使用异常检测视图来解释异常检测分析的结果。典型的工作流程涉及以下领域的检查:
查看数据
在应用程序上 完成运行 异常检测后,收集的数据将显示在概括 窗户。
从
代码感兴趣区域持续时间直方图 . 这显示了特定持续时间或延迟(以毫秒为单位)的性能关键任务的实例数。
检查直方图以查看:
感兴趣的代码区域
有关模拟执行速度比正常速度快或慢的区域的信息
此图标识了慢速区域中的意外性能异常值。
如有必要,使用 X 轴上的滑块调整快速、良好和慢速延迟的阈值。
慢速区域的加载详细信息
在里面
自下而上
- 窗口,加载感兴趣的慢代码区域的详细信息:
切换到
自下而上
- 窗户。
按结果分组
代码感兴趣区域/持续时间类型
- .
要进一步检查慢速区域中的异常值,请右键单击慢速字段并选择
通过选择加载英特尔处理器数据
- .
这将加载有关感兴趣的代码区域的详细信息
英特尔处理器跟踪详细信息
- 窗户。
比较处理器跟踪详细信息
一旦您在
英特尔处理器跟踪详细信息
- 窗口中,您可以通过并排放置标记代码区域的各个实例来比较它们的跟踪详细信息。栈顶代表
内核入口点
- .
公制 | 解释 |
停用的指令、调用计数、总迭代计数 | 控制流指标。 已停用的说明 指进入内核的条目数。 |
CPU 时间(内核和用户) | CPU 上的活动时间。 |
等待时间,非活动时间 | 线程由于同步或抢占而空闲的持续时间。 |
经过时间 | 延迟(代码区域执行的挂钟时间)。 |
使用此窗口作为中心来检测以下类型的性能异常。
上下文切换异常
内核引起的异常
频率下降
控制流偏差异常
上下文切换异常
在里面
英特尔处理器跟踪详细信息
- 窗口,检查
- 和
- 指标。这
- 指示线程由于同步问题而空闲的持续时间。
如果指标为零,则应用程序没有上下文切换。继续检查不同类型的异常。
如果指标不为零,请继续执行此过程以检查上下文切换。
对数据进行排序
等待时间
- .
对于具有显着性的实例
等待时间
- , 比较
- 和
- . 如果线程在相当长的一段时间内处于空闲状态,则这是由于上下文切换同步问题造成的。在这个例子中,
- 在 1.318 毫秒中空闲了 1.269 毫秒,这大约是 96% 的时间。
展开实例以深入了解函数或堆栈。识别使线程进入空闲状态的堆栈。
非活动时间
等待时间
等待时间
等待时间
经过时间
线程 25883
内核引起的异常
在里面
英特尔处理器跟踪详细信息
- 窗口,对数据进行排序
- . 栈顶元素指向内核的入口点。在内核时间与已用时间的比率很高的情况下,大量时间花费在内核中。在此示例中,突出显示的线程在 997 微秒中花费了 566 微秒。
展开线程以查看可能导致较长内核时间的贡献堆栈。==》下图说明是因为网络tcp 通信导致性能很差!!!
内核时间
由于内核和驱动程序中存在动态代码,因此无法对这些二进制文件执行静态处理。这
内核活动
- 堆栈顶部的节点聚合了在感兴趣的代码区域的特定实例期间发生的内核活动的所有性能数据。
由于不处理内核二进制文件,
VTune
探查器
- 无法收集代码流指标,例如
通话次数
- ,
迭代次数
- , 或者
已停用的说明
- . 所有这些指标都是零,除了
已停用的说明
- ,它表示进入内核的条目数。
内核引起的异常的一个可能解释可能是网络速度。当控制权进入内核同时接收请求并通过网络发送响应时,这可能会导致速度减慢。
频率下降
在以下窗口之一中查找有关频率下降的信息:
自下而上的窗口:
- 显示整个应用程序的频率信息。
英特尔处理器跟踪详细信息窗口:
- 仅显示加载区域的频率信息。
由于以下几个原因,可能会发生频率下降:
在加载的代码区域内部或外部使用英特尔® 高级矢量扩展(英特尔® AVX)指令。
存在潜在的硬件问题,例如冷却。
除了您的应用程序之外,内核和操作系统上的低活动也会导致频率下降。寻找大量的
非活动时间
- 或者
- .
等待时间
控制流偏差异常
当。。。的时候
已停用的说明
- 对于某些线程来说,指标出乎意料地巨大,它表明控制流异常。在代码区域的执行过程中可能发生了代码偏差。
在网格中选择一个您看到高值的节点
已停用的说明
- .
右键单击并选择
按选择过滤
- 从上下文菜单中。
切换到
呼叫者/被呼叫者
- 窗户。
在平面配置文件视图中,您可以看到使用 Self 和 Total CPU Times 注释的函数。调用者视图以自下而上的形式显示所选函数的调用者。被调用者视图以自上而下的形式显示来自所选函数的调用树。
在本例中,函数调用
_slab_evict_one
- 函数来自
_slab_evict_rand
- 导致显着延迟,如 Self CPU Time 所证明的那样。
源码分析:
这是识别控制流中的偏差的另一种方法。
检查
总迭代次数
- 比较快速和慢速迭代之间的循环迭代次数。
如果较慢的迭代具有较高的迭代计数,则切换到
源程序集
- 查看并检查函数的源代码。
检查较慢的迭代是否通过了缓存元素的验证。
这两种方法都表明存在
缓存驱逐
- , 这可能很少发生。虽然您可能无法完全消除缓存驱逐,但您可以通过以下方式将其最小化:
增加缓存大小。
更新缓存数据并重复分析。