当C函数必须返回多个值时,有几种方法可以做到这一点。
现在我对其中两种方法的相对效率感兴趣:
a)将值绑定到struct foo中。填充一个本地foo,并返回它。
B)传递要填充的指针。
(我正在处理一些混合了这两种代码的遗留代码。
就这篇文章而言:
- 所有返回的值都是基元。int、指针值等。所以sizeof(foo)非常小。
- 让struct foo不透明不是问题。
- 这些函数最多有12个参数,包括所有ptr-to-return-value参数。
- 假设一个有点现代的编译器,例如GCC 11或更高版本。
显然,内联会使这个问题变得毫无意义。
不同的方法会影响编译器内联的能力吗?
如果不内联,这两种方法之间是否会有性能差异?
在函数参数中放置返回值指针参数会有影响吗?是取决于编译器的内联能力,还是取决于非内联性能?
为清楚起见,编辑了(a)。
2条答案
按热度按时间2hh7jdfx1#
这是ABI特有的。
在Linux / x86-64上,一个
struct
只有两个单词(例如两个指针或两个intptr_t
或两个long
-s)在两个寄存器中返回。这比例如要快得多。malloc
-ing它,并且可能比由调用者在调用堆栈上分配的写入两个字struct
更快(那么它可能在一些快速CPU cache;请记住,在最近的处理器上,高速缓存未命中可能需要数百纳秒,或者一百个寄存器寄存整数加法机器指令所需的时间)但是内联函数并不总是更快。您还可以使用部分求值技术或C代码生成(如RefPerSys)
使用最新的GCC编译器,还可以考虑编译所有C或C文件 *,并使用链接时优化(例如:
-flto -O2
)owfi6suc2#
我想,问题是:更快(假设没有内联):
字符串
对
型
struct
变体将更快,因为它不必从内存中加载单个指针(在x86
上,您只能在寄存器中传递几个指针,其余的将溢出到堆栈中)。但是,调用方上下文也很重要。如果调用者看起来像这样:
型
则节省的部分将被“解包
foo
”代码大大抵消。但如果呼叫者看起来像这样:
型
则“解包”代码将不存在。