Author Topic: Is function in struct efficient in c?  (Read 5368 times)

0 Members and 1 Guest are viewing this topic.

Offline navidrctTopic starter

  • Regular Contributor
  • *
  • Posts: 117
  • Country: 00
Is function in struct efficient in c?
« on: November 08, 2017, 02:50:17 pm »
Hi
I'm using keil for working with arm mcu
If I put all function that related to each other to a struct , my code will be so easy to read
I do this and in dis assembly code I saw five line for that
But when I use the exact function and I see the dis assembly I saw one line
I really like to use first method . Do u have any suggestion to work it efficiently?
 

Offline stmdude

  • Frequent Contributor
  • **
  • Posts: 479
  • Country: se
Re: Is function in struct efficient in c?
« Reply #1 on: November 08, 2017, 02:55:58 pm »
A few lines of example code would go a long way to explain what you're talking about.

Are you talking about function-pointers in a struct?  Like:

Code: [Select]
struct {
  int (*my_function_pointer)(int a,int b);
} somefunctions;

?
 

Offline navidrctTopic starter

  • Regular Contributor
  • *
  • Posts: 117
  • Country: 00
Re: Is function in struct efficient in c?
« Reply #2 on: November 08, 2017, 03:03:14 pm »
A few lines of example code would go a long way to explain what you're talking about.

Are you talking about function-pointers in a struct?  Like:

Code: [Select]
struct {
  int (*my_function_pointer)(int a,int b);
} somefunctions;

?
Sorry I'm in mobile and I did not have any sample code
Yes that was what I'm talking about
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Is function in struct efficient in c?
« Reply #3 on: November 08, 2017, 03:09:14 pm »
Quote
If I put all function that related to each other to a struct
You can't do that in C without messing around. I wouldn't recommend it.
You can use C++ with classes instead. It's designed to support this.

Function pointers are no problem, they're just like regular pointers.
Remember structs are just a way to abstract data in memory. It is not necessarily faster, except allowing cleaner code.
« Last Edit: November 08, 2017, 03:12:39 pm by Jeroen3 »
 

Offline navidrctTopic starter

  • Regular Contributor
  • *
  • Posts: 117
  • Country: 00
Re: Is function in struct efficient in c?
« Reply #4 on: November 08, 2017, 03:24:53 pm »
Quote
If I put all function that related to each other to a struct
You can't do that in C without messing around. I wouldn't recommend it.
You can use C++ with classes instead. It's designed to support this.

Function pointers are no problem, they're just like regular pointers.
Remember structs are just a way to abstract data in memory. It is not necessarily faster, except allowing cleaner code.
I don't know how to use c++ in keil at all.
If I use function pointer in struct to categorize my functions it won't be efficient right?
 

Offline stmdude

  • Frequent Contributor
  • **
  • Posts: 479
  • Country: se
Re: Is function in struct efficient in c?
« Reply #5 on: November 08, 2017, 03:43:59 pm »
Are you talking about function-pointers in a struct?  Like:

Code: [Select]
struct {
  int (*my_function_pointer)(int a,int b);
} somefunctions;

?
Yes that was what I'm talking about

Ok, that isn't a problem (performance wise) unless you're chasing every single cycle you can. It'll add one memory-read ("mov") to each call to the function, worst-case. I wouldn't worry about it at all.

Edit: It'll disable some optimizations though. Routines called through function-pointers can't be inlined.
 

Offline dmills

  • Super Contributor
  • ***
  • Posts: 2093
  • Country: gb
Re: Is function in struct efficient in c?
« Reply #6 on: November 08, 2017, 03:51:55 pm »
Also, cache performance, IPO, and it makes every struct bigger (Not the case for C++ where non virtual functions can be resolved at compile time).

I would use a C++ compiler (With RTTI and exceptions switched off) if I really wanted to do this routinely. The C++ compiler will know how to get clever with this stuff in a way that a C compiler just does not.

There are places it makes sense, some bits of network stacks spring to mind where implementing state machines by changing function pointers withing structures is actually sort of reasonable.

Regards, Dan.
 
The following users thanked this post: navidrct

