linux – perf在用户和内核级别测量事件的选项是什么意思?

前端之家收集整理的这篇文章主要介绍了linux – perf在用户和内核级别测量事件的选项是什么意思?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Linux perf工具提供对cpu事件计数器的访问.它允许您指定要计数的事件以及何时计算这些事件.

https://perf.wiki.kernel.org/index.php/Tutorial

By default,events are measured at both user and kernel levels:

perf stat -e cycles dd if=/dev/zero of=/dev/null count=100000

To measure only at the user level,it is necessary to pass a modifier:

perf stat -e cycles:u dd if=/dev/zero of=/dev/null count=100000

To measure both user and kernel (explicitly):

perf stat -e cycles:uk dd if=/dev/zero of=/dev/null count=100000

从这一点开始,我预计这些周期:你的意思是“只运行非内核代码时才计算事件”,记录的计数不会映射到内核符号,但似乎并非如此.

这是一个例子:

  1. perf record -e cycles:u du -sh ~
  2. [...]
  3. perf report --stdio -i perf.data
  4. [...]
  5. 9.24% du [kernel.kallsyms] [k] system_call
  6. [...]
  7. 0.70% du [kernel.kallsyms] [k] page_fault
  8. [...]

如果我这样做但使用循环:uk然后我会报告更多的内核符号,所以事件修饰符确实有效.使用周期:k生成几乎只有内核符号的报告,但它确实包含一些libc符号.

这里发生了什么?这是预期的行为吗?我是否误解了链接文档中使用的语言?

链接文档还包括此表,如果有帮助,则使用略有不同的描述:

06001

编辑:更多信息:

cpu是Intel Haswell.具体型号为i7-5820K.

Distro是最新的Arch Linux(滚动版本计划),内核为4.1.6.

perf本身的版本是4.2.0.

EDIT2:

示例运行的输出更多.如您所见,周期:您主要报告非内核符号.我知道当您查看带注释的程序集输出时,perf有时会将错误属性计数到相邻指令.也许这是相关的?

周期:U

  1. # perf record -e cycles:u du -sh ~
  2. 179G /home/khouli
  3. [ perf record: Woken up 1 times to write data ]
  4. [ perf record: Captured and wrote 0.116 MB perf.data (2755 samples) ]
  5. # sudo perf report --stdio -i perf.data
  6. # To display the perf.data header info,please use --header/--header-only options.
  7. #
  8. #
  9. # Total Lost Samples: 0
  10. #
  11. # Samples: 2K of event 'cycles:u'
  12. # Event count (approx.): 661835375
  13. #
  14. # Overhead Command Shared Object Symbol
  15. # ........ ....... ................. ..............................
  16. #
  17. 11.02% du libc-2.22.so [.] _int_malloc
  18. 9.73% du libc-2.22.so [.] _int_free
  19. 9.24% du du [.] fts_read
  20. 9.23% du [kernel.kallsyms] [k] system_call
  21. 4.17% du libc-2.22.so [.] strlen
  22. 4.17% du libc-2.22.so [.] __memmove_sse2
  23. 3.47% du libc-2.22.so [.] __readdir64
  24. 3.33% du libc-2.22.so [.] malloc_consolidate
  25. 2.87% du libc-2.22.so [.] malloc
  26. 1.83% du libc-2.22.so [.] msort_with_tmp.part.0
  27. 1.63% du libc-2.22.so [.] __memcpy_avx_unaligned
  28. 1.63% du libc-2.22.so [.] __getdents64
  29. 1.52% du libc-2.22.so [.] free
  30. 1.47% du libc-2.22.so [.] __memmove_avx_unaligned
  31. 1.44% du du [.] 0x000000000000e609
  32. 1.41% du libc-2.22.so [.] _wordcopy_bwd_dest_aligned
  33. 1.19% du du [.] 0x000000000000e644
  34. 0.93% du libc-2.22.so [.] __fxstatat64
  35. 0.85% du libc-2.22.so [.] do_fcntl
  36. 0.73% du [kernel.kallsyms] [k] page_fault
  37. [lots more symbols,almost all in du...]

