perf 中的 cpu-cycles event 介绍

perf 中的 cpu-cycles event 介绍

cycles简介

cycles事件记录处理器核心执行的时钟周期数。每个时钟周期代表处理器内部时钟振荡器的一个周期。这个事件通常用于衡量处理器的执行速度,因为它直接反映了指令执行所需的时间。一个较高的cycles计数可能意味着代码执行较慢,因为需要更多的时钟周期来完成任务。

instructions 和 cycles的关系

instructions事件则记录处理器执行的指令数。这通常用来评估指令级别的效率,因为它显示了程序执行了多少条指令。如果一条指令需要多个时钟周期来执行,那么instructions与cycles之间的比率可以用来估算指令级的效率。一个较低的instructions/cycle比率表示更高的指令级并行性或更有效的代码。

在性能分析中,通常会关注这两个指标的比值,即instructions per cycle (IPC),来评估代码的执行效率。IPC越高,表示每时钟周期执行的指令越多,程序的执行效率也就越高。如果一个程序的IPC下降,可能是因为出现了分支预测错误、内存访问延迟或其他性能瓶颈。

perf cycles 分析

看环境是否支持 cycles 采集

[root@localhost ~]# perf list | grep cycles
...cpu-cycles OR cycles                               [Hardware event]
...

查看当前环境cpu频率: 2.6GHz

[root@localhost ~]# cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
2600000

写一个简单的程序,让cpu利用率跑100%:

// test.cpp
int main() {while(1);return 0;
}
[root@localhost ~]# g++ test.cpp -o test
[root@localhost ~]# ./test
[root@localhost ~]# perf stat -e cycles -p `pidof test` sleep 1Performance counter stats for process id '515011':2,601,831,429      cycles1.000756985 seconds time elapsed

可以看出这个值近似等于2.6G

进一步测试

写一个程序,让控制cpu利用率在20%左右

#include <iostream>
#include <chrono>
#include <unistd.h>int main() {int ratio = 20;int base_time = 1000;int sleeptime = base_time * (100-ratio);int runtime = base_time * ratio;while(true) {auto start = std::chrono::high_resolution_clock::now();while(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - start).count() < runtime) {}usleep(sleeptime);}return 0;
}

[root@localhost ~]# perf stat -e cycles -p `pidof test` sleep 1Performance counter stats for process id '515142':520,289,676      cycles1.000767149 seconds time elapsed

520,289,676/2,601,831,429=0.199
可以看出,结合cycles 和 系统频率可以换算出cpu利用率,利用perf采集各个线程的cycles,可以计算这个线程的负载。

采用perf record 的 方式

控制采集频率为 50Hz

[root@localhost ~]# perf record -h-a, --all-cpus        system-wide collection from all CPUs-c, --count <n>       event period to sample-e, --event <event>   event selector. use 'perf list' to list available events-F, --freq <freq or 'max'>profile at this frequency
[root@localhost ~]# perf record -e cycles -F 1  -p `pidof test`  sleep 50
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.014 MB perf.data (12 samples) ]
[root@localhost ~]# perf script -i perf.datatest 515142 4507231.759994:          1 cycles:  ffff50d8eeff379c finish_task_switch+0x74 ([kernel.kallsyms])test 515142 4507231.759996:          1 cycles:  ffff50d8eeff379c finish_task_switch+0x74 ([kernel.kallsyms])test 515142 4507231.759997:          1 cycles:  ffff50d8eeff379c finish_task_switch+0x74 ([kernel.kallsyms])test 515142 4507231.760015:      45456 cycles:      ffff904e03cc __kernel_clock_gettime+0xcc ([vdso])test 515142 4507243.582136: 6176126731 cycles:            400a40 std::chrono::operator-<long, std::ratio<1l, 1000000000l>, long, std::ratio<1l, 1000000000l> >+0x58 (/home/test)test 515142 4507248.582382: 2593218597 cycles:            4009d4 std::chrono::duration<long, std::ratio<1l, 1000000l> >::count+0x4 (/home/test)test 515142 4507253.582381: 2592326656 cycles:            400a28 std::chrono::operator-<long, std::ratio<1l, 1000000000l>, long, std::ratio<1l, 1000000000l> >+0x40 (/home/test)test 515142 4507258.581960: 2591492485 cycles:      ffff904e03f4 __kernel_clock_gettime+0xf4 ([vdso])test 515142 4507263.581284: 2591325615 cycles:            400a28 std::chrono::operator-<long, std::ratio<1l, 1000000000l>, long, std::ratio<1l, 1000000000l> >+0x40 (/home/test)test 515142 4507268.580381: 2590221715 cycles:      ffff904e03e4 __kernel_clock_gettime+0xe4 ([vdso])test 515142 4507273.501923: 2596489317 cycles:            400964 std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long, std::ratio<1l, 1000000000l> > >::time_since_epoch+0x4 (>test 515142 4507278.502390: 2594059695 cycles:      ffff904e040c __kernel_clock_gettime+0x10c ([vdso])

