当perf stat -e branches 是统计

再看perf record,perf record是为了是记录时间发生的时候的调用栈,

在我的测试代码中总共有200,000,000条branch的命令,但是为啥我只看到了1964这样一个数量级的采样呢?

perf record设置了采样的频率吗?

发现了和sample_freq相关,这个sample_freq是干啥的?

表示我一秒钟采样多少次,但是这里有个问题,原来系统默认的采样频率是4000,那么这里就涉及到了所有管控涉及到的采样频率的问题了。如果这个进程在采样周期内都只发生了三次的branch事件,

采样频率是4000是什么意思?是时间计数器溢出吗?采样的频率是怎么定的?一条指令每秒中连4000条指令都不到这个就说不过去了,

应该cycles:pp是什么意思?

那么问题就来了,对于 cycles来说还能做采样,对于branches事件来说,要怎么做采样呢?因为CPU的时钟周期是固定的,但是branchs这些事件却不是固定的,所以对于函数来说,cycles在一个时钟周期内是均匀的,只要做一个溢出就可以采集到事件,那么在perf record的指令来说,perf record -e branches又有什么实际的物理意义呢?

-e中指定的事件: -e branches,确实会导致文件系统中记录下这个值的,使用perf report的时候会告诉你这个事件发生了多少次,但是

采样的频率是比较难以理解的,看下相关的源码,在perf系统调用中国sample_period中记录的是

sample_freq中是啥子呢

采样的事件放在哪里?

  1. 98 enum perf_hw_id {
  2. 99 /*
  3. 100 * Common hardware events, generalized by the kernel:
  4. 101 */
  5. 102 PERF_COUNT_HW_CPU_CYCLES = 0,
  6. 103 PERF_COUNT_HW_INSTRUCTIONS = 1,
  7. 104 PERF_COUNT_HW_CACHE_REFERENCES = 2,
  8. 105 PERF_COUNT_HW_CACHE_MISSES = 3,
  9. 106 PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
  10. 107 PERF_COUNT_HW_BRANCH_MISSES = 5,
  11. 108 PERF_COUNT_HW_BUS_CYCLES = 6,
  12. 109 };

到了真正的函数x86_pmu_hw_config,我们发现竟然在这里还有 event->hw.config = ARCH_PERFMON_EVENTSEL_INT;

直接就是

  1. 20 #define ARCH_PERFMON_EVENTSEL_EVENT 0x000000FFULL
  2. 21 #define ARCH_PERFMON_EVENTSEL_UMASK 0x0000FF00ULL
  3. 22 #define ARCH_PERFMON_EVENTSEL_USR (1ULL << 16)
  4. 23 #define ARCH_PERFMON_EVENTSEL_OS (1ULL << 17)
  5. 24 #define ARCH_PERFMON_EVENTSEL_EDGE (1ULL << 18)
  6. 25 #define ARCH_PERFMON_EVENTSEL_PIN_CONTROL (1ULL << 19)
  7. 26 #define ARCH_PERFMON_EVENTSEL_INT (1ULL << 20)
  8. 27 #define ARCH_PERFMON_EVENTSEL_ANY (1ULL << 21)
  9. 28 #define ARCH_PERFMON_EVENTSEL_ENABLE (1ULL << 22)
  10. 29 #define ARCH_PERFMON_EVENTSEL_INV (1ULL << 23)
  11. 30 #define ARCH_PERFMON_EVENTSEL_CMASK 0xFF000000ULL
  12. 31