周期:英国

  1. # perf record -e cycles:uk du -sh ~
  2. 179G /home/khouli
  3. [ perf record: Woken up 1 times to write data ]
  4. [ext4] with build id 0f47443e26a238299e8a5963737da23dd3530376 not found,continuing without symbols
  5. [ perf record: Captured and wrote 0.120 MB perf.data (2856 samples) ]
  6. # perf report --stdio -i perf.data
  7. # To display the perf.data header info,please use --header/--header-only options.
  8. #
  9. #
  10. # Total Lost Samples: 0
  11. #
  12. # Samples: 2K of event 'cycles:uk'
  13. # Event count (approx.): 3118065867
  14. #
  15. # Overhead Command Shared Object Symbol
  16. # ........ ....... ................. ..............................................
  17. #
  18. 13.80% du [kernel.kallsyms] [k] __d_lookup_rcu
  19. 6.16% du [kernel.kallsyms] [k] security_inode_getattr
  20. 2.52% du [kernel.kallsyms] [k] str2hashbuf_signed
  21. 2.43% du [kernel.kallsyms] [k] system_call
  22. 2.35% du [kernel.kallsyms] [k] half_md4_transform
  23. 2.31% du [kernel.kallsyms] [k] ext4_htree_store_dirent
  24. 1.97% du [kernel.kallsyms] [k] copy_user_enhanced_fast_string
  25. 1.96% du libc-2.22.so [.] _int_malloc
  26. 1.93% du du [.] fts_read
  27. 1.90% du [kernel.kallsyms] [k] system_call_after_swapgs
  28. 1.83% du libc-2.22.so [.] _int_free
  29. 1.44% du [kernel.kallsyms] [k] link_path_walk
  30. 1.33% du libc-2.22.so [.] __memmove_sse2
  31. 1.19% du [kernel.kallsyms] [k] _raw_spin_lock
  32. 1.19% du [kernel.kallsyms] [k] __fget_light
  33. 1.12% du [kernel.kallsyms] [k] kmem_cache_alloc
  34. 1.12% du [kernel.kallsyms] [k] __ext4_check_dir_entry
  35. 1.05% du [kernel.kallsyms] [k] lockref_get_not_dead
  36. 1.02% du [kernel.kallsyms] [k] generic_fillattr
  37. 0.95% du [kernel.kallsyms] [k] do_dentry_open
  38. 0.95% du [kernel.kallsyms] [k] path_init
  39. 0.95% du [kernel.kallsyms] [k] lockref_put_return
  40. 0.91% du libc-2.22.so [.] do_fcntl
  41. 0.91% du [kernel.kallsyms] [k] ext4_getattr
  42. 0.91% du [kernel.kallsyms] [k] rb_insert_color
  43. 0.88% du [kernel.kallsyms] [k] __kmalloc
  44. 0.88% du libc-2.22.so [.] __readdir64
  45. 0.88% du libc-2.22.so [.] malloc
  46. 0.84% du [kernel.kallsyms] [k] ext4fs_dirhash
  47. 0.84% du [kernel.kallsyms] [k] __slab_free
  48. 0.84% du [kernel.kallsyms] [k] in_group_p
  49. 0.81% du [kernel.kallsyms] [k] get_empty_filp
  50. 0.77% du libc-2.22.so [.] malloc_consolidate
  51. [more...]