以1Hz的频率采样,可以看出,当perf稳定下来后,cycles稳定在 2.59e6,相邻的数据事件间隔5s,换算过后,也是相当于20%的cpu占用率。但是这似乎与我的预期不符,我的程序1s中实际会在运行状态下多次,理论上每秒都会采到,采样率1Hz,cpu利用率,采样时间50s, 实际的样本个数才有12个,似乎是 样本个数约等于采样间隔 * 采样频率 * 线程cpu利用率。

通过此方法计算线程的利用率,必须考虑时间戳,或者计算的周期要比采样周期大很多,如果采样1s,每1s计算下占用率,那么就会出现每5s的计算的线程占用率100%,其余是0%;

将程序绑在 core 10 上运行,观察现象。现象基本一致。

[root@localhost ~]# perf record -e cycles -F 1  -C 10  sleep 50
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.417 MB perf.data (11 samples) ]
[root@localhost ~]# perf script -i perf.datatest 515307 [010] 4509711.079092:          1 cycles:            400a10 std::chrono::operator-<long, std::ratio<1l, 1000000000l>, long, std::ratio<1l, 1000000000l> >+0x28 (/home/test)test 515307 [010] 4509711.079094:          1 cycles:            400a10 std::chrono::operator-<long, std::ratio<1l, 1000000000l>, long, std::ratio<1l, 1000000000l> >+0x28 (/home/test)test 515307 [010] 4509711.079095:          1 cycles:            400a10 std::chrono::operator-<long, std::ratio<1l, 1000000000l>, long, std::ratio<1l, 1000000000l> >+0x28 (/home/test)test 515307 [010] 4509711.079121:      67206 cycles:      fffd5d4503f4 __kernel_clock_gettime+0xf4 ([vdso])test 515307 [010] 4509726.498642: 8000773091 cycles:      fffd5d4503f4 __kernel_clock_gettime+0xf4 ([vdso])test 515307 [010] 4509731.213642: 2447049195 cycles:      fffd5d4503e0 __kernel_clock_gettime+0xe0 ([vdso])test 515307 [010] 4509736.170329: 2574579536 cycles:      fffd5d4503e4 __kernel_clock_gettime+0xe4 ([vdso])test 515307 [010] 4509741.066237: 2540232188 cycles:      fffd5d4503f4 __kernel_clock_gettime+0xf4 ([vdso])test 515307 [010] 4509746.031759: 2575910682 cycles:      fffd5d2f9ba0 clock_gettime@plt+0x0 (/usr/lib64/libstdc++.so.6.0.24)test 515307 [010] 4509750.937614: 2546808087 cycles:      fffd5d45040c __kernel_clock_gettime+0x10c ([vdso])test 515307 [010] 4509755.894792: 2574924584 cycles:            400878 main+0x74 (/home/test)

以固定周期数采样

[root@localhost ~]# perf record -e cycles -c 520000000  -p `pidof test` sleep 10
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.014 MB perf.data (9 samples) ]
[root@localhost ~]# perf script -i perf.datatest 515307 4510198.258890:  520000000 cycles:            400a94 std::chrono::__duration_cast_impl<std::chrono::duration<long, std::ratio<1l, 1000000l> >, std::ratio<1l, 1000l>, long, true, false>::__cast<long, std::ratio<1l, 1000000000l> >>test 515307 4510199.263843:  520000000 cycles:      fffd5d4503e4 __kernel_clock_gettime+0xe4 ([vdso])test 515307 4510200.268764:  520000000 cycles:      fffd5d4503f4 __kernel_clock_gettime+0xf4 ([vdso])test 515307 4510201.273860:  520000000 cycles:      fffd5d325304 std::chrono::_V2::system_clock::now+0x4c (/usr/lib64/libstdc++.so.6.0.24)test 515307 4510202.278955:  520000000 cycles:            400a8c std::chrono::__duration_cast_impl<std::chrono::duration<long, std::ratio<1l, 1000000l> >, std::ratio<1l, 1000l>, long, true, false>::__cast<long, std::ratio<1l, 1000000000l> >>test 515307 4510203.275996:  520000000 cycles:      fffd5d4503f4 __kernel_clock_gettime+0xf4 ([vdso])test 515307 4510204.281150:  520000000 cycles:      fffd5d4503f4 __kernel_clock_gettime+0xf4 ([vdso])test 515307 4510205.286123:  520000000 cycles:      fffd5d4503f4 __kernel_clock_gettime+0xf4 ([vdso])test 515307 4510206.291034:  520000000 cycles:            400ab0 std::chrono::duration<long, std::ratio<1l, 1000000l> >::duration<long, void>+0x14 (/home/test)

