【问题标题】:Which is faster: Empty Function Call or If Statements?哪个更快:空函数调用或 If 语句?
【发布时间】:2012-05-29 10:32:42
【问题描述】:

我正在实现一个循环缓冲区来存储固定大小的数据结构,如队列。这个循环缓冲区用三个参数初始化:-

/*
 * Initialize the ring buffer.
 * @capacity Max capacity of ring buffer.
 * @item_size Fixed size of item that will be put in this circular buffer.
 * @item_cleaner Clean callback, NULL if cleanup not required.
 */
ringbuf*
ringbuf_create(size_t capacity, size_t item_size, clean_up_cb item_cleaner)

我的循环缓冲区始终处于wrapping 模式,这意味着当新项目放入完整的循环缓冲区时,最后一项总是被替换。由于动态分配的对象也可以放入这个缓冲区,因此循环缓冲区会保持引用一个清理回调函数,以便在替换或删除项目时释放它们。但同时这个回调函数也可以是NULL(不需要清理的时候)。在我的代码中到处都有这样的语句:-

if(buffer->callback != NULL)
   buffer->callback(item);

现在,为了防止这些if 语句,当用户不提供任何回调函数时,我放置了空存根函数。这会阻止我每次检查回调函数是否为NULL

使用这种方法,我的代码看起来很整洁。但我不确定,其中哪一个更快?在装配级别上,empty function callif statement 在速度方面有何关联?它们是等价的吗?

【问题讨论】:

  • 你测量一下怎么样?或者,如果性能非常重要并且代码执行频繁(不太可能,你有证据证明它很重要吗?)你可以使用预处理器生成一个没有回调的版本。
  • 试试看。还要记住,在大多数处理器上,if 的性能取决于选择哪一侧的可预测性(所以当你尝试它时,让测试做一些现实的事情)。如果您要问性能问题,请包括您的目标平台——它与代码本身一样重要。
  • 视情况而定。编译器?优化级别?
  • 这取决于编译器、编译器设置、目标架构、ABI 和实际处理器。所以真正的答案需要这些数据。我的情况是,我会使用更整洁的代码。它可能更快或更慢,但都不会太多。
  • 如果你吸引到一个关于精打细算的演讲,不要感到难过 :)

标签: c performance


【解决方案1】:

不用担心速度,我可能只是编写代码:

 if (buffer->callback) buffer->callback(item);

仅仅是因为它既清晰又惯用。而且它肯定不会比空函数调用慢。

【讨论】:

    【解决方案2】:

    一个空的存根函数实际上是两个 JMP 操作和 CPU 上分配的 PUSH/POP 操作。 IF 通常是一个 COMP 操作,它比任何 JMP+PUSHS+POPS 都便宜得多。

    如果您的 'IF 通常返回 false/true,那么我不会担心它,因为 CPU 通过预测结果以非常好的方式优化 IF,只要 IF 是“可预测的”(通常返回 true 或 false 或有一些真/假模式)

    我会选择 IF。

    【讨论】:

    • 其实在if的情况下也会产生条件跳转指令。这就是if 的真正含义:条件跳转。
    • 证明:pastebin.com/ZBPuVF5P 使用 gcc -O3 -S 编译时,在汇编代码输出中有 je 指令。
    • 你是对的,你是错的。 if 实际上是条件跳转,但优化不在程序集中,而是在 CPU 中。 CPU 跟踪分支预测表中的所有条件跳转并优化执行。阅读更多igoro.com/archive/…
    • 我哪里错了?我在哪里说过“优化”?我说:if 产生条件跳转。很明显,条件跳转取决于 CPU 的分支预测。我从来没有说过不是。
    • 另一方面,在其当前版本中,your answer 基本上是说:'An if 产生一个比任何 JMP+PUSHS+POPS 都便宜得多的 COMP '。这,错了。 if 不会产生单个 COMP。它还会产生一个条件跳转,它可能会也可能不会成功。
    猜你喜欢
    • 1970-01-01
    • 2017-08-29
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 2012-03-21
    • 2011-06-10
    • 1970-01-01
    • 2020-10-19
    相关资源
    最近更新 更多