周期:K

  1. # perf record -e cycles:k du -sh ~
  2. 179G /home/khouli
  3. [ perf record: Woken up 1 times to write data ]
  4. [ext4] with build id 0f47443e26a238299e8a5963737da23dd3530376 not found,continuing
  5. without symbols
  6. [ perf record: Captured and wrote 0.118 MB perf.data (2816 samples) ]
  7. # perf report --stdio -i perf.data
  8. # To display the perf.data header info,please use --header/--header-only options.
  9. #
  10. #
  11. # Total Lost Samples: 0
  12. #
  13. # Samples: 2K of event 'cycles:k'
  14. # Event count (approx.): 2438426748
  15. #
  16. # Overhead Command Shared Object Symbol
  17. # ........ ....... ................. ..............................................
  18. #
  19. 17.11% du [kernel.kallsyms] [k] __d_lookup_rcu
  20. 6.97% du [kernel.kallsyms] [k] security_inode_getattr
  21. 4.22% du [kernel.kallsyms] [k] half_md4_transform
  22. 3.10% du [kernel.kallsyms] [k] str2hashbuf_signed
  23. 3.01% du [kernel.kallsyms] [k] system_call_after_swapgs
  24. 2.59% du [kernel.kallsyms] [k] ext4_htree_store_dirent
  25. 2.24% du [kernel.kallsyms] [k] copy_user_enhanced_fast_string
  26. 2.14% du [kernel.kallsyms] [k] lockref_get_not_dead
  27. 1.86% du [kernel.kallsyms] [k] ext4_getattr
  28. 1.85% du [kernel.kallsyms] [k] kfree
  29. 1.68% du [kernel.kallsyms] [k] __ext4_check_dir_entry
  30. 1.53% du [kernel.kallsyms] [k] __fget_light
  31. 1.34% du [kernel.kallsyms] [k] link_path_walk
  32. 1.34% du [kernel.kallsyms] [k] path_init
  33. 1.22% du [kernel.kallsyms] [k] __kmalloc
  34. 1.22% du [kernel.kallsyms] [k] kmem_cache_alloc
  35. 1.14% du [kernel.kallsyms] [k] do_dentry_open
  36. 1.11% du [kernel.kallsyms] [k] ext4_readdir
  37. 1.07% du [kernel.kallsyms] [k] __find_get_block_slow
  38. 1.07% du libc-2.22.so [.] do_fcntl
  39. 1.04% du [kernel.kallsyms] [k] _raw_spin_lock
  40. 0.99% du [kernel.kallsyms] [k] _raw_read_lock
  41. 0.95% du libc-2.22.so [.] __fxstatat64
  42. 0.94% du [kernel.kallsyms] [k] rb_insert_color
  43. 0.94% du [kernel.kallsyms] [k] generic_fillattr
  44. 0.93% du [kernel.kallsyms] [k] ext4fs_dirhash
  45. 0.93% du [kernel.kallsyms] [k] find_get_entry
  46. 0.89% du [kernel.kallsyms] [k] rb_next
  47. 0.89% du [kernel.kallsyms] [k] is_dx_dir
  48. 0.89% du [kernel.kallsyms] [k] in_group_p
  49. 0.89% du [kernel.kallsyms] [k] cp_new_stat
  50. [more...]

perf_event_paranoid

  1. $cat /proc/sys/kernel/perf_event_paranoid
  2. 1

