关于系统调用的perf报告

时间:2018-04-16 07:24:27

标签: c memory perf

我为进程A,B:

提供了针对perf报告(关于malloc)的以下输出

记录:perf记录-e cycles:u

流程A:

0.00%       1833448  Test-Recv  libc-2.17.so           [.] malloc              
0.00%       1833385  Test-Recv  [kernel.kallsyms]      [k] system_call         
0.00%        916588  Test-Recv  libc-2.17.so           [.] _int_malloc

以及进程B的以下内容:

24.90%   10855848444  test.exe  libc-2.17.so   [.] _int_malloc
15.78%    6881565672  test.exe  libc-2.17.so   [.] _int_free
 7.48%    3261672221  test.exe  libc-2.17.so   [.] malloc
 4.66%    2030332370  test.exe  libc-2.17.so   [.] systrim.isra.2
 2.43%    1061251259  test.exe  libc-2.17.so   [.] free
 2.12%     925588492  test.exe  test.exe       [.] main

他们都在源代码中做了一些malloc

我可以假设在进程A的情况下,malloc会发生系统调用, 但在进程B的情况下,没有发生系统调用,因为在 进程B性能报告,根本没有[k] system_call !!!

2 个答案:

答案 0 :(得分:2)

你不会通过使用采样获得某些程序所调用的所有函数,你会得到一些被调用的函数,即事件被采样最多的函数,用于"循环:u&# 34;你会得到最热的"用户空间中的函数(没有内核函数)。

考虑使用跟踪而不是采样,例如:' perf trace workload'。考虑使用它的回溯,例如,查看' brk'的回溯。系统调用' ls'我们能得到:



# perf trace -e brk --call-graph dwarf ls
   0.933 (0.009 ms): ls brk(brk: 0x5577c4683000) = 0x5577c4683000
                     __brk (/usr/lib64/libc-2.26.so)
                     __GI___sbrk (inlined)
                     __GI___default_morecore (inlined)
                     sysmalloc (/usr/lib64/libc-2.26.so)
                     _int_malloc (/usr/lib64/libc-2.26.so)
                     tcache_init.part.5 (/usr/lib64/libc-2.26.so)
                     __GI___libc_malloc (inlined)
                     __GI___strdup (inlined)
                     [0xffff80aa65b9ae49] (/usr/lib64/libselinux.so.1)
                     [0xffff80aa65b9af0e] (/usr/lib64/libselinux.so.1)
                     call_init.part.0 (/usr/lib64/ld-2.26.so)
                     _dl_init (/usr/lib64/ld-2.26.so)
                     _dl_start_user (/usr/lib64/ld-2.26.so)

这表明在这种情况下调用了系统调用,以响应调用malloc()的strdup(),最终通过' brk'来向内核核心询问更多内存。调用

使用' perf trace'还有一些,你会发现类似于' strace'提供的统计数据,例如,一个程序调用brk和其他系统调用的次数。

答案 1 :(得分:1)

是的,似乎很合理。可能进程B从内核获取了一些内存,然后能够满足自由列表中的所有分配。即,glibc的malloc实现决定将任何页面都返回给内核,自由列表永远不会变得足够大(或者太碎片化)。

这一切都归结为分配/解除分配模式和映射的大小。对于较大的malloc次请求,glibc会直接使用mmap(MAP_ANONYMOUS),因此munmap可以free {。}}。