提问人:rollsch 提问时间:7/3/2023 最后编辑:rollsch 更新时间:8/7/2023 访问量:80
使用编译指示进行 C 优化,它会递归吗?还是简单地使用查看文件中编译指示的顺序?
C optimization with pragmas, does it recurse? Or does it simply use look at the order of the pragmas in the file?
问:
假设我们为我的项目禁用了项目范围的优化(例如 -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 优化(字符串,...)
此编译指示允许您为稍后在源文件中定义的函数设置全局优化选项。[...]在此点之后定义的每个函数都被视为已使用每个字符串参数的一个 optimize(string) 属性声明。[...]
因此,此编译指示从它在文件中出现到文件末尾都有效。
为了在不影响后续函数定义的情况下优化单个函数,可以使用属性表示法:
__attribute__((optimize(3)))
void func()
{
...
}
或者,可以通过保存和还原设置来限定编译指示的范围:
#pragma GCC push_options
#pragma GCC optimize ("-O3")
void func()
{
...
}
#pragma GCC pop_options
函数定义的优化选项仅影响函数本身,不会传播到被调用的函数。它们将使用在定义它们时生效的选项进行优化。
评论
method1
method2
method 1, method 2, method method 1, method1, method2
Method1()
Method2()