Offline navidrctTopic starter

  • Regular Contributor
  • *
  • Posts: 117
  • Country: 00
Re: Is function in struct efficient in c?
« Reply #7 on: November 08, 2017, 04:00:16 pm »
Also, cache performance, IPO, and it makes every struct bigger (Not the case for C++ where non virtual functions can be resolved at compile time).

I would use a C++ compiler (With RTTI and exceptions switched off) if I really wanted to do this routinely. The C++ compiler will know how to get clever with this stuff in a way that a C compiler just does not.

There are places it makes sense, some bits of network stacks spring to mind where implementing state machines by changing function pointers withing structures is actually sort of reasonable.

Regards, Dan.
Thanks allot that was awesome
 

Offline hans

  • Super Contributor
  • ***
  • Posts: 1637
  • Country: nl
Re: Is function in struct efficient in c?
« Reply #8 on: November 08, 2017, 04:08:04 pm »
Done coding with function pointers in C before. Can't recommended.

You're basically re-implementing C++, but with none of the strong-typing compile checks and other benefits C++ brings over C. You will be chasing your own tail why some piece of code will fail to run because some function pointer is incorrectly set.

Moreover I think classes in C++ will do a better job in terms of efficiency.

Like stmdude said, function pointers in C will kill the optimizer and will prevent it from inlining functions. In my own projects I wrote C++ drivers for setting up and using GPIO's, bitbanging I2C, reading/writing EEPROM and a settings manager. With high optimizations GCC was able to inline that whole chain into the settings manager code. If you're doing function pointers in C it won't even come close.

Watch out with virtual methods though. Those are not that efficient, perhaps a bit worse than function pointers in C. However the compiler will do the housekeeping for you, which is nice.

I suppose you're researching now how to write your next project, and in that case you might as well invest in a C++ tool and learning how to use it.
Or accept that C has a certain flavour to it: it's low-level, it's your responsibility to write good code. That is awesome. But writing organized large projects can feel like a chore.
« Last Edit: November 08, 2017, 04:11:56 pm by hans »
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: Is function in struct efficient in c?
« Reply #9 on: November 08, 2017, 04:19:16 pm »
Watch out with virtual methods though. Those are not that efficient, perhaps a bit worse than function pointers in C.
How so?
 

Offline dgtl

  • Regular Contributor
  • *
  • Posts: 183
  • Country: ee
Re: Is function in struct efficient in c?
« Reply #10 on: November 08, 2017, 04:33:33 pm »
In case of using some function pointers where using enums with switches or other methods do not make sense, they are fine. Look at the Linux kernel source code, it is a huge c-only project and it uses quite a lot of function pointers. But just calling everything via function pointers leads to re-inventing the wheel (C++ vtable). Find a C++ compiler and use it.
In case of microcontroller projects, my reasoning of using or not using some technology goes like this: do not do anything in runtime, that can be pre-calculated compile time. So in case your function pointer can only have a single value, it is pointless of using function pointers. Either just define the function header and expect some other compilation unit (c file) to implement it; use preprocessor defines in headers to allow mapping functions to exact implementations (like a lot of projects  do "#define my_printf printf"), use weak functions (like interrupts in ARM world are usually done) etc etc. Keep in mind, that unlike for regular computer libraries, the scope of a project embedded world is usually limited at the compile time and usually there are no plugins or other methods to bring in new code. So there is no point of pushing code to uc that won't be used at all or that will be used only in a few pre-defined cases.
Also another point is safety. Having function pointers in RAM is a risk due to stack overflow or buffer overflow problems (in case the struct with function pointers is not const). For a lot of embedded projects, the worst stack size is not throrughly investigated, it is just hopefully big enough. If things go bad, the function pointer corruption is usually fatal, other kinds of corruptions can be somewhat handled. See for example misra-c if more interested.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26896
  • Country: nl
    • NCT Developments
Re: Is function in struct efficient in c?
« Reply #11 on: November 08, 2017, 04:36:52 pm »
Done coding with function pointers in C before. Can't recommended.

