gpt4 book ai didi

c - C 调用约定的参数顺序是否会对性能产生影响?

转载 作者:太空狗 更新时间:2023-10-29 17:11:03 25 4
gpt4 key购买 nike

例如,函数:

void foo(float*,float*,int,float);
void foo(float*,float,float*,int);

开销相同还是不同?

编辑:我不是在问编译器将如何优化事物。我特别询问与 cdecl calling convention 有关的问题各种 ABI 的开销有何不同。

最佳答案

传统的调用约定几乎总是在堆栈上分配参数空间,并且总是存在与将参数复制到该空间相关的开销。

假设一个严格易变的环境,唯一可能存在的额外开销可能来自内存对齐问题。在您给出的示例中,参数将位于连续的内存中,因此不会有任何填充可以正确对齐。

对于具有不同大小类型的参数,以下声明中的参数:

int func (int a, char c, int b)

它们之间会有填充,而在这个声明中的那些:

int func (int a, int b, char c)

不会。

前者的堆栈框架可能如下所示:

| local vars... |                  low memory
+---------------+ - frame pointer
| a | a | a | a |
| c | X | X | X |
| b | b | b | b |
+---------------+ high memory

对于后者:

| local vars... |                  low memory
+---------------+ - frame pointer
| a | a | a | a |
| b | b | b | b |
| c | X | X | X |
+---------------+ high memory

当函数被调用时,参数将按照它们出现的顺序写入堆栈内存,因此对于前者,您将写入 4 个字节的 int a,1 个字节的char c,那么你需要跳过这3个字节来写入int b的4个字节。

在后者中,您将写入连续的内存位置,并且不需要考虑由于填充而导致的跳过。

在多变的环境中,我们谈论的是跳过几纳秒数量级的性能差异。性能损失可能是可检测的,但几乎可以忽略不计。

(顺便说一下,如何完成跳过完全取决于架构......但我敢打赌,一般来说,这只是下一个要填充的地址的更高偏移量。我不完全确定这可能是怎么回事在不同的体系结构中以不同的方式完成)。

当然,在非 volatile 环境中,当我们使用 CPU 缓存时,性能下降到几分之一纳秒。我们将冒险进入无法检测的领域,因此实际上不存在差异。

数据填充实际上只是一个空间成本。当您在嵌入式系统中工作时,您会希望将参数从最大到最小排序以减少(有时甚至消除)填充。

因此,据我所知(没有进一步的信息,例如特定机器或架构上内存之间的确切数据传输速率),不同的参数顺序应该不会影响性能。

关于c - C 调用约定的参数顺序是否会对性能产生影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31214567/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com