-fprofile使用和-futo配置文件之间的区别是什么
What is the difference between -fprofile-use and -fauto-profile?
-fprofile-use
和-fauto-profile
之间有什么区别?
以下是医生的说法:
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-选项
fprofile使用
-fprofile use=路径
启用配置文件反馈导向优化,以及以下优化,这些优化通常只有在配置文件反馈可用的情况下才有利可图:〔…〕
如果指定了路径,GCC会查看该路径以查找配置文件反馈数据文件。请参见-fprofile目录。
和下面
-futo配置文件
-fauto profile=路径
启用基于采样的反馈导向优化,以及以下优化,这些优化通常只有在配置文件反馈可用的情况下才有利可图:〔…〕
path是包含AutoFDO配置文件信息的文件的名称。如果省略,则默认为当前目录中的fbdata.afdo。
([...]
中针对-fauto-profile
的优化列表较长。)
我在一条我甚至记不起来的路上偶然发现了这个线程,并在学习的过程中学习了这些东西。但如果我能从中吸取教训,我不喜欢看到一个没有答案的问题!所以我开始读书了。
反馈导向优化
正如GCC所说,这两种模式都是应用反馈定向优化的模式。通过运行该程序并分析它做什么、如何做、在哪些功能上花费多长时间等,我们可以从生成的数据中促进额外的定向优化。探查器的结果被"前馈"到优化器。接下来,据推测,您可以使用配置文件优化的二进制文件和配置文件,然后编译另一个FDO版本,依此类推…因此名称中有反馈部分。
真正的答案,这两个开关之间的区别,并没有很清楚的记录,但如果我们只需要进一步研究,它是可用的。
-f配置文件使用
首先,您对-fprofile-use
的引用只是真正说明它需要-fprofile-generate
,这是一个没有很好记录的选项:-use
的引用只是告诉您阅读您已经使用的页面,在所有情况下,-generate
只被提及,但从未定义。有用但是我们可以参考这个问题的答案:如何在g++中使用概要文件引导优化?
正如这个答案所说,这里有问题的GCC文件温和地表明。。。-fprofile-generate
导致检测被添加到输出二进制文件中。正如该页面所总结的,插入指令的可执行文件添加了一些内容,以便于在运行时进行额外的检查或深入了解。
(我知道的另一种形式的工具,也是我使用过的一种,是编译器附加库UBSan,我通过GCC的-fsanitize=undefined
选项使用它。它在运行时捕获一些未定义的行为。打开它的GCC揭示了我可能需要很长时间才能找到的UB,这让我想知道我的程序是如何运行的!Clang也可以使用这个库,也许还有其他编译器。)
-动物剖面
相比之下,-fauto-profile
不同。关键区别在你引用的简介中得到了暗示,如果不清楚的话:
path
是包含AutoFDO配置文件信息的文件名。
此模式使用AutoFDO处理分析和后续优化。我们去谷歌:AutoFDO前几行并没有尽可能简洁地解释这一点,我认为最好的总结隐藏在页面的深处:
AutoFDO[
-fauto-profile
]和FDO[CDC_14]之间的主要区别在于,AutoFDO配置文件基于优化的二进制文件,而不是插入指令的二进制文件这使得它在处理克隆函数时大不相同。
它是如何做到这一点的?-fauto-profile
要求您提供由Linux内核的探查器Perf编写的、转换为AutoFDO格式的探查文件。Perf不是添加工具,而是使用CPU的硬件功能和操作系统的内核级功能来分析程序运行时的各种统计信息:
perf
功能强大:它可以检测CPU性能计数器、跟踪点、kprobes和uprobes(动态跟踪)。它能够进行轻量级评测。[…]性能计数器是CPU硬件寄存器,用于统计硬件事件,如执行的指令、缓存未命中或预测错误的分支。它们构成了分析应用程序的基础,以跟踪动态控制流并识别热点。
因此,它可以评测优化的程序,而不是插入指令的程序。我们可以合理地假设,这更能代表您的程序在现实世界中的反应,因此可以促进收集更有用的分析数据,并因此应用更有效的优化。
这里总结了一个如何将所有这些联系在一起并让-fauto-profile
对您的程序做一些事情的跑腿工作的例子:使用GCC和Perf-的反馈导向优化
(也许现在我已经学会了这一切,总有一天我会尝试这些选项!)
undercore_d深入了解了差异。
这是我的看法。
通过最初使用-fprofile-generate
进行编译来执行内部评测,CCD_18将评测器集成到二进制文件中,以便运行性能数据收集。执行二进制文件,持续10分钟或您认为足以让探查器记录的任何时间。如果是多线程应用程序,请使用-fprofile-use
和-fprofile-correction
重新编译。内部探查器的运行会导致显著的性能命中率(在我的情况下为25%),这并不能反映真实世界中不包含探查器的二进制行为,因此可能会导致不太准确的分析,但如果运行启用探查器的二元文件时的所有活动都会随着性能损失而扩展,我想这应该无关紧要。
或者,您可以使用特定于内核的perf工具(更容易出错和更努力)(可能还需要构建内核来支持评测、跟踪等)来创建评测数据。这可以被认为是外部评测,并且在评测时对应用程序性能的影响可以忽略不计。您可以在正常编译的二进制文件上运行此操作。我找不到任何比较这两者的研究。
perf record -e br_inst_retired:near_taken -b -o perf.data *your_program.unstripped -program -parameters*
然后在不剥离二进制文件的情况下,将分析数据转换为GCC理解的数据。。。
create_gcov --binary=your_program.unstripped --profile=perf.data --gcov=profile.afdo
然后使用-fauto-profile
重新编译应用程序。已知存在Perf和AutoFDO/create_gcov版本特定的问题。我提到https://blog.wnohang.net/index.php/2015/04/29/feedback-directed-optimization-with-gcc-and-perf/以获取有关此替代分析方法的详细信息。
默认情况下,-fprofile-use
和-fauto-profile
都会启用许多优化选项,在我的情况下,不需要的funroll循环会对应用程序的性能产生负面影响。如果你是迂腐的类型,你可以通过在编译标志中包括禁用的对应项来测试选项组合,在我的例子中是-fno展开循环。
在剥离二进制文件后,对我的程序使用内部评测,它将大小减少了25%(与原始的非评测器剥离二进制文件相比),但我只观察到了次百分位数的性能提升,程序日志(它是一个加密货币矿工)报告的以前的工作输出波动更不稳定,而不是像最初那样在哈希率的波峰和波谷之间逐渐上升和下降。
总的来说,这是一次暗箭伤人。
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 在 const 函数中通过引用和指针返回之间的区别
- 我想知道长双倍和双倍之间的区别
- 这 4 个 lambda 表达式之间有什么区别?
- 结构体 S { int align; } 之间的区别;(struct 关键字后的名称)和 struct { int al
- (double) 和 double() 之间的区别
- & 和 * 之间的区别
- std::is_convertible 和 std::convertible_to 之间的区别(在实践中)?
- 析构函数和'delete'之间的区别
- 在 typedef 内部使用 const 关键字和在 typedef 外部使用 const 关键字之间有区别吗?
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- vector.back() 和 vector[vector.size() - 1] 之间的区别?
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 函数签名与调用的函数不匹配,常量字符[]和字符*之间的区别?
- OpenMP #pragma omp for v/s #pragma omp parallel for 之间的区别?
- S() 与 S{} 之间的区别?