gpt4 book ai didi

C静态内联参数评估优化

转载 作者:太空狗 更新时间:2023-10-29 16:56:33 25 4
gpt4 key购买 nike

假设一个 API,其中每个函数都返回一个错误代码,如果没有错误,错误代码为零,错误值则为非零。

int foo(...);
int bar(...);

在此 API 中发挥作用。假设有一个代码片段,其中必须按顺序调用 foobar 并且应该始终 调用 foo 和 bar,无论先前的错误如何,但要传播第一个返回的非零错误代码,即

int foobar(...)
{
int rc = 0, rc_;
/* ... */
rc_ = foo(...); rc = rc ? rc : rc_;
rc_ = bar(...); rc = rc ? rc : rc_;
return rc;
}

编写 rc,rc_ 多路复用很累而且容易出错(无论是否使用三元运算符,if/else 或其他东西)。

让传播辅助函数出现错误

static inline
int rc_propagate(int r, int p){ return p ? p : r; }

这可以像这样在 foobar 中使用

int foobar(...)
{
int rc = 0;
/* ... */
rc = rc_propagate(foo(...), rc);
rc = rc_propagate(bar(...), rc);
return rc;
}

C 标准是否允许通过将静态内联函数 rc_propagate 的第一个参数的评估拉入三元来进行优化,以便它可能由于三元运算符评估规则而无法执行如果第二个参数 p 不为零?

最佳答案

只要程序保持不变,编译器(或硬件)就可以优化程序1,也就是说,您无法证明所执行的程序与之前的程序不同你写的。

在这种情况下,您编写的程序将始终调用外部函数,因为它不存在于可能无法计算的三元运算符中。该函数可能有不同的有趣副作用,并且编译器不知道。这意味着程序的优化版本将不得不在某个时候调用外部函数(代码可能会重新排序)以保持该行为。

如果那不是真的,您可以证明所执行的程序与您编写的程序不同。这样做很容易;将 printf(或等效)语句放入外部函数调用中。

<子>1。执行时存在的抽象程序的概念,而不是生成的机器代码或可执行文件。


使用来自权威的论据,您可以看到没有编译器实际上会优化对 foo() 和 bar() 的调用:

带有 -O2 的 gcc 版本 4.9.2、5.3 或 6.1:

foobar():
pushq %rbx
call foo()
movl %eax, %ebx
call bar()
testl %ebx, %ebx
cmove %eax, %ebx
movl %ebx, %eax
popq %rbx
ret

带有 -O2 的 clang 版本 3.7.1 或 3.8:

foobar():                          
pushq %rbx
callq foo()
movl %eax, %ebx
callq bar()
testl %ebx, %ebx
cmovnel %ebx, %eax
popq %rbx

关于C静态内联参数评估优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38175070/

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