假设我们为我的项目禁用了项目范围优化(例如 -O0),并且我执行了以下操作。编辑:我正在使用 tricore-gcc (应该与普通 GCC 相同)。我找不到关于 tricore-gcc 有关编译指示的特定文档。
static void Method1(U8 *data) __attribute__((-fno-inline));
static void Method2(U8 *data) __attribute__((-fno-inline));
//Example 1 (expect method1/method2 to both be optimised at -0s level
#pragma GCC optimize ("-Os")
static void Method1(U8 *data);
{
...do stuff
Method2(data);
}
#pragma GCC optimize ("-O0")
#pragma GCC optimize ("-Os")
static void Method2(U8 *data)
{
...do stuff
}
#pragma GCC optimize ("-O0")
//Example 2 Expect method 1 to not be optimised
//expect method2 to be optimised at -0s level
#pragma GCC optimize ("-O0")
static void Method1(U8 *data)
{
...do stuff
Method2(data);
}
#pragma GCC optimize ("-O0")
#pragma GCC optimize ("-Os")
static void Method2(U8 *data);
{
...do stuff
}
#pragma GCC optimize ("-O0")
//Example 3 - Expect method method 1 to not be optimised?
expect method 2 to be optimised
//No pragma, assume defaults to -O0 as that is the project default
static void Method1(U8 *data)
{
Method2(data);
}
#pragma GCC optimize ("-Os")
static void Method2(U8 *data);
{
...do stuff
}
#pragma GCC optimize ("-O0")
//Example 4 - expect method 1 to be optimised, however will method 2 be optimised?
//as it was called from method1?
#pragma GCC optimize ("-Os")
static void Method1(U8 *data)
{
...do stuff
Method2(data);
}
#pragma GCC optimize ("-O0")
//No pragma, assume defaults to -O0 as that is the project default
//OR does it simply default to the last pragma it saw, eg the -O0 above?
static void Method2(U8 *data);
{
...do stuff
}
//Example 6 - expect method 1 to be optimised, however will method 2 be optimised?
//as it was called from method1?
#pragma GCC optimize ("-Os")
static void Method1(U8 *data)
{
...do stuff
Method2(data);
}
//Ommitted #pragma GCC optimize ("-O0"), I assuming that method2
//will be optimised?
static void Method2(U8 *data);
{
...do stuff
}
示例 3 和 4 是两个示例,我不确定会发生什么或期望什么,因为没有编译指示,编译指示是否递归到被调用的函数中?或者编译器只是简单地查找它是否位于编译指示内来确定是否应该对其进行优化?
示例 5 我相信我明白会发生什么
最后一个问题。我需要将编译指示放在文件顶部的函数定义上吗?或者它们只是被忽略了,功能本身才是最重要的?
例如,这里的这些行,将编译指示放在这里会不会造成混乱,什么也不做,或者它们应该放在这里而不是在函数上?或者为了简洁而两者都做?
static void Method1(U8 *data) __attribute__((-fno-inline));
static void Method2(U8 *data) __attribute__((-fno-inline));
编辑:更新 - 本地化优化的工作方式与尼尔森描述的完全一样。可能看起来是一件奇怪的事情,但对于我的用例来说,这正是我想要的。
编译指示效果是实现定义的,因此不能假设它在不同的编译器中是相同的。问题集中在 GCC 上,GCC 文档 说明如下:
#pragma GCC 优化(字符串,...)
此编译指示允许您为源文件中稍后定义的函数设置全局优化选项。 [...] 在这一点之后定义的每个函数都被视为使用每个字符串参数的一个 optim(string) 属性进行声明。 [...]
因此,该编译指示从其在文件中出现的位置起一直有效,直到文件末尾。
为了优化单个函数而不影响后续函数定义,可以使用属性表示法:
__attribute__((optimize(3)))
void func()
{
...
}
或者可以通过保存和恢复设置来确定编译指示的范围:
#pragma GCC push_options
#pragma GCC optimize ("-O3")
void func()
{
...
}
#pragma GCC pop_options
对函数定义有效的优化选项仅影响函数本身,它不会传播到被调用的函数。它们将使用定义时有效的选项进行优化。