Visual Studio2022 Profile 工具使用

本篇研究下Visual Studio自带的性能分析工具,针对C++代码,基于Visual Studio2022


文章目录

  • CPU使用率
  • 检测
  • 并发可视化工具
    • 使用率视图
    • 线程视图
    • 内核视图
    • 并发可视化工具SDK
  • 参考资料


CPU使用率

对于CPU密集型程序,我们可以通过分析程序的CPU使用率,找到程序的瓶颈,Visual Studio原生提供了对于CPU使用情况的诊断工具,具体使用方法如下:

  1. 在 Visual Studio 里打开我们的程序,在我们想分析的函数/代码块的起始位置和结束位置打上断点,比如这里我们想分析的是 getSum() 这个函数。

  2. 调试状态下运行我们的程序,然后打开诊断工具窗口(调试>窗口>显示诊断工具)

  3. 之后可以在诊断工具里,设置选择工具,选择是否查看 CPU使用率和内存使用

  4. 当程序运行到一个断点时,打开CPU 使用率下的记录 CPU 配置文件,之后就会开始记录CPU使用情况

  5. 继续执行我们的代码,然后程序运行到我们的第二个断点处,这是点开CPU使用率,就可以看到CPU使用率相关的信息了。

    (1)CPU 总计:表示该函数函数体和调用的其他函数的总的CPU计数,及占比
    (2)自CPU:表示该函数函数体本身的CPU计数,及占比
    (3)排名靠前的函数:按自CPU计数从大到小排列,这里 func1 函数自CPU 5152(99.52%)
    (4)热路径:CPU计数最大部分的调用树,上面可以看到是 getSum 中调用了 func1

  6. 这里可以打开CPU 使用率的详细信息窗口,或者点击上面图中任意函数,导航到对应位置,这里视图默认显示是调用树,下面代码中会在左侧显示每一行代码的CPU计数。
    在这里插入图片描述

  7. 我们可以选择视图为调用方/被调用方,选择对应的函数,当前函数就是我们选择的函数,可以看到调用函数就是调用当前函数的函数,调用的函数就是当前函数调用到的一些函数

  8. 也可以选择火焰图视图


检测

上面的CPU使用率是通过采样的方式得到,定时去检查CPU的调用堆栈,好处是不会产生大的开销,而检测是通过工具将代码注入到可捕获计时信息的二进制文件中,或通过使用hook在应用程序运行期间收集和发出精确计时和调用计数信息。相对于采样的方式,检测方法开销较大,但检测可提供更确切的调用计数和精确计时。

Visual Studio也提供了原生的检测工具,但对C++程序只能进行静态检测,具体步骤如下:

  1. 首先编译好的目标文件,在链接时需要加上 -PROFILE 选项
  2. 调试 > 性能探查器,打开性能探查器
    .
  3. 首先选择目标,这里选择启动项目,也可以选择链接好的可执行文件,选择检测选项,点击开始。
  4. 等程序运行结束或手动停止检测就会输出包含函数计时的报告
  5. 添加用户标记,这个功能目前还有问题,见下图,等修复好了更新

并发可视化工具

这里简单介绍下如何使用 Visual Studio 提供的并发可视化工具和相关的SDK。

并发可视化工具的使用比较简单,分析 > 并发可视化工具 > 从当前项目开始/启动新进程,启动新进程的话就选择我们要检测的 .exe 文件。

程序运行完之后就会输出报告。

使用率视图

使用率输出进程使用的平均逻辑核心数,这里逻辑核心数上限是 12 那么实际核心数就是 6,如果两个内核在某一给定时间段内均以 50% 的使用率运行,则此视图将显示使用一个逻辑内核。

CPU 使用率图颜色:

  • 绿色表示系统中当前进程的逻辑内核使用率
  • 浅灰色表示系统上其他进程的逻辑内核利用率。如果 CPU 图中的浅灰色百分比过高,则表示其他进程已使系统负载过重,你的进程可能会被这些进程抢占资源。若要减少其他进程使用的逻辑内核数,请减少系统上运行的逻辑内核数。
  • 深灰色表示系统进程的逻辑内核消耗。无法直接控制这部分逻辑内核消耗,但由于这些消耗会影响用户进程可以使用的逻辑内核情况,因此了解这些消耗何时出现非常有用。
  • 白色表示系统上未使用逻辑内核的可用性。如果可以找到更多的并行机会,这些核心则可用于你的进程。

线程视图

左上角选项卡选择线程视图

