加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 嵌套函数调用速度与否?

发布时间:2020-12-16 10:50:18 所属栏目:百科 来源:网络整理
导读:我和朋友有这个愚蠢的争论,需要一个权威的话. 我有这两个片段,想知道哪一个更快? [A或B] (假设编译器没有优化任何东西) [一个] if ( foo () ); [B] int t = foo ();if ( t ) 编辑:伙计们,这对你来说可能看起来很愚蠢,但我有一位硬件工程师朋友,他认为即使
我和朋友有这个愚蠢的争论,需要一个权威的话.

我有这两个片段,想知道哪一个更快? [A或B]

(假设编译器没有优化任何东西)

[一个]

if ( foo () );

[B]

int t = foo ();
if ( t )

编辑:伙计们,这对你来说可能看起来很愚蠢,但我有一位硬件工程师朋友,他认为即使没有优化(采取任何处理器,任何编译器对),CASE B总是更快,因为它不会获取内存来自先前指令的结果,但通过绕过该数据直接访问公共数据总线的结果(记住5级流水线).

虽然我的论点是这样的,没有编译器通知要复制或检查多少数据,但是不可能这样做(你必须转到内存来获取数据,没有编译器优化)

解决方法

对于记录,gcc在使用特别禁用的优化(-O0)进行编译时,会为两个输入生成不同的代码(在我的情况下,foo的主体是return rand();因此在编译时不会确定结果).

没有临时变量t:

movl    $0,%eax
        call    foo
        testl   %eax,%eax
        je      .L4
        /* inside of if block */
.L4:
        /* rest of main() */

这里,foo的返回值存储在EAX寄存器中,寄存器针对自身进行测试以查看它是否为0,如果是,则跳过if块的主体.

使用临时变量t:

movl    $0,%eax
        call    foo
        movl    %eax,-4(%rbp)
        cmpl    $0,-4(%rbp)
        je      .L4
        /* inside of if block */
.L4:
        /* rest of main() */

这里,然后压入堆栈.然后,将堆栈上的位置内容与文字0进行比较,如果它们相等,则跳过if块的主体.

因此,如果我们进一步假设处理器在为此生成微码时没有进行任何“优化”,那么没有临时的版本应该更快几个时钟周期.它不会快得多,因为即使具有临时的版本涉及堆栈推送,当比较指令在字之后立即执行时,堆栈值几乎肯定仍然在处理器的L1缓存中,因此不会是一次往返RAM的往返旅程.

当然,只要打开任何优化级别,即使是-O1,代码就会变得相同,并且编译任何非常关键的东西,以至于他们关心所有优化关闭的少数时钟周期?

编辑:关于您有关硬件工程师朋友的更多信息,我无法看到如何访问L1缓存中的值比直接访问寄存器更快.如果值永远不会离开管道,我可以看到它的速度一样快,但我看不到它更快,特别是因为它除了比较之外还必须执行movl指令.但是告诉他上面的汇编代码并询问他的想法;它会比用C来讨论问题更有成效.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读