- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我看到很多人提示 -O3
选项:
-O3
我查看 GCC 的手册:
-O3 Optimize yet more. -O3 turns on all optimizations
specified by -O2 and also turns on the
-finline-functions and -frename-registers options.
而且我还确认了代码,以确保两个选项是 -O3
中仅有的两个优化:
if (optimize >= 3){
flag_inline_functions = 1;
flag_rename_registers = 1;
}
对于这两个优化:
-finline-functions
在某些情况下(主要是 C++)很有用,因为它允许我们使用 -finline-limit 定义内联函数的大小(默认为 600)。设置高内联限制时,编译器可能会报告内存不足的错误。-frename-registers
尝试通过使用寄存器分配后剩余的寄存器来避免预定代码中的错误依赖。这种优化最有利于具有大量寄存器的处理器。对于inline-functions,虽然它可以减少函数调用的次数,但是它可能会导致一个大的二进制文件,所以-finline-functions
可能会引入严重的缓存惩罚并且变得比-O2。我认为缓存惩罚不仅取决于程序本身。
对于重命名寄存器,我认为它不会对像 x86 这样的 cisc 架构产生任何积极影响。
我的问题有 2.5 个部分:
我是否可以声称使用 -O3 选项可以更快地运行程序取决于底层平台/架构? [已回答]
编辑:
第一部分已确认为真。 David Hammen 还声称,我们应该非常小心优化和浮点运算如何在具有扩展精度浮点寄存器的机器(如 Intel 和 AMD)上交互。
我什么时候可以自信地使用 -O3
选项?我想这两个优化,尤其是重命名寄存器可能会导致与 -O0/O2 不同的行为.我看到一些使用 -O3
编译的程序在执行过程中崩溃了,这是确定性的吗?如果我运行一次可执行文件而没有任何崩溃,这是否意味着使用 -O3
是安全的?
编辑:确定性与优化无关,它是一个多线程问题。但是,对于多线程程序,当我们运行一次可执行文件而没有错误时,使用 -O3
是不安全的。 David Hammen 表明,-O3
对浮点运算的优化可能会违反严格的比较弱排序标准。 使用-O3
选项还有什么需要注意的地方吗?
如果第一个问题的答案是"is",那么当我更改目标平台或在具有不同机器的分布式系统中时,我可能需要在 -O3
和-O2
。有什么通用的方法可以决定我是否可以通过 -O3
获得性能改进?比如寄存器多,内联函数短等等。[已回答]
编辑:第 3 部分已被 Louen 回答为“平台的多样性使得对这个问题的一般推理变得不可能”在评估 -O3
的性能增益时,我们必须同时尝试并对我们的代码进行基准测试,看看哪个更快。
最佳答案
- I saw some programs got crashed when compiling with -O3, is it deterministic?
如果程序是单线程的,程序使用的所有算法都是确定性的,并且如果每次运行的输入相同,是的。如果这些条件中的任何一个不成立,答案是“不一定”。
如果您不使用 -O3 进行编译,这同样适用。
If I run an executable once without any crash, does it mean it is safe to use -O3?
当然不是。同样,如果您不使用 -O3 进行编译,同样适用。仅仅因为您的应用程序运行一次并不意味着它在所有情况下都能成功运行。这是使测试成为难题的部分原因。
浮点运算可能会在浮点寄存器比 double 精度更高的机器上导致奇怪的行为。例如,
void add (double a, double b, double & result) {
double temp = a + b;
result = temp;
if (result != temp) {
throw FunkyAdditionError (temp);
}
}
编译一个使用这个 add
的程序功能未优化,您可能永远不会看到任何 FunkyAdditionError
异常(exception)。编译优化和某些输入会突然开始导致这些异常。问题是通过优化,编译器会生成 temp
注册 result
,作为引用,不会被编译到寄存器中。添加 inline
当您的编译器使用 -O3
编译时,限定符和这些异常可能会消失因为现在result
也可以是寄存器。浮点运算的优化可能是一个棘手的问题。
最后,让我们看一下其中一个案例,当使用 -O3,GCC: program doesn't work with compilation option -O3 编译程序时,事情确实在晚上发生了变化。 .该问题仅出现在 -O3 中,因为编译器可能内联了 distance
函数,但将其中一个(但不是两个)结果保存在扩展精度浮点寄存器中。通过此优化,某些点 p1
和 p2
可以导致 p1<p2
和 p2<p1
评估为 true
.这违反了比较函数的严格弱排序标准。
您需要非常小心优化和浮点运算如何在具有扩展精度浮点寄存器的机器(例如 Intel 和 AMD)上交互。
关于c++ - 我什么时候可以自信地使用 -O3 编译程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14850593/
这个问题在这里已经有了答案: multiple definition error c++ (2 个答案) 关闭 3 年前。 我遇到了一些编译问题,这里是详细信息: 假设我声明了一些数据结构 my_d
我正在尝试使用 lessfs 并了解它如何使用 mhash 来生成其加密指纹,所以我正在查看 mhash 以了解它如何处理哈希算法,因此我正在尝试运行中提供的一些示例程序,但我遇到了并发症和错误 我试
所以我有一个编译程序,但我有两个小问题。该程序将十六进制转换为十进制和二进制,并将其显示在这个可爱的小 GUI 中。 问题: 我想将二进制文件放入一个数组中,然后在连续的 5 个小框窗口之间传输。转换
这可能是一个很难用我实际提供的信息进行故障排除的问题,但我希望有人至少能够为我指出一个可能的方向。 我正在尝试安装 HTK ( http://htk.eng.cam.ac.uk/ ),根据 this页
我用客户端松鼠在oracle 11g中创建了一个简单的过程,这是代码 create or replace procedure EXAMPLE_P is begin 1+2; end;/ 在执行
$2有 C 文件的路径。 问题是当我编译一个有错误的文件时,它会显示错误。我不想显示错误,我只想说:“$2 无法编译。”有什么想法吗? cc $2 if test ! $? = 0
我使用安装了 Advanced Tomato 的华硕路由器(基于 ARMv7 proc)在它上面作为我的 ARMv7 开发者平台。我安装编译器 (gcc - 5.4.0-1)加上来自 OpenWRT
我想在 Linux 上用 twitter 库编译一个 C++ 程序。 我目前使用 twitcurl 作为 twitter API 库并安装了 g++ 以及官方网站上列出的所有必要文件和包:http:/
我正在尝试编译使用 libdl 库中的 API 的示例代码: #include #include #include int main(int argc, char **argv) { v
我看到很多人提示 -O3 选项: GCC: program doesn't work with compilation option -O3 Floating Point Problem provid
有如下代码: #include #include int main(void){ CURL *curl; CURLcode res; curl = curl_easy_init();
我们有一个非常重要的应用程序,但到目前为止还没有源代码。该应用程序是用 COBOL 编写的,编译版本在我们的生产系统中并正在运行。 但是,我们需要迁移到新服务器和新的 cobol 编译器。我们的印象是
我正在尝试使用一些 curl 代码来测试库,但我无法编译它:( 我正在使用 Clion (Cmake + gcc),我有一个 libcurl.a、一个 libcurl.dll 和一个 libcurl.
我使用 mingw(Windows 8 64 位,MinGW 20120426)在 Windows 上用 clang 构建了 llvm: ./configure --disable-docs --en
我在 ubuntu 下写了一个程序,其中包含 gtkmozembed.h。我在编译程序时遇到问题。下面是使用 gtkmozembed 的程序的最简单形式。 #include #include #i
我在 Ubuntu 上使用 GNAT 编译了一个 Ada 程序。 之后,我尝试使用该程序进行几次测试,它运行正常。 但是当我将它上传到我的 Apache (UNIX) 网络服务器并尝试运行该程序时,没
我正在尝试通过批处理文件使用 MinGW 编译器运行我的程序。但是当我尝试启动它时,它什么也没说。 代码如下: g++ -o Learning.exe Main.o pause 当我打开 .exe 文
我在 Windows 8 计算机 (x64) 上使用 VS2012 编写了一个 Windows 窗体应用程序,我希望它在 Windows XP x86 上运行。当我尝试运行该程序时出现错误“...不是
我在运行 ArchLinux 的系统上使用 clang 版本 4.0.0,它一直运行良好,但最近我无法再编译使用某些 STL header 的程序了! 详细信息: clang --version 的输
我有程序 main.cpp 调用其他 C++ 程序 file1.cpp、file2.cpp 和 message.txt 请问如何使用 g++ 在 Linux Ubuntu 中编写编译命令,主要不是“v
我是一名优秀的程序员,十分优秀!