线程视图上半部分是时间线,时间线显示主计算机上的进程与所有物理磁盘设备中的所有线程的活动。它还显示 GPU 活动和标记事件。

在时间线上,X 轴上是时间,y 轴上是几个通道:

  • 系统上每个磁盘驱动器两个 I/O 通道,一个通道用于读取,另一个用于写入
  • 进程中每个线程一个通道
  • 标记通道(如果跟踪中存在事件标记)。标记通道最初出现在生成这些事件的线程通道下。
  • GPU 通道。

最初,线程按创建顺序进行排序,以便主应用线程处于第一位。在“排序依据”下拉列表中选择另一个选项,以按另一种标准(例如“执行”)对线程进行排序。

时间线的颜色指示线程在给定时间的状态”

  • 绿色段表示已在执行
  • 红色段指示已因同步而受阻
  • 黄色段指示已被抢占
  • 紫色段指示已参与设备 I/O

左侧有线程通道,停在通道名称处时,将显示给定线程的开始函数。并发可视化工具可检测到多种线程。下表列出了最常用的线程类型。

线程描述
主线程启动应用的线程
工作线程由应用程序主线程创建的线程
CLR工作线程由公共语言运行时(CLR)创建的工作线程
调试器帮助程序由 Visual Studio 调试器创建的帮助线程
ConRT 线程由 Microsoft 并发运行时创建的线程
GDI线程由GDIPlus创建的线程
OLE/RPC 线程作为 RPC工作线程创建的线程
RPC作为RPC线程创建的线程
Winsock 线程作为 Winsock 线程创建的线程
线程池由 CLR 线程池创建的线程

内核视图

并发可视化工具里还有一个内核视图,显示线程执行如何映射到逻辑处理器核心。

与留在同一逻辑核心上的切换相比,跨核心上下文切换要花费更多的开销和性能。在上下文切换过程中,将保存并恢复处理器寄存器,执行操作系统内核代码,重新加载转换旁视缓冲项,并刷新处理器管道。因为缓存数据对其他核心上的此线程无效,所以跨核心上下文切换可能比其他上下文切换开销更大。相比之下,如果某个线程上下文切换到之前运行过的该线程的核心上,则有用的数据可能仍在缓存中。当跨核心上下文切换因试图管理线程关联而有所增加且性能出现下降时,请考虑是否要解决这一问题。首先消除线程关联,然后观察由此导致的跨核心行为。

下表描述了图例元素。

元素定义
线程名显示上一个内核时间线中线程的颜色,以及该线程的名称
跨核心上下文切换也从一个逻辑内核切换到另一个逻辑内核的线程的上下文切换数。 不区分从一个处理器芯片跨到另一个芯片的跨核心上下文切换,以及留在同一芯片上的跨核心上下文切换。
上下文切换总数采样期间给定线程的上下文切换总数。 每次线程更改上下文(例如从执行到同步)时,将进行一次上下文切换计数。
跨越核心的上下文切换所占的百分比通过跨核心上下文切换数除以上下文切换总数计算出的百分比。 此百分比越高,此特定线程的性能上的跨核心上下文切换的开销的整体效果越大。

并发可视化工具SDK

这里介绍一个简单的应用,给我们想要关注的函数部分/代码段打上标记,这样在线程视图中,就能看到对应标记的范围了。
对于带解决方案的应用,直接 分析 > 并发可视化工具 > 将 SDK 添加到项目中,然后在项目中 #include <cvmarkersobj.h>,然后使用对应的命名空间 using namespace Concurrency::diagnostic

然后我们可以添加标记通道,创建对应的对象 marker_series series; 在对应的标记通道中,可以加入一个标志范围,delete 就可以结束这个范围,示例代码如下。

#include <iostream>
#include "cvmarkersobj.h"

#define MAX 10000

using namespace Concurrency::diagnostic;

void func1(int& sum) {
    for (int i = 0; i < MAX; i++)
		sum += i;
}

int getSum() {
	int sum = 0;
	for (int i = 0; i < 1000000; i++)
		func1(sum);
	return sum;
}


int main()
{
	marker_series series;
	span* flagSpan = new span(series, 1, _T("flag span"));
	series.write_flag(_T("Here is the flag."));
	int ans = getSum();
	delete flagSpan;

	std::cout << ans << std::endl;

	int ans2 = getSum();
	std::cout << ans2 << std::endl;
}

下面是对应的并发可视化工具视图,可以看到多了一个通道,同时有对应的标志区间。

