简体   繁体   English

在优化方面,定义带参数和不带参数的函数指针有什么区别

[英]In term of optimization, What is the difference between defining function pointer with argument and without argument

I know that defining function pointer in this way 我知道以这种方式定义函数指针

struct handler_index {
    const char *name;
   int (*handler)();
};

allow to use handler pointer for any function with unspecified (but non-variable) number and types of parameters. 允许对具有未指定(但不可变)数量和参数类型的函数使用处理程序指针。

but I m wondering if this definition could affect the optimization of code or memory or execution time comparing to this: 但我想知道,与此定义相比,此定义是否会影响代码或内存的优化或执行时间:

struct handler_index {
    const char *name;
    int (*handler)(int a, int b);
};

If you're wondering how adding more parameters to a function pointer affects specifically the function pointer -- it doesn't. 如果您想知道向函数指针添加更多参数是如何特别影响函数指针的 -不会。 Function pointers are all the same size regardless of the number of parameters. 无论参数数量如何,函数指针的大小都相同。

If you're wondering about efficiency of calling such a function pointer: adding more parameters will result in code being generated to pass arguments. 如果您想知道调用这样的函数指针的效率:添加更多参数将导致生成代码以传递参数。 So yea, it will affect code size of the call slightly, and maybe execution time depending on how much ILP your CPU can pull off while passing those args. 所以,是的,这会稍微影响调用的代码大小,并且可能会影响执行时间,具体取决于传递这些arg时CPU可以拉出的ILP数量。

Modern calling conventions often pass some number of arguments in registers, so you may or may not have an increase in stack usage. 现代调用约定通常在寄存器中传递一定数量的参数,因此您可能会或可能不会增加堆栈使用率。

To see exactly what the difference is between code generated for each call, read up on calling conventions (there are too many to list here!) and check the asm generated from your code. 要确切了解每次调用生成的代码之间的区别,请仔细阅读调用约定 (此处列出的内容太多!),并检查从代码生成的asm。 But really, adding more parameters (within reason) is probably going to have such a vanishingly small effect that it simply doesn't matter. 但是,实际上,添加更多参数(在合理范围内)可能会产生很小的效果,以至于根本没有关系。

As Cory says, it's not really relevant whether it is a function pointer or just a regular basic function [except in cases where a regular function gets inlined, which of course, function pointers generally can't - although if the situation is specific enough I have seen the compiler actually figure out "Ah, we're always calling function X here, so lets inline X" - typically when the function pointer is an argument to a function, rather than say in a structure). 正如Cory所说的,它是函数指针还是普通的基本函数并没有什么关系[除非在常规函数被内联的情况下,通常,函数指针通常不能-尽管这种情况足够具体,看到编译器实际上发现“啊,我们总是在这里调用函数X,所以让内联X”-通常是当函数指针是函数的参数,而不是在结构中说时)。

What WILL make a difference is adding arguments to function calls in general. 通常会在函数调用中添加参数,这将有所作为。 The processor will have to place those arguments somewhere, and even if they go in registers, it may require extra instructions to get the value into the RIGHT register. 处理器将不得不将这些参数放在某个地方,即使它们进入寄存器,也可能需要额外的指令才能将值放入RIGHT寄存器。

However, your first example is very bad because there's no check that your code is doing the right thing. 但是,您的第一个示例非常糟糕,因为无法检查您的代码是否在做正确的事情。

Further, you need some pretty pathological cases to make the overhead of passing arguments to a function to be much of the time of calling a function pointer - hopefully your function does more than add one number to another. 此外,您需要一些相当麻烦的情况,以使将参数传递给函数的开销花在调用函数指针上的大部分时间上-希望您的函数所做的不只是将一个数加到另一个上。

Having said that, passing LOTS of arguments, especially "hard to get" arguments can be really bad. 话虽如此,传递很多论点,尤其是“难于获得”的论点可能真的很糟糕。 I was working on a graphics chip simulator, and part of the pixelshader processing unit had a debug print in the middle of it, which rarely got printed, but it took something like 7 or 8 arguments (aside from the debug level of 1000 or whatever it was). 我当时在图形芯片模拟器上工作,部分pixelhader处理单元在其中部进行调试打印,很少打印出来,但是它需要7或8个参数(除调试级别1000或其他条件外)它是)。 Fishing out those arguments from the respective structures and sticking them on the stack took quite some time, and putting an "if (debuglevel >= 1000) ..." so that the call was only made when it was actually needed, made the code some 40% faster in that function. 从各个结构中找出这些参数并将它们粘贴到堆栈上花费了很长时间,然后放置了一个“ if(debuglevel> = 1000)...”,以便仅在实际需要时才进行调用,从而使代码该功能快40%。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM