首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >帮助编译器优化函数指针

帮助编译器优化函数指针
EN

Stack Overflow用户
提问于 2012-11-16 02:40:05
回答 2查看 3.5K关注 0票数 19

在C中实现类OO代码封装和多态性的一种常见方法是将不透明的指针返回到包含某些函数指针的结构。例如,在Linux内核中,这是一种非常常见的模式。

使用函数指针而不是函数调用引入了开销,由于缓存,该开销几乎可以忽略不计,正如在其他问题中已经讨论过的那样。

然而,随着针对GCC (>4.6)的new - for program和-flto优化选项的出现,情况发生了变化。

libPointers.c

代码语言:javascript
复制
#include <stdlib.h>
#include "libPointers.h"

void do_work(struct worker *wrk, const int i) 
{
        wrk->datum += i;
}

struct worker *libPointers_init(const int startDatum)
{
        struct worker *wrk = malloc (sizeof (struct worker));

        *wrk = (struct worker) {
                .do_work = do_work,
                .datum = startDatum
        };

        return wrk;
}

libPointers.h

代码语言:javascript
复制
#ifndef __LIBPOINTERS_H__
#define __LIBPOINTERS_H__


struct worker {
        int datum;

        void (*do_work)(struct worker *, int i);
};

extern void do_work (struct worker *elab, const int i);

struct worker *libPointers_init(const int startDatum);


#endif //__LIBPOINTERS_H__

testPointers.c

代码语言:javascript
复制
#include <stdio.h>
#include "libPointers.h"


int main (void)
{
        unsigned long i;
        struct worker *wrk;

        wrk = libPointers_init(56);

        for (i = 0; i < 1e10; i++) {
#ifdef USE_POINTERS
                wrk->do_work(wrk,i);
#else
                do_work(wrk,i);
#endif
        }

        printf ("%d\n", wrk->datum);
}

使用-O3编译,但没有-flto - flags testPointers标志,在我的机器上执行USE_POINTERS大约需要25秒,而不管USE_POINTERS是否定义了#。

如果我打开-flto - call 程序标志,在定义USE_POINTERS #的情况下,testPointers大约需要25秒,但如果使用函数调用,则大约需要14秒。

这是完全预期的行为,因为我知道编译器将内联并优化循环中的函数。然而,我想知道是否有一种方法可以帮助编译器告诉它函数指针是常量,从而允许它优化这种情况。

对于那些使用cmake的人,我是如何编译它的

CMakeLists.txt

代码语言:javascript
复制
set (CMAKE_C_FLAGS "-O3 -fwhole-program -flto")
#set (CMAKE_C_FLAGS "-O3")
add_executable(testPointers
        libPointers.c
        testPointers.c
        )
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-11-16 03:02:36

编译器不能内联一个函数,除非它确定只有一个可能的函数版本会被调用。通过指针调用,事实并非如此。编译器仍然有可能找出它,因为如果你遵循代码,指针只有一个可能的值;然而,这将超出我期望编译器所做的事情。

票数 10
EN

Stack Overflow用户

发布于 2016-01-28 09:38:16

如果在循环中调用函数指针,则可以将循环移动到函数指针内。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13404007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档