当然我们也可以创建多个通道。

	marker_series flagSeries(_T("flag series"));
	span* flagSeriesSpan = new span(flagSeries, 1, _T("flag span"));
	flagSeries.write_flag(1, _T("flag"));
	// Sleep to even out the display in the Concurrency Visualizer.
	int ans = getSum();
	Sleep(50);
	delete flagSeriesSpan;
	std::cout << ans << std::endl;

	marker_series messageSeries(_T("message series"));
	span* messageSeriesSpan = new span(messageSeries, 1, _T("message span"));
	messageSeries.write_message(1, _T("message"));
	// Sleep to even out the display in the Concurrency Visualizer.
	int ans2 = getSum();
	Sleep(50);
	delete messageSeriesSpan;
	std::cout << ans2 << std::endl;

这样在视图中就可以看到多个通道和标记区间。


参考资料

通过分析 CPU 使用情况衡量应用程序性能(C#、Visual Basic、C++、F#)
了解探查器性能收集方法
在 Visual Studio(C#、C++、Visual Basic、F#)中检测 .NET 应用程序
内核视图
使用并发可视化工具标记 SDK
“使用率”视图
并发可视化工具中的线程视图

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL】MySQL数据库中密码加密和查询的解决方案

本篇博客是为了记录自己在遇到password函数无法生效时的解决方案。通过使用AES_ENCRYPT(str,key)和AES_DECRYPT(str,key)进行加密和解密。 一、问题 自己想创建一个user表&#xff0c;user表中有一个password属性列&#xff0c;自己想对密码进行加密后再存入数据库&#xff0c…

基于JAVA+SpringBoot+Vue的华府便利店信息管理系统

基于JAVASpringBootVue的华府便利店信息管理系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f3…

GCC 简介

Linux 中的编译器 GCC 的编译原理和使用详解 GCC 简介 GCC&#xff08;GNU Compiler Collection&#xff09;是一套由 GNU 开发的编程语言编译器&#xff0c;它支持多种编程语言&#xff0c;包括 C、C、Objective-C、Fortran、Ada 和 Go 等。GCC 是一个开源的工具集&#xff…

STM32F103C8T6 IO 操作

1.开启相关时钟 在 STM32 微控制器中&#xff0c;开启 GPIO 端口的时钟是确保 IO 口可以正常工作的第一步。 查找 RCC 寄存器使能时钟 在 STM32 中&#xff0c;时钟控制的寄存器通常位于 RCC (Reset and Clock Control) 模块中。不同的 STM32 系列&#xff08;如 STM32F1、STM…

vue3+vite 部署npm 包

公司需要所以研究了一下怎么部署安装&#xff0c;比较简单 先下载个vue项目 不用安准路由&#xff0c;pinna 啥的&#xff0c;只需要一个最简单的模版 删掉App.vue 中的其它组件 npm create vuelatest 开始写自定义组件 新建一个el-text 组件, name是重点&#xff0c;vue3中…

《Python游戏编程入门》注-第3章3

《Python游戏编程入门》的“3.2.4 Mad Lib”中介绍了一个名为“Mad Lib”游戏的编写方法。 1 游戏玩法 “Mad Lib”游戏由玩家根据提示输入一些信息&#xff0c;例如男人姓名、女人姓名、喜欢的食物以及太空船的名字等。游戏根据玩家输入的信息编写出一个故事&#xff0c;如图…

洛谷 P1226:【模板】快速幂

【题目来源】https://www.luogu.com.cn/problem/P1226【题目描述】 给你三个整数 a&#xff0c;b&#xff0c;p&#xff0c;求 a^b mod p。【输入格式】 输入只有一行三个整数&#xff0c;分别代表 a&#xff0c;b&#xff0c;p。【输出格式】 输出一行一个字符串 a^b mod ps&a…

Centos7快速重置root密码

1、重新启动Centos7&#xff0c;5秒内按向下方向键&#xff0c;使其停留在开机界面&#xff0c;如下图。 2、按’e’键&#xff0c;进入如下界面&#xff0c;移动向下方向键至“linux16”开头的行。然后按向右的方向键移动,找到“ro”并将其修改为“rw init/sysroot/bin/bash…

编写一个简单的Iinput_dev框架

往期内容 本专栏往期内容&#xff1a; input子系统的框架和重要数据结构详解-CSDN博客input device和input handler的注册以及匹配过程解析-CSDN博客input device和input handler的注册以及匹配过程解析-CSDN博客 I2C子系统专栏&#xff1a; 专栏地址&#xff1a;IIC子系统_憧憬…

使用 NumPy 和 Matplotlib 进行高级数据可视化:实践指南

使用 NumPy 和 Matplotlib 进行高级数据可视化&#xff1a;实践指南 数据科学和工程实践中&#xff0c;NumPy 和 Matplotlib 是强大的组合工具。本文将进一步展示如何借助这两个库进行更复杂的可视化任务&#xff0c;例如创建多曲线、叠加图、动态可视化等场景。 一、环境准备…

Crowd Counting 系列NO4.—SwitchCNN(CVPR 2017)网络复现

文章目录 引言简介环境配置1、numpy 安装2、matplotlib 安装3、cv2 安装&#xff0c;即opencv-python安装4、scipy 安装5、theano安装7、flip_filters不再支持 数据问题密度图生成注意 引言 SwitchCNN是我看的比较早的一篇多列密集计数网络了&#xff0c;但是其网络实现因各种…

漏洞挖掘 | 基于mssql数据库的sql注入

前记 今天挖edu随意点开个站&#xff0c;发现存在mssql数据库的sql注入&#xff0c;在此分享下整个挖掘过程 目录 0x1 判断网站数据库类型 0x2 了解mssql数据库的主要三大系统表 0x3 了解mssql的主要函数 0x4 判断注入点及其注入类型 0x5 联合查询之判断列数 0x6 联合查询之…

Redis 哨兵 总结

前言 相关系列 《Redis & 目录》&#xff08;持续更新&#xff09;《Redis & 哨兵 & 源码》&#xff08;学习过程/多有漏误/仅作参考/不再更新&#xff09;《Redis & 哨兵 & 总结》&#xff08;学习总结/最新最准/持续更新&#xff09;《Redis & 哨兵…

【成长day】NeRF学习记录1:预备知识nerf论文算法学习

个人知乎文章链接&#xff1a;https://zhuanlan.zhihu.com/p/3383996241 预备知识 NeRF重建 NeRF的全称是Neural Radiance Fields&#xff0c;即将场景表示为视场合成的神经辐射场&#xff0c;用神经网络来拟合辐射场&#xff0c;实现对三维场景的隐式表示。本质是完成了图形…

[项目详解][boost搜索引擎#2] 建立index | 安装分词工具cppjieba | 实现倒排索引

目录 编写建立索引的模块 Index 1. 设计节点 2.基本结构 3.(难点) 构建索引 1. 构建正排索引&#xff08;BuildForwardIndex&#xff09; 2.❗构建倒排索引 3.1 cppjieba分词工具的安装和使用 3.2 引入cppjieba到项目中 倒排索引代码 本篇文章&#xff0c;我们将继续项…

Android——事件冲突处理

当我们给列表的item设置了点击事件后&#xff0c;又给item中的按钮设置了点击事件&#xff0c;此时item的点击事件会失效。 解决 给item的布局xml中设置以下属性 android:descendantFocusability"blocksDescendants"<LinearLayout xmlns:android"http://sc…

005:航空力学基础、无人机操纵、飞机性能

摘要&#xff1a;本文详细介绍无人机稳定性、操控性、飞机性能等概念。 一、飞机的稳定性 概念&#xff1a; 飞机的稳定性&#xff08;安定性&#xff09;&#xff0c;是指在飞机受到扰动后&#xff0c;不经飞行员操纵&#xff0c;能恢复到受扰动前的原始状态&#xff08;即原…

Android系统架构

Android系统架构&#xff1a; Android系统架构是一个复杂的、分层的结构&#xff0c;旨在提供高度的灵活性和可扩展性。这个架构可以大致分为以下几个主要层次&#xff1a; Linux Kernel&#xff08;Linux内核&#xff09;&#xff1a; Linux内核是Android系统的底层&#xff0…

OAK相机的RGB-D彩色相机去畸变做对齐

▌低畸变标准镜头的OAK相机RGB-D对齐的方法 OAK相机内置的RGB-D管道会自动将深度图和RGB图对齐。其思想是将深度图像中的每个像素与彩色图像中对应的相应像素对齐。产生的RGB-D图像可以用于OAK内置的图像识别模型将识别到的2D物体自动映射到三维空间中去&#xff0c;或者产生的…

OpenSSL

OpenSSL 概述 OpenSSL 是一个开源的、安全传输协议实现工具&#xff0c;广泛应用于数据加密与解密、证书生成与管理以及其他安全性相关的任务。在现代网络安全中&#xff0c;OpenSSL 被用于构建和维护 SSL/TLS 通信&#xff0c;确保数据在传输过程中的机密性和完整性。 简单来…