硬件事件和相应的寄存器id之间的映射关系

  1. 25 * Intel PerfMon, used on Core and later.
  2. 26 */
  3. 27 static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly =
  4. 28 {
  5. 29 [PERF_COUNT_HW_CPU_CYCLES] = 0x003c,
  6. 30 [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
  7. 31 [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e,
  8. 32 [PERF_COUNT_HW_CACHE_MISSES] = 0x412e,
  9. 33 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
  10. 34 [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
  11. 35 [PERF_COUNT_HW_BUS_CYCLES] = 0x013c,
  12. 36 [PERF_COUNT_HW_REF_CPU_CYCLES] = 0x0300, /* pseudo-encoding */
  13. 37 };

最终最关键的是都合入到了hw.config中去了,

采样了五千次,这五千次都是从哪里来的?

  1. 0xffffffff811834a0 : perf_prepare_sample+0x0/0x350 [kernel]
  2. 0xffffffff8118381f : perf_event_output+0x2f/0x80 [kernel]
  3. 0xffffffff81183a1f : __perf_event_overflow+0x1af/0x1d0 [kernel]
  4. 0xffffffff811844d4 : perf_event_overflow+0x14/0x20 [kernel]
  5. 0xffffffff8100c4b1 : intel_pmu_handle_irq+0x1e1/0x460 [kernel]
  6. 0xffffffff810056bd : perf_event_nmi_handler+0x2d/0x50 [kernel]
  7. 0xffffffff810323a9 : nmi_handle+0x69/0x120 [kernel]
  8. 0xffffffff810328e0 : default_do_nmi+0x40/0x100 [kernel]
  9. 0xffffffff81032a82 : do_nmi+0xe2/0x130 [kernel]
  10. 0xffffffff81826906 : nmi+0x56/0xa5 [kernel]
  11. -

所以branch事件看来仅仅是是为了作统计用的,真正负责采样的或许仍然是cycles事件, intel_pmu_handle_irq事件;

所以他妈的采样的频率和采样的事件无关,有了-e感觉perf_event_

output会增多,有采样的事件,有收集的事件,待会验证一下

看下采样的频率是如何收集到设置器里的

PMU计数器如何设置溢出,到底这个频率是怎么设置的呀,

抓到了一个关键的函数:x86_perf_event_set_period

关键函数:x86_perf_event_set_period,这个函数中会涉及到参数perf_event->hw_perf_event->sample_period,在这个结构体会出现下个函数的值。

perf_event_overflow是啥东西

perf_calculate_period 函数应该是最终的算周期的函数了,所有

在perf_adjust_period中会调整hwc->sample_period的数值

发现换成不同的事件,event->hwc->sample_period竟然不是一样的!

sample_period中存储是多少条指令发生一次溢出事件! 

这里采样的算法是多么的精妙啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

发现啥东西了吗?这里的采样就像是tcp的包发送一样,逐渐地试探,这里所说的-F 1000,都是指我这个进程的执行周期,说白了就是perf_clock,最关键的函数就是perf_adjust_period,看一下这些函数都是怎么收敛的:

-C是指进程的执行周期内的采样,先看下采样的算法,

如果这个进程还有线程呢,这个待会测试一下,有几个问题需要解决,首先这些采样的周期如何在不同的core上分配

在我这个进程执行的1s之内我要做1000次采样,首先我将计数器设置为1,然后发现在10us的时候这个值溢出了,说明我在branches上设置了1,这个值就溢出了,溢出说明了这个计数器的值,我设置的采样的周期是1000, perf_adjust_period函数中perf是通过perf_calculate_period函数来来计算下一个溢出值是多少,溢出总会有一个时间,我们发现对于

是什么意思?perf_adjust_period函数中中:

  1. if (event->attr.freq) {
  2. u64 now = perf_clock(); // ns granularity
  3. s64 delta = now - hwc->freq_time_stamp;
  4.  
  5. hwc->freq_time_stamp = now;
  6.  
  7. if (delta > 0 && delta < 2*TICK_NSEC)
  8. perf_adjust_period(event, delta, hwc->last_period, true);
  9. }

上面说明了啥,上面的函数中 delta是时间片溢出的绝对的时间,这里是

刚开始启动的时候都是不均匀的,刚开始的sample_period

什么时候会adjust_period,只有在中断溢出的时候!!!!

adjust的地方只会修改sample,但是真正设置这个溢出值的地方是x86_perf_event_set_period,所以这里的溢出的事件啊,怎么样调整的周期

其中perf_clock调用的是sched_clock,也就是说,这里只计算我这个调度实体的调度时间!!!!!!!!!!!

整个perf里大量运用到了估计值,我到底应该在什么时候发生溢出?如果是cycles这种还好说,但是如果是branches这样的呢?根本就没有办法估计,所以我只能根据历史信息去估计;啥子历史信息呢?

我的采样周期是10^9/freq,在上一个溢出周期中,我的溢出值设置的多少,然后溢出的时间是多少,那么一个很简单的比例的关系就出来了 

A=10^9/freq A/period = lastduration/lastperiod,这样我们想要求的period就是我们想要的下次的溢出值了嘛。这样就能达到一个大约的统计值了;

  1. 892316 x86_perf_event_set_period 4 sample_period(1 0x1)
  2. 10626 x86_perf_event_set_period 5 sample_period(1 0x1)
  3. 115968 x86_perf_event_set_period 6 sample_period(1 0x1)
  4. 4052 x86_perf_event_set_period 7 sample_period(1 0x1)
  5. 37069 x86_perf_event_set_period 8 sample_period(2 0x2)
  6. 3104 x86_perf_event_set_period 9 sample_period(2 0x2)
  7. 29846 x86_perf_event_set_period 10 sample_period(8 0x8)
  8. 3093 x86_perf_event_set_period 11 sample_period(8 0x8)
  9. 29394 x86_perf_event_set_period 12 sample_period(38 0x26)
  10. 3270 x86_perf_event_set_period 13 sample_period(38 0x26)
  11. 3788 x86_perf_event_set_period 14 sample_period(179 0xb3)
  12. 3821 x86_perf_event_set_period 15 sample_period(5996 0x176c)
  13. 36838 x86_perf_event_set_period 16 sample_period(194467 0x2f7a3)
  14. 22025 x86_perf_event_set_period 17 sample_period(194467 0x2f7a3)
  15. 34085 x86_perf_event_set_period 18 sample_period(583293 0x8e67d)
  16. 248057 x86_perf_event_set_period 19 sample_period(583293 0x8e67d)
  17. 20792 x86_perf_event_set_period 20 sample_period(583293 0x8e67d)
  18. 20943 x86_perf_event_set_period 21 sample_period(1 0x1)
  19. 4852 x86_perf_event_set_period 22 sample_period(1 0x1)
  20. 736460 x86_perf_event_set_period 23 sample_period(11600 0x2d50)
  21. 27806 x86_perf_event_set_period 24 sample_period(11600 0x2d50)
  22. 25194 x86_perf_event_set_period 25 sample_period(12048 0x2f10)
  23. 25422 x86_perf_event_set_period 26 sample_period(70082 0x111c2)
  24. 165045 x86_perf_event_set_period 27 sample_period(407591 0x63827)
  25. 800145 x86_perf_event_set_period 28 sample_period(665214 0xa267e)
  26. 1569057 x86_perf_event_set_period 29 sample_period(685995 0xa77ab)
  27. 1327410 x86_perf_event_set_period 30 sample_period(654895 0x9fe2f)
  28. 45090 x86_perf_event_set_period 31 sample_period(614171 0x95f1b)
  29. 24029926 x86_perf_event_set_period 32 sample_period(614171 0x95f1b)
  30. 1411250 x86_perf_event_set_period 33 sample_period(614171 0x95f1b)
  31. 1387908 x86_perf_event_set_period 34 sample_period(614171 0x95f1b)
  32. 1187035 x86_perf_event_set_period 35 sample_period(572970 0x8be2a)
  33. 15984867 x86_perf_event_set_period 36 sample_period(572970 0x8be2a)
  34. 265346 x86_perf_event_set_period 37 sample_period(572970 0x8be2a)
  35. 1365152 x86_perf_event_set_period 38 sample_period(572970 0x8be2a)
  36. 1392381 x86_perf_event_set_period 39 sample_period(553815 0x87357)

perf使用的问题,再看perf record,perf record 设置的采样频率,采样频率是如何体现在的更多相关文章

  1. 再看Ajax

    再回顾Ajax相关的内容,再次梳理学习还是很有必要的,尤其是实际的开发中,ajax更是必不可少,仔细学习以便避免不必要的错误. 文章导读: --1.使用XMLHttpRequest---------- ...

  2. 再看ftp上传文件

    前言 去年在项目中用到ftp上传文件,用FtpWebRequest和FtpWebResponse封装一个帮助类,这个在网上能找到很多,前台使用Uploadify控件,然后在服务器上搭建Ftp服务器,在 ...

  3. 再看 AspriseOCR - OCR应用开发 -20151124

    再看 AspriseOCR - OCR应用开发 我写这个博文时间为 2015/11/24日,注意时间因为,网上很多文章时间上很久远,有的已经不能参考了 很多人面对从图片中识别文字或者数字0~9  A~ ...

  4. Android菜鸟的成长笔记(17)—— 再看Android中的Unbounded Service

    原文:Android菜鸟的成长笔记(17)-- 再看Android中的Unbounded Service 前面已经写过关于startService(Unbounded Service)的一篇文章:&l ...

  5. 再看case语句

    再看case语句,case语句只处理单条记录,而不是set 列名的使用,可以当做数值来使用: case when 后面简直是完美的的,什么东西都是能放的,只要是一个逻辑上的true/false的逻辑就 ...

  6. android 智能指针的学习先看邓凡平的书扫盲 再看前面两片博客提升

    android 智能指针的学习先看邓凡平的书扫盲 再看前面两片博客提升

  7. python基础----再看property、描述符(__get__,__set__,__delete__)

    一.再看property                                                                          一个静态属性property ...

  8. 再看Scrapy(1) 基本概念

    再看Scrapy(1) 基本概念 1 准备 安装scrapy: 国内镜像源(官方的pypi不稳定)安装 pip3 install -i https://pypi.douban.com/simple/ ...

  9. 再看GS接包过程

    再看GS接包过程 bool GameServer::ProcessLoop(packet& rPkt) { if(false == m_spDataLayer->Recv(rPkt)) ...

随机推荐

  1. 156. Merge Intervals【LintCode by java】

    Description Given a collection of intervals, merge all overlapping intervals. Example Given interval ...

  2. 堪称最好的A*算法(转)

    如此好贴,不能不转!原文地址:http://dev.gameres.com/Program/Abstract/Arithmetic/AmitAStar.mht 中文译文转自:http://blog.c ...

  3. 成都Uber优步司机奖励政策(1月24日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. C++三元操作符

    c++的三元操作符形式: //条件表达式 ? 表达式1 : 表达式2; 语义:如果“条件表达式”为true,则整个表达式的值就是表达式1,忽略表达式2:如果“条件表达式”为false,则整个表达式的值 ...

  5. 创龙DSP6748学习之RS485收发

    1. 先看下原理图,第一个问题,RS485其实就是使用的串口USART1,同时485的输出脚之间接120欧姆的电阻. 遇到个问题,为什么有两个使能引脚?还有RS485_A和RS485_B为什么分别接上 ...

  6. 韩国KT软件NB-IOT开发记录V150(2)FOTA差分包生成

    1. 生成差分包

  7. jenkins通过maven指定testng的xml文件,并给testng代码传参

    1.jenkins设置参数化构建,设置要传的参数名和值 2.指定testng的xml文件,在jenkins的输入以下 3.在pom.xml文件分别引用jenkins的参数,设置两个property & ...

  8. create-react-app创建react项目 css模块化处理

    用的css预处理器用sass,其他大同小异. 用create-react-app创建项目,执行npm run eject弹出配置文件(此操作不可逆): 配置sass,用的最新的CRA,webpack4 ...

  9. 第5章 Linux网络编程基础

    第5章 Linux网络编程基础 5.1 socket地址与API 一.理解字节序 主机字节序一般为小端字节序.网络字节序一般为大端字节序.当格式化的数据在两台使用了不同字节序的主机之间直接传递时,接收 ...

  10. Spring 配置String转Date

    操作步骤: 1. 实现 org.springframework.core.convert.converter.Converter 接口 2. 配置 org.springframework.contex ...