这样每秒都可以采到。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

到东莞樟木头“中国作家第一村”来!这里大有文“樟”

樟木头&#xff0c;古称泰安&#xff0c;一直是康泰平安、物阜民丰之地。作为东莞唯一纯客家镇&#xff0c;传自中原先民的烂漫因子让这座城市崇文重礼&#xff0c;绿水青山更氤氲出古镇芳华。这个文章锦绣地&#xff0c;以其敢为人先、勇立潮头的姿态&#xff0c;成为了各种文…

JS代码随想录(一):数组

代码随想录 一、数组理论基础 二、LeetCode 704. 二分查找 三、LeetCode 27. 移除元素 四、LeetCode 977.有序数组的平方 五、LeetCode 209.长度最小的子数组 六、LeetCode 59.螺旋矩阵II 七、数组总结 一、数组理论基础 数组是存放在连续内存空间上的相同类型数据的集合。 数组…

操作系统基础之磁盘

概述 基本概念 磁盘有正反两个盘面&#xff0c;每个盘面有多个同心圆&#xff0c;每个同心圆是一个磁道&#xff0c;每个同心圆又被划分为多个扇区&#xff0c;数据就被存在扇区中。 磁头首先寻找到对应磁道&#xff0c;然后等到磁盘进行周期旋转到指定的扇区&#xff0c;才…

redis深入理解之数据存储

1、redis为什么快 1&#xff09;Redis是单线程执行&#xff0c;在执行时顺序执行 redis单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的&#xff0c;Redis在处理客户端的请求时包括获取(socket 读)、解析、执行、内容返回 (socket 写)等都由一个顺序串行的主线…

代码审计-php篇之某CRM系统多处sql注入

&#x1f31f; ❤️ 作者&#xff1a;yueji0j1anke 首发于公号&#xff1a;剑客古月的安全屋 字数&#xff1a;3516 阅读时间: 35min 声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果…

【Python】PYQT5详细介绍

本专栏内容为&#xff1a;Python学习专栏 通过本专栏的深入学习&#xff0c;你可以了解并掌握Python。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;Python &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &#x1f3…

【C语言】路漫漫其修远兮,深入[指针]正当下

目录 一. 指针初步 1.概念定义 2.基本运算符 • 取地址操作符&#xff08;&&#xff09; • 解引⽤操作符 &#xff08;*&#xff09; 3.指针变量的⼤⼩ 二. 指针运算 1.指针- 整数 2.指针 - 指针 3.指针的关系运算 三. 野指针 1.野指针成因 • 指针未初始化 • …

详解drop,delete,truncate区别

在SQL中&#xff0c;"DROP"、"DELETE"和"TRUNCATE"是用于删除数据的不同命令&#xff0c;它们之间有一些重要的区别&#xff1a; DROP&#xff1a; DROP用于删除数据库对象&#xff0c;例如删除表、视图、索引、触发器等。使用DROP删除的对象将…

IPv6资产测绘哪家强?揭秘新一代网络空间资产测绘平台的独门秘籍

网络空间资产测绘&#xff0c;即通过一系列技术手段&#xff0c;对网络中的各类资产进行全面的发现、分类和定位&#xff0c;为各类用户提供精准的数据支撑和决策依据。网络空间资产测绘作为一门新兴的交叉学科&#xff0c;融合了计算机网络技术、数据挖掘、人工智能、信息安全…

电商中差评客服回复话术技巧

在电商行业&#xff0c;中差评是难以避免的现象&#xff0c;它们可能源于产品问题、物流延误、顾客期望与实际不符等多种原因。对于运营和客服团队来说&#xff0c;有效应对中差评不仅能够挽回客户的信任&#xff0c;还能提升品牌形象和服务质量。因此&#xff0c;掌握一些中差…

Stable Diffusion教程|图生图原理和实战

Stable Diffusion凭借其卓越的图生图功能&#xff0c;极大地提升了图像生成的可控性与输出品质&#xff0c;赋予用户前所未有的个性化创作风格表达能力。这一革新特性使得Stable Diffusion不仅能精准地捕捉用户的艺术愿景&#xff0c;更能以数字化手段孕育出新颖且极具创意的画…

浅谈运维数据安全

在数字化日益深入的今天&#xff0c;运维数据安全已经成为企业信息安全体系中的核心要素。运维工作涉及到企业信息系统的各个方面&#xff0c;从硬件维护到软件升级&#xff0c;从网络配置到数据备份&#xff0c;无一不需要严谨的数据安全保障措施。本文将从运维数据安全的重要…