You're basically re-implementing C++, but with none of the strong-typing compile checks and other benefits C++ brings over C. You will be chasing your own tail why some piece of code will fail to run because some function pointer is incorrectly set.
I fully agree! Currently I'm working on an existing piece of code which uses function pointers and void pointers to data which should be 32 bit aligned -shudder-.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline JPortici

  • Super Contributor
  • ***
  • Posts: 3461
  • Country: it
Re: Is function in struct efficient in c?
« Reply #12 on: November 08, 2017, 06:36:40 pm »
You can't do that in C without messing around. I wouldn't recommend it.

what do you mean exactly?
I use structures a lot to pack data/properties/etc about a sensor for example, because then in my fuction i just use pointer to the structure. Only the base address is put on the stack and the compiler takes care of the addressing.
I like how cleaner the code gets (As you point out) and i like the idea that i have a "contained" space where everything about my sensor or whatever is, if such a place can exist in C

Also, i may not have a C++ compiler available for my MCU of choice

(or have i misinterpreted the OP's phrase?)
« Last Edit: November 08, 2017, 06:49:37 pm by JPortici »
 

Offline hans

  • Super Contributor
  • ***
  • Posts: 1637
  • Country: nl
Re: Is function in struct efficient in c?
« Reply #13 on: November 08, 2017, 06:42:27 pm »
Watch out with virtual methods though. Those are not that efficient, perhaps a bit worse than function pointers in C.
How so?

Because virtual methods are defined in some kind of abstract class, which is then implemented by other classes. E.g. if you have an abstract sensor class and have different temperature sensor implementations. From an object orientated programming point of view this is great.

But it's run-time inheritance. Function pointers are stored in a vtable that is added to each type of class instantiated in the code. This is very similar to a struct of function pointers. At least the compilers does the chores for you, but it will generate more code in doing so to solve the inheritance at run-time. And so it will be slower in run-time.

Fortunately you can still explore the extra freedom of C++ without virtual methods, so it's not a disaster. Moreover if you're dealing with high-level concepts of your system, those few extra instructions for e.g. 100 calls/second won't matter neither. But if you're using this on a very low level like MCU peripherals and call abstractions at a high-rate (as you do) then it will matter.

In my experience GCC won't be able to optimize virtual method calls, even if the exact type of class is known at compile time and is not going to change. In that case you're better off [in terms of performance] using templates instead of virtual methods. However creating types composed of multiple template objects is not fun (and CRTP=brainfuck), so it's a trade-off what you want.

Personally I write template classes for hardware abstractions. You can get negative cost C++ code (compared to C) from doing so like I mentioned. Then at a higher level in the firmware I will consider using virtual methods.
« Last Edit: November 08, 2017, 06:44:05 pm by hans »
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Is function in struct efficient in c?
« Reply #14 on: November 08, 2017, 07:10:07 pm »
You can't do that in C without messing around. I wouldn't recommend it.

what do you mean exactly?
I use structures a lot to pack data/properties/etc about a sensor for example, because then in my fuction i just use pointer to the structure. Only the base address is put on the stack and the compiler takes care of the addressing.
I like how cleaner the code gets (As you point out) and i like the idea that i have a "contained" space where everything about my sensor or whatever is, if such a place can exist in C
You can't put a function inside a struct with c. You can only put pointers to functions in structs.
It will literally tell you: error:  #168: a function type is not allowed here
Using structs as "object" containers is a common thing indeed. But you'd have to call the function foo(struct *bar).
A bit like object oriented, but not quite.
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3143
  • Country: ca
Re: Is function in struct efficient in c?
« Reply #15 on: November 08, 2017, 07:41:06 pm »
Aside of being pointless, it is nothing wrong with it. This is, sort of, the beginning of object oriented approach. You may make it useful if you have polymorphic objects which exhibit different behaviour (that is every object has its own function). In this case you actually save tons of code which would decide which function to call.

In terms of efficiency, you add one indirection, so every access to the function will take few more cycles, but this should be Ok with you if you use C (as opposed to Assembler).

C++ objects will add one more level of indirection, your objects will not contain pointers to functions, but rather a single pointer to a table of functions. So it will be even less efficient in terms of speed. Although, static functions will not be in the table and will be called directly.
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: Is function in struct efficient in c?
« Reply #16 on: November 08, 2017, 08:23:13 pm »
... but [the C++ compiler] will generate more code in doing so to solve the inheritance at run-time. And so it will be slower in run-time [than straight C].

I doubt this is the case. At least, if there is any performance hit to using C++ virtual methods compared to rolling your own structs-with-fn-pointers, the difference is going to be vanishingly small.

FWIW, I'm a heavy user of C++ on microcontroller hardware (Cortex-M) using GCC. C++ adds one 32-bit pointer (vptr) to objects that have virtual methods. That pointer indirects to the actual vtable which lives in flash. A virtual method call first needs to load the vptr out of SRAM and then use it to load the method address out of flash. That's two memory loads.

The straight C style posted above essentially puts the entire vtable into each instance. You can get to the address of the method with only one memory load, but at a cost of burning more SRAM. So sure, one memory load is faster than two, but if that difference really matters, you've got other problems to deal with.
 

Offline hans

  • Super Contributor
  • ***
  • Posts: 1637
  • Country: nl
Re: Is function in struct efficient in c?
« Reply #17 on: November 08, 2017, 10:43:58 pm »
If you view it that way, then C++ will scale better in large applications because of RAM usage.

But if you're writing a tight piece of code in terms of execution speed or latency, then these things can matter. I still think the C implementation could be marginally faster, but it maybe won't be much. Nevertheless, there is cost that often needs to be paid by abstraction, and depending on what you do that could be too high either case (despite all the software quality & development benefits).

But in most cases modern microcontrollers are more than capable to handle C++, even the ones with 4KB of RAM or less. I think that if one is contemplating implementing C structs & function pointers, IMO there must be a great counter argument for not choosing C++.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4078
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Is function in struct efficient in c?
« Reply #18 on: November 09, 2017, 06:33:51 am »
Arduino is C++, Mbed is C++.

When your application complexity can benefit from C++, you probably won't notice the slight performance penalty.
With static allocation I think think it isn't very noticeable at all.
 

Online nctnico

  • Super Contributor
  • ***
  • Posts: 26896
  • Country: nl
    • NCT Developments
Re: Is function in struct efficient in c?
« Reply #19 on: November 09, 2017, 11:12:33 am »
Arduino is C++, Mbed is C++.

When your application complexity can benefit from C++, you probably won't notice the slight performance penalty.
With static allocation I think think it isn't very noticeable at all.
That and if you use function pointers to link objects in C then C++ will be faster because it can sort all these links out and do optimisations in either speed or size.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3713
  • Country: us
Re: Is function in struct efficient in c?
« Reply #20 on: November 10, 2017, 05:05:03 am »
... but [the C++ compiler] will generate more code in doing so to solve the inheritance at run-time. And so it will be slower in run-time [than straight C].

I doubt this is the case. At least, if there is any performance hit to using C++ virtual methods compared to rolling your own structs-with-fn-pointers, the difference is going to be vanishingly small.

This is correct.  C++ virtual methods will almost always be as fast or faster than doing the same thing with function pointers in C.  Its doing the same thing, but the compiler can constrain the behavior a lot more, so it can do a better job of optimizing.

For instance, C++ knows that an objects virtual member pointer can't change over the life of an object.  Therefore, if you call a virtual method in a tight loop, the compiler may be able to store the jump address in a register.  If you use explicit function pointers, the compiler can't prove that the function pointer doesn't change as a result of the call and needs to reload it ever iteration.

Virtual method calls do have a slight overhead to static calls of course, especially if the static call can be inlined.  However, if you need the functionality of a dispatch table, virtual functions in C++ will be as fast or faster than rolling your own.

C++ also has the advantage that if the compiler can statically determine the object type, it will automatically convert the virtual calls to static calls.  That can include inlining the method if possible.
 
The following users thanked this post: hans

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3143
  • Country: ca
Re: Is function in struct efficient in c?
« Reply #21 on: November 10, 2017, 02:23:21 pm »
C++ virtual methods will almost always be as fast or faster than doing the same thing with function pointers in C.  Its doing the same thing, but the compiler can constrain the behavior a lot more, so it can do a better job of optimizing.

This is incorrect. Calling virtual method requires fetching a pointer to the VMT, then the pointer has to be fetched from VMT and the function called. Calling a function through a pointer is definitely faster. Therefore virtual function call cannot be faster at any rate.

As to the optimizations, typically C and C++ is the same compiler, and consequently will have the same optimizations. If you have a pointer which always point to the same function (and the compiler knows it), the compiler can eliminate it whether it is C or C++.
 
The following users thanked this post: hans

Offline glarsson

  • Frequent Contributor
  • **
  • Posts: 814
  • Country: se
Re: Is function in struct efficient in c?
« Reply #22 on: November 10, 2017, 05:53:11 pm »
If you have a pointer which always point to the same function (and the compiler knows it), the compiler can eliminate it whether it is C or C++.
The compiler knows it if you declare the function pointer const.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4199
  • Country: us
Re: Is function in struct efficient in c?
« Reply #23 on: November 10, 2017, 11:12:11 pm »
Quote
If I put all function that related to each other to a struct , my code will be so easy to read
I do this and in dis assembly code I saw five line for that
But when I use the exact function and I see the dis assembly I saw one line
I still don't think I understand what the original poster is trying to do.  Can you post actual code?

On ARM, calling a global function means that the compiler will assemble a single "branch and link" instruction, while dereferencing a pointer to a function in a struct means getting the (possibly dynamic) location of a struct, loading the pointer from the struct, and doing an indirect branch on the result.  Five instructions sounds about right.

Based on the subsequent discussion, careful use of "const" and/or "static" might allow the C Compiler to optimize the structure pointer references...

It really does sound like you're looking for C++ "object methods" - note that normal (not virtual) C++ object methods do NOT use pointers; they're based on compile-time magic.
 

Offline gnif

  • Administrator
  • *****
  • Posts: 1675
  • Country: au
Re: Is function in struct efficient in c?
« Reply #24 on: November 10, 2017, 11:32:27 pm »
Function pointers are very useful if used properly, such as bypassing a ton of detection logic after/at first time initialization/use (ie, lazy/late initialization). A project I am currently working on uses them for pixel format handling routines, if the frame pixel format type suddenly changes, everything is reinitialized and the handler function pointer is changed to the one for the correct type avoiding complex conditionals every single frame of data.

In the instance of using them everywhere, I agree with most people here, use C++, you're likely to cause yourself bugs that are near impossible to track down, such as forgetting to initialize one of the pointers, or memory corruption messing with the pointers making debugging the corruption very hard.

For an atomic/singleton instance of an object the pattern I follow is this:

Code: [Select]
struct ExampleState
{
  int x, y;
};

static struct ExampleState example;

int example_initialize()
{
  example.x = 0;
  example.y = 10;
  return 0;
}

void example_deinit()
{
  // do stuff...
}

When multiple instances are needed (ie, like objects) I use the following pattern:

Code: [Select]
struct ExampleState
{
  int x, y;
};

struct ExampleState * example_initialize()
{
  // obviously for embedded you may not want to malloc like this.
  struct ExampleState * state = (struct ExampleState *)malloc(sizeof(struct ExampleState));
  state->x = 0;
  state->y = 10;
  return state;
}

void example_deinit(struct ExampleState * state)
{
  if (!state)
  {
    fprintf(stderr, "warning: null pointer passed to " __FUNC__);
    return;
  }

  // do stuff

  free(state);
}

by prefixing all methods related to the module with the module name it makes your code clear and easy to follow without the need for function pointers everywhere. Really what is cleaner "example->initialize()" or "example_initialize()"? The only thing here that C++ would afford additional is protection (public/private/protected) and extra features such as templates, which for most projects are not needed. Inheritance also, but that can also be done in C without too much trouble with function pointers, the Linux kernel is a perfect example of this, pick any kernel driver to see how they initialize.

Edit:

Actually private protection can be done also by simply not declaring the functions in the header.
« Last Edit: November 11, 2017, 12:19:06 am by gnif »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf