我正在使用perf分析一个玩具程序(选择排序),我想知道在perf报告输出中迭代对应什么。它显示的地址对应于内部循环和if语句。我希望有人能帮忙。此外,当我在perf中使用“-b -分支历史”时,基本块循环列就消失了。我也不知道原因。
这是我的代码被采样的部分(MAX_LENGTH是500):
35 // FROM: https://www.geeksforgeeks.org/selection-sort
37 void swap(int *xp, int *yp)
38 {
39 int temp = *xp;
40 *xp = *yp;
41 *yp = temp;
42 }
43
44 void selection_sort(int arr[])
45 {
46 int i, j, min_idx;
47
48 // One by one move boundary of unsorted subarray
49 for (i = 0; i < MAX_LENGTH-1; i++)
50 {
51 // Find the minimum element in unsorted array
52 min_idx = i;
53 for (j = i+1; j < MAX_LENGTH; j++)
54 if (arr[j] < arr[min_idx])
55 min_idx = j;
56
57 // Swap the found minimum element with the first element
58 swap(&arr[min_idx], &arr[i]);
59 }
60 }使用(clang版本5.0.0)编译:
clang -O0 -g selection_sort.c -o selection_sort_g_O0下面是我如何调用perf记录:
sudo perf record -e cpu/event=0xc4,umask=0x20,name=br_inst_retired_near_taken,period=1009/pp -b -g ./selection_sort_g_O0perf报告及其产出:
sudo perf report -b --branch-history --no-children
Samples: 376 of event 'br_inst_retired_near_taken', Event count (approx.): 37603384
Overhead Source:Line Symbol Shared Object ▒
+ 51.86% selection_sort_g_O0[862] [.] 0x0000000000000862 selection_sort_g_O0 ▒
- 24.47% selection_sort_g_O0[86e] [.] 0x000000000000086e selection_sort_g_O0 ▒
0x873 (cycles:1) ▒
- 0x86e (cycles:1) ▒
- 23.94% 0x86e (cycles:3 iterations:25) ▒
0x862 (cycles:3) ▒
0x83f (cycles:1) ▒
0x87c (cycles:1) ▒
0x873 (cycles:1) ▒
0x86e (cycles:1) ▒
0x86e (cycles:3) ▒
0x862 (cycles:3) ▒
0x83f (cycles:1) ▒
0x87c (cycles:1) ▒
0x873 (cycles:1) ▒
0x86e (cycles:1) ▒
0x86e (cycles:3) ▒
0x862 (cycles:3) ▒
+ 22.61% selection_sort_g_O0[87c] [.] 0x000000000000087c selection_sort_g_O0 ▒
+ 1.06% selection_sort_g_O0[8a5] [.] 0x00000000000008a5 selection_sort_g_O0我将objdump用于地址和源文件行之间的映射:
objdump -Dleg selection_sort_g_O0 > selection_sort_g_O0.s
../selection_sort.c:53
836: 8b 45 f4 mov -0xc(%rbp),%eax
839: 83 c0 01 add $0x1,%eax
83c: 89 45 f0 mov %eax,-0x10(%rbp)
83f: 81 7d f0 f4 01 00 00 cmpl $0x1f4,-0x10(%rbp)
846: 0f 8d 35 00 00 00 jge 881 <selection_sort+0x71>
../selection_sort.c:54
84c: 48 8b 45 f8 mov -0x8(%rbp),%rax
850: 48 63 4d f0 movslq -0x10(%rbp),%rcx
854: 8b 14 88 mov (%rax,%rcx,4),%edx
857: 48 8b 45 f8 mov -0x8(%rbp),%rax
85b: 48 63 4d ec movslq -0x14(%rbp),%rcx
85f: 3b 14 88 cmp (%rax,%rcx,4),%edx
862: 0f 8d 06 00 00 00 jge 86e <selection_sort+0x5e>
../selection_sort.c:55
868: 8b 45 f0 mov -0x10(%rbp),%eax
86b: 89 45 ec mov %eax,-0x14(%rbp)
../selection_sort.c:54
86e: e9 00 00 00 00 jmpq 873 <selection_sort+0x63>
../selection_sort.c:53
873: 8b 45 f0 mov -0x10(%rbp),%eax
876: 83 c0 01 add $0x1,%eax
879: 89 45 f0 mov %eax,-0x10(%rbp)
87c: e9 be ff ff ff jmpq 83f <selection_sort+0x2f>发布于 2018-08-08 12:09:10
我将尝试在祖兰回答的基础上重申和补充更多的信息。
最后一个分支记录(LBR)允许在可执行文件中查找热执行路径,以直接检查它们是否有优化机会。在perf中,这是通过扩展调用堆栈显示机制和在调用堆栈中添加最后一个基本块来实现的,调用堆栈通常用于显示最常见的函数调用层次结构。
这可以通过使用perf记录中的调用图(-g)和LBR (-b)选项和perf报告中的选项来实现,后者将最后一个分支信息添加到调用图中。从本质上讲,它给出了8-32个分支为什么会发生事情的额外上下文。
timed 特性在最近的perf版本中报告了每个基本块的平均周期数。
什么是迭代?
据我所知,分支历史代码具有循环检测功能。这允许我们通过计算移除环的次数来获得迭代次数。只在perf report输出中引入了删除重复循环(以直方图格式显示),这是通过Linux内核中以前的提交实现的。
结构迭代是一个有用的C结构,用于显示perf report中的迭代次数。
这是保存在perf report输出中要显示的迭代次数的地方。save_iterations函数是从remove_loops函数内部调用的。
在解析呼叫链时,正在删除这些循环。
您还可以阅读这个提交,它描述了perf report如何显示在较新的Linux内核版本中引入的迭代和更改的数量。
https://stackoverflow.com/questions/51640940
复制相似问题