c语言中让循环慢下来,c-函数指针会使程序变慢吗?

您会发现,在从性能角度看实际上很重要的情况下,例如在一个循环中多次重复调用该函数,性能可能根本没有什么不同。

对于习惯将C代码视为由抽象C机器执行的东西的人来说,这听起来有些奇怪,而抽象C机器的“机器语言”与C语言本身非常相似。 在这种情况下,“默认情况下”对函数的间接调用确实比直接调用慢,因为它在形式上涉及额外的内存访问以确定调用目标。

但是,在现实生活中,代码是由一台真正的机器执行的,并由对底层机器体系结构非常了解的优化编译器进行编译,这有助于它为该特定机器生成最佳代码。 在许多平台上,可能会发现从循环执行函数调用的最有效方法实际上导致直接和间接调用的代码相同,从而导致两者的性能相同。

考虑例如x86平台。 如果我们“直截了当地”将直接和间接调用转换为机器代码,我们可能最终会遇到这样的情况

// Direct call

do-it-many-times

call 0x12345678

// Indirect call

do-it-many-times

call dword ptr [0x67890ABC]

前者在机器指令中使用立即数操作数,实际上通常比后者要快,后者必须从某个独立的内存位置读取数据。

在这一点上,让我们记住x86体系结构实际上还有另一种方法可以为call指令提供操作数。 它在寄存器中提供目标地址。 关于此格式的一个非常重要的事情是,它通常比上述两种都快。 这对我们意味着什么? 这意味着一个好的优化编译器必须并且将利用这一事实。 为了实现上述循环,在两种情况下,编译器都会尝试使用通过寄存器的调用。 如果成功,则最终代码可能如下所示

// Direct call

mov eax, 0x12345678

do-it-many-times

call eax

// Indirect call

mov eax, dword ptr [0x67890ABC]

do-it-many-times

call eax

注意,现在重要的部分-循环主体中的实际调用-在两种情况下完全相同。 不用说,性能几乎是相同的。

甚至有人说,无论听起来多么奇怪,在此平台上,只要在寄存器中提供了间接调用的操作数,直接调用(使用立即操作数的调用在call中)就会比间接调用慢。 而不是存储在内存中)。

当然,在一般情况下,整个过程并不容易。 编译器必须处理有限的寄存器可用性,别名问题等。但是,在您的示例中(甚至在更复杂的情况中)这种简单的情况,上述优化将由好的编译器执行,并将完全消除 循环直接调用和循环间接调用之间的性能差异。 在调用虚拟函数时,此优化在C ++中特别有效,因为在典型的实现中,所涉及的指针完全由编译器控制,从而使它充分了解别名画面和其他相关内容。

当然,始终存在一个问题,即您的编译器是否足够聪明,可以优化诸如此类的东西...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值