这与Determine cause of segfault when using -O3?有关在这个问题中,我使用特定版本的GCC在使用-O3
编译时捕获特定函数中的段错误。在-O3
处,使用了矢量化指令(在-O2
,不使用它们。)
我想在较低的优化级别中包装单个函数。根据{{3}},我可以做到。但是,按照问题和答案中的各种链接,我找不到"答案的答案,确切地说,#34; 。
如何将单个函数标记为使用不同的优化级别?
相关,我不想将此函数移动到单独的文件,然后为它提供不同的makefile配方。这样做会打开另一种蠕虫,就像在某些平台上将它应用于GCC 4.9一样。
答案 0 :(得分:12)
我知道这个问题被标记为海湾合作委员会,但我只是looking into doing this portably并认为结果可能对某人有用,所以:
optimize(X)
功能属性optnone
和minsize
个函数属性(使用__has_attribute
来测试支持)。由于我相信 3.5,它也有#pragma clang optimize on|off
。#pragma intel optimization_level 0
适用于pragma之后的下一个函数#pragma optimize
,适用于pragma之后的第一个函数#pragma option_override(funcname, "opt(level,X)")
。请注意,对于__has_attribute(optnone)
,13.1.6(至少)返回true,但实际上并不支持它。#pragma Onum
,可以与#pragma push/pop
#pragma opt X (funcname)
#pragma _CRI [no]opt
#pragma FUNCTION_OPTIONS(func,"…")
(C)和#pragma FUNCTION_OPTIONS("…")
(C ++)#pragma optimize=...
#pragma optimize time/size/none
因此,对于GCC / ICC / MSVC / clang / IAR / Pelles和TI C ++,您可以定义一个刚刚放在函数之前的宏。如果要支持XL,ODS和TI C,可以添加函数名作为参数。在函数弹出设置后,ARM将需要另一个宏。对于Cray AFAIK,您无法恢复之前的值,只能关闭和打开优化。
我认为这样做的主要原因是禁用对错误编译器(或编译器中暴露代码中的错误)的优化,因此统一的可移植体验可能并不重要,但希望此列表可以帮助找到合适的人他们的编译器的解决方案。
编辑:值得注意的是,禁用优化是相对常见的,因为之前不再有效的代码。虽然编译器中可能存在错误,但您的代码更可能依赖于未定义的行为,而更新,更智能的编译器可以并且将忽略未定义的情况。在这种情况下正确的答案不是禁用优化,而是修复代码。关于clang和gcc的UBsan可以在这里提供很多帮助;使用-fsanitize=undefined
进行编译,许多未定义的行为将在运行时开始发出警告。此外,尝试使用您可以启用的所有警告选项进行编译;对于GCC来说意味着-Wall -Wextra
,对于-Weverything
中的铿锵声。
答案 1 :(得分:8)
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
中描述了它您可以通过声明如下函数来更改级别:
void some_func() __attribute__ ((optimize(1))) {
....
}
强制优化级别1.
答案 2 :(得分:3)
以下是如何使用pragma:
#pragma GCC push_options
#pragma GCC optimize ("-O2")
void xorbuf(byte *buf, const byte *mask, size_t count)
{
...
}
#pragma GCC pop_options
使其便携,如下所示。
#define GCC_OPTIMIZE_AWARE (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) || defined(__clang__)
#if GCC_OPTIMIZE_AWARE
# pragma GCC push_options
# pragma GCC optimize ("-O2")
#endif
它需要被包装,因为使用-Wall
,旧版本的GCC不理解-Wno-unknown-pragma
,并且它们将导致编译嘈杂。将在现场遇到旧版本,如OpenBSD上的GCC 4.2.1。
但根据Markus Trippelsdorf在GCC邮件列表When did 'pragma optimize' become available?上的说法:
总的来说这是一个坏主意,因为“pragma GCC优化”的意思是 仅限编译器调试辅助工具。它应该不在生产中使用 码。