内核配置为perf

  1. $cat /proc/config.gz | gunzip | grep -A70 'Kernel Perf'
  2. # Kernel Performance Events And Counters
  3. #
  4. CONFIG_PERF_EVENTS=y
  5. # CONFIG_DEBUG_PERF_USE_VMALLOC is not set
  6. CONFIG_VM_EVENT_COUNTERS=y
  7. CONFIG_SLUB_DEBUG=y
  8. # CONFIG_COMPAT_BRK is not set
  9. # CONFIG_SLAB is not set
  10. CONFIG_SLUB=y
  11. CONFIG_SLUB_cpu_PARTIAL=y
  12. CONFIG_SYSTEM_TRUSTED_KEYRING=y
  13. CONFIG_PROFILING=y
  14. CONFIG_TRACEPOINTS=y
  15. CONFIG_OPROFILE=m
  16. # CONFIG_OPROFILE_EVENT_MULTIPLEX is not set
  17. CONFIG_HAVE_OPROFILE=y
  18. CONFIG_OPROFILE_NMI_TIMER=y
  19. CONFIG_KPROBES=y
  20. CONFIG_JUMP_LABEL=y
  21. CONFIG_KPROBES_ON_FTRACE=y
  22. CONFIG_UPROBES=y
  23. # CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
  24. CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
  25. CONFIG_ARCH_USE_BUILTIN_BSWAP=y
  26. CONFIG_KRETPROBES=y
  27. CONFIG_USER_RETURN_NOTIFIER=y
  28. CONFIG_HAVE_IOREMAP_PROT=y
  29. CONFIG_HAVE_KPROBES=y
  30. CONFIG_HAVE_KRETPROBES=y
  31. CONFIG_HAVE_OPTPROBES=y
  32. CONFIG_HAVE_KPROBES_ON_FTRACE=y
  33. CONFIG_HAVE_ARCH_TRACEHOOK=y
  34. CONFIG_HAVE_DMA_ATTRS=y
  35. CONFIG_HAVE_DMA_CONTIGUOUS=y
  36. CONFIG_GENERIC_SMP_IDLE_THREAD=y
  37. CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
  38. CONFIG_HAVE_CLK=y
  39. CONFIG_HAVE_DMA_API_DEBUG=y
  40. CONFIG_HAVE_HW_BREAKPOINT=y
  41. CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
  42. CONFIG_HAVE_USER_RETURN_NOTIFIER=y
  43. CONFIG_HAVE_PERF_EVENTS_NMI=y
  44. CONFIG_HAVE_PERF_REGS=y
  45. CONFIG_HAVE_PERF_USER_STACK_DUMP=y
  46. CONFIG_HAVE_ARCH_JUMP_LABEL=y
  47. CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y
  48. CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y
  49. CONFIG_HAVE_CMPXCHG_LOCAL=y
  50. CONFIG_HAVE_CMPXCHG_DOUBLE=y
  51. CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y
  52. CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y
  53. CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
  54. CONFIG_SECCOMP_FILTER=y
  55. CONFIG_HAVE_CC_STACKPROTECTOR=y
  56. CONFIG_CC_STACKPROTECTOR=y
  57. # CONFIG_CC_STACKPROTECTOR_NONE is not set
  58. # CONFIG_CC_STACKPROTECTOR_REGULAR is not set
  59. CONFIG_CC_STACKPROTECTOR_STRONG=y
  60. CONFIG_HAVE_CONTEXT_TRACKING=y
  61. CONFIG_HAVE_VIRT_cpu_ACCOUNTING_GEN=y
  62. CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
  63. CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y
  64. CONFIG_HAVE_ARCH_HUGE_VMAP=y
  65. CONFIG_HAVE_ARCH_SOFT_DIRTY=y
  66. CONFIG_MODULES_USE_ELF_RELA=y
  67. CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y
  68. CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
  69. CONFIG_OLD_SIGSUSPEND3=y
  70. CONFIG_COMPAT_OLD_SIGACTION=y
最佳答案
我理解你的问题是:为什么用户模式录制的perf会显示来自内核的值?从“系统会计”的角度来看,它正在做它应该做的事情.

你做了:执行记录-e周期:你杜-sh~你得到了system_call和page_fault的统计数据,你想知道为什么会这样?

当你做du时,它必须遍历文件系统.在这样做时,它发出系统调用所需的东西(例如open,readdir等). du为你启动了这些东西,所以它被“收回”给他们.同样,du页面出现了多次故障.

perf正在跟踪由给定进程/程序引起的任何活动,即使它发生在内核地址空间内.换句话说,程序请求活动,并且内核在程序的要求下执行它,因此它会得到适当的收费.内核必须做“实际工作”来执行FS I / O和/或解决页面错误,因此您必须“为您委托的工作付费”.任何给定程序执行的消耗系统资源的内容都会被考虑在内.

这是计算机系统的标准会计模型,可以追溯到20世纪60年代,当时人们实际上在大型计算机上租用了时间.你直接或间接地为你所做的一切[就像律师:-)]收费.
*每分钟充电连接时间
*在用户程序中消耗的每个cpu周期的费用
*为内核空间中的程序执行的每个cpu周期充电
*对每个发送/接收的网络数据包收费
*对您的程序导致的任何页面错误收费
*为读/写的每个磁盘块充电,无论是文件还是分页/交换磁盘
在月底,他们邮寄了一个逐项帐单[就像公用事业账单],你必须支付:
真钱.

请注意,有些东西是不收费的.例如,假设您的程序是计算绑定但不执行[很多] I / O并使用相对少量的内存(即它本身不会导致页面错误).该程序将收取用户空间cpu使用费.

操作系统可能必须更换(即窃取)您的一个或多个页面,以便为其他一些内存占用程序腾出空间.生猪运行后,您的程序将再次运行.您的程序需要在页面或故障页面中进行故障排除.

