假设我在源文件中有这个小功能
static void foo() {}
Run Code Online (Sandbox Code Playgroud)
我构建了二进制文件的优化版本,但我不希望这个函数内联(出于优化目的).我可以在源代码中添加一个宏来阻止内联吗?
ale*_*gle 137
您需要gcc-specific noinline属性.
此函数属性可防止将函数考虑为内联.如果函数没有副作用,那么除了内联之外,还有一些优化会导致函数调用被优化掉,尽管函数调用是实时的.为了防止此类调用被优化,请放置
asm ("");
像这样使用它:
void __attribute__ ((noinline)) foo()
{
...
}
Run Code Online (Sandbox Code Playgroud)
And*_*oss 21
一种可移植的方法是通过指针调用该函数:
void (*foo_ptr)() = foo;
foo_ptr();
Run Code Online (Sandbox Code Playgroud)
虽然这会产生不同的分支指令,但这可能不是你的目标.这带来了一个好点:你的目标是什么?
Sam*_*iao 13
如果您遇到编译器错误__attribute__((noinline)),您可以尝试:
noinline int func(int arg)
{
....
}
Run Code Online (Sandbox Code Playgroud)
nem*_*equ 11
我知道问题是关于GCC,但我认为有关编译器其他编译器的一些信息也许有用.
GCC的
noinline
函数属性也很受其他编译器的欢迎.它至少得到以下支持:
__has_attribute(noinline))__TI_GNU_ATTRIBUTE_SUPPORT__)此外,MSVC支持
__declspec(noinline)
回Visual Studio 7.1.英特尔也可能支持它(它们试图与GCC和MSVC兼容),但我没有费心去验证这一点.语法基本相同:
__declspec(noinline)
static void foo(void) { }
Run Code Online (Sandbox Code Playgroud)
PGI 10.2+(可能更旧)支持noinline适用于下一个函数的pragma:
#pragma noinline
static void foo(void) { }
Run Code Online (Sandbox Code Playgroud)
TI 6.0+支持
FUNC_CANNOT_INLINE
pragma(烦人地)在C和C++中的工作方式不同.在C++中,它类似于PGI:
#pragma FUNC_CANNOT_INLINE;
static void foo(void) { }
Run Code Online (Sandbox Code Playgroud)
但是,在C中,函数名称是必需的:
#pragma FUNC_CANNOT_INLINE(foo);
static void foo(void) { }
Run Code Online (Sandbox Code Playgroud)
Cray 6.4+(可能更早)采用类似的方法,需要函数名称:
#pragma _CRI inline_never foo
static void foo(void) { }
Run Code Online (Sandbox Code Playgroud)
Oracle开发人员Studio还支持编译这需要函数名,可以追溯到至少复地开发6,但要注意,它需要拿出后的声明,即使在最新版本:
static void foo(void);
#pragma no_inline(foo)
Run Code Online (Sandbox Code Playgroud)
根据您的专注程度,您可以创建一个可以在任何地方工作的宏,但您需要将函数名称和声明作为参数.
如果,OTOH,你可以选择适合大多数人的东西,那么你可以放弃一些更美观,不需要重复自己的东西.这就是我为Hedley采取的方法,当前版本的 HEDLEY_NEVER_INLINE 如下所示:
#if \
HEDLEY_GNUC_HAS_ATTRIBUTE(noinline,4,0,0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
HEDLEY_TI_VERSION_CHECK(8,0,0) || \
(HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
# define HEDLEY_NEVER_INLINE __attribute__((__noinline__))
#elif HEDLEY_MSVC_VERSION_CHECK(13,10,0)
# define HEDLEY_NEVER_INLINE __declspec(noinline)
#elif HEDLEY_PGI_VERSION_CHECK(10,2,0)
# define HEDLEY_NEVER_INLINE _Pragma("noinline")
#elif HEDLEY_TI_VERSION_CHECK(6,0,0)
# define HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
#else
# define HEDLEY_NEVER_INLINE HEDLEY_INLINE
#endif
Run Code Online (Sandbox Code Playgroud)
如果你不想使用Hedley(它是一个单独的公共域/ CC0标题),你可以毫不费力地转换版本检查宏,但不仅仅是我愿意放入☺.
小智 9
static __attribute__ ((noinline)) void foo()
{
}
Run Code Online (Sandbox Code Playgroud)
这对我有用.
使用noinline 属性:
int func(int arg) __attribute__((noinline))
{
}
Run Code Online (Sandbox Code Playgroud)
在声明外部使用函数和编写函数时,您应该使用它.
| 归档时间: |
|
| 查看次数: |
98288 次 |
| 最近记录: |