我们不会对您的程序收取费用,因为您的程序没有导致页面错误.换句话说,对于每个“被盗”的页面,当您的程序必须将其故障时,您将获得该页面的“信用”.

此外,当尝试运行不同的进程时,内核不会将其进程调度程序消耗的cpu时间收取到任何进程.这被认为是“间接费用”和/或标准运营成本.例如,如果您有银行的支票帐户,他们不会向您收取您访问的当地分支机构的维护费用.

因此,虽然有用来衡量绩效,但它正在使用会计模型来获取数据.

它就像一辆汽车.你可以把车开到商店买东西,然后你会消耗一些汽油.或者,您可以请朋友开车去商店.在任何一种情况下,你必须支付汽油,因为你开车,或因为[当朋友开车时]汽油是在为你做某事时消耗的.在这种情况下,内核是你的朋友:-)

更新:

我的来源是源[内核源代码].而且,我已经做了40年的内核编程.

perf计数器有两种基本类型.内核可以生成的“宏”,例如页面错误.其他是系统调用计数器.

另一个时间是“微”或“纳米”类型.它们来自x86的PMC arch,并且具有内核无法计算的“缓存未命中”,“分支错误预测”,“数据获取错误预测”等内容的计数器.

PMC专柜只是免费运行.这就是为什么你得到你的全局统计数据,无论你正在做什么记录模式.内核可以定期询问它们,但是每次PMC递增时它都无法获得控制权.想要这些全局/系统范围和/或每个cpu的值?只需执行适当的RDPMC指令即可.

要跟踪进程的PMC,当您启动进程时,请执行RDPMC并将值保存在任务结构中[对于标记为“感兴趣”的多个]作为“启动时的PMC值”.当重新安排给定的cpu内核时,调度程序计算“下一个”任务,调度程序获取当前的PMC值,在启动该任务时获取它与存储在“旧”任务块中的一个之间的差异,并且突然增加该任务是该PMC的“总计数”. “当前值”成为新任务的“开始时的PMC值”

在Linux中,当发生任务/上下文切换时,它会生成两个perf事件,一个用于“在cpu X上输入新任务”和“在cpu X上停止旧任务”.

您的问题是监视“用户模式”生成内核地址的原因.这是因为在录制时(这不是perf程序),它将临时数据[如上所述]存储在当前任务/上下文块中,直到实际发生任务切换.

需要注意的关键是,这个上下文不会因为执行系统调用而改变 – 仅在发生上下文切换时.例如,gettimeofday系统调用获取挂钟时间并将其返回给用户空间.它不会进行上下文切换,因此它启动的任何perf事件都将被计入活动/当前上下文.它是来自内核空间还是用户空间并不重要.

作为另一个例子,假设该进程执行文件读取系统调用.在遍历文件句柄数据,索引节点等时,它可以生成几个perf事件.此外,它可能会产生更多的缓存未命中和其他PMC计数器颠簸.如果所需的块已经在FS块缓存中,则系统调用将只执行copy_to_user,然后重新输入用户空间.没有昂贵的上下文切换与上述PMC差异计算,因为pmc_value_at_start仍然有效.

以这种方式完成的原因之一是[执行机制]的性能.如果你在系统调用启动后立即进入内核空间进行PMC保存/恢复[将内核统计信息与给定进程的用户统计信息分开,就像你想要的那样],开销将是巨大的.你不会测量基本内核的性能.你的性能测量内核很多性能开销.

当我不得不对基于Linux的商业硬实时系统进行性能分析时,我开发了自己的性能记录系统.该系统具有8个cpu内核,可与PCIe总线上的多个定制硬件板交互,并具有多个FPGA. FPGA还在Microblaze中运行自定义固件.来自用户空间,内核空间和微博的事件日志都可以按照纳秒分辨率进行时间协调,存储事件记录的时间为70ns.

对我来说,Linux的perf机制有点粗糙和臃肿.如果要使用它来尝试解决涉及竞争条件,可能的锁定/解锁问题等的性能/时间错误,则可能会出现问题.也就是说,运行没有perf的系统,你就会得到bug.打开perf,你没有,因为你已经改变了系统的基本特征时序.关闭perf,再次出现计时错误.

猜你在找的Linux相关文章