tags:

views:

357

answers:

8
+2  Q: 

Code optimization

If I have a big structure(having lot of member variables). This structure pointer is passed to many functions in my code. Some member variables of this structure are used vary often, in almost all functions.

  1. If I put those frequently used member variables at the beginning in the structure declaration, will it optmize the code for MCPS - Million cycles per second(time consumed by the code). If i put frequently accessed members at time, will they be accessed efficiently/lesser time than if they are put randomly in the structure of at bottom of structure declaration? If yes what is the logic?

  2. If I have a structure member being accessed in some function as follows:

    structurepointer1->member_variable

Will it help in optimizing it in MCPS aspect if I assign it to a local variable and then access the local variable, as shown below?

local_variable = structurepointer1->member_variable;

If yes, then how does it help?

+13  A: 

1) The position of a field in a structure should have no effect on its access time except to the extent that, if your structure is very large and spans multiple pages, it may be a good idea to position members that are often used in quick succession close together in order to increase locality of reference and try to decrease cache misses.

2) Maybe / maybe not. In fact it may make things slower. If the variable is not volatile, your compiler may be smart enough to store the field in a register anyway. Even if not, your processor will cache its value, but this may not help if is uses are somewhat far apart, with lots of other memory access in between. If the value would have either been stored in a register or would have stayed in your processor's cache, then assigning it to a local will only be unnecessary extra work.

Standard Optimizations Disclaimer: Always profile before optimizing. Make sure that what you are trying to optimize is worth optimizing. Always profile your attempted optimizations and make sure they actually made things faster (and not slower).

Tyler McHenry
There are cache-line considerations as well as page considerations, but in general, I agree.
+5  A: 

First, the obligatory disclaimer: for all performance questions, you must profile the code to see where improvements can be made.

In general though, anything you can do to keep your data in the processor cache will help. Putting the most commonly accessed items close together will facilitate this.

Mark Ransom
+1  A: 

I think your question is related with data alignment and data structure padding. In modern compilers this is handled automatically the most of the times, trying to avoid the alignment faults that could happen on memory. You can read about this here. Of course, you can change the alignment for your data, but I think you would need to specify some compiler options to disable auto-alignment and rearrange the fields on the structure to match the architecture you are aiming to.

I would say this is a very low level optimization.

Edmundo
+2  A: 

I know this is not really answering your question, but before you delve into super-optimizing your code, go through this presentation http://dl.fefe.de/optimizer-isec.pdf. I saw it live and it was a good eye opening experience showing compilers are getting far more advanced in optimization than we tend to think and readable code is more important than small optimizations.

On 2, you most likely are better off not declaring a local variable. The compiler is usually smart enough to figure out when and how variable is used and utilize registers to keep it around.

Also, I would second Mark Ransom's suggestion, profile the code before making assumptions about bottlenecks.

Nasko
A: 
  1. The location of the field in the structure is irrelevant as that will be calculated by the compiler. A more promising optimization is to make sure that your most-used fields are byte-aligned with the word size of your processor.

  2. If you are using the variable local to a function, this should have no impact. If you are passing it to other functions (separate from the larger structure) than that might help a bit.

(1) is not strictly true. The compiler can change field alignment and add padding around fields (unless compiler-specific extensions are used to control these things), but it is not allowed to re-order fields.
Tyler McHenry
A: 

As with all of the other answers, you need to run a profile baseline before optimizing, to make sure changes are effective. If you're worried about execution time, profile your algorithms and optimize them before you worry about the code a compiler creates, more bang for the buck.

Also, if you want to know what is going to happen, you should consider compiling your c code into assembly output. This will give you an idea of what the compiler is going to do and how you may go about further "fine tuning".

  1. Structure access is most always indexed indirect access. The assembly code will effectively pull memory knowing the pointer to the structure as the base plus and index to get the right field. This is usually an expensive operation, but for modern CPU's its probably not that slow.

  2. This depends on the locality of the data being accessed. First and foremost accessing the structure the first time will be the most expensive. Accessing the data afterwards, can be quick if the data is already in a processor register, however, this may not be the case depending on the processor used. Storing to a local variable should be less expensive since the memory access instructions for such an operation is less expensive. Again, I think now days processors are fast enough that this optimization is minimal.

I still think that there are probably better places to optimize your code. It is good though that there is someone out there that thinks about this still, in a world of code bloat ;) Embedded computing, you still need to worry about these things.

KFro
A: 
  1. This depends on the size of your fields and caching details. Look at using valgrind for profiling this.
  2. If you doing this dereferencing a lot it would cost time. A decent optimizing compiler will effectively do the storing the pointer into the local variable optimization as you described. It will do a better job than you will and it will do it in an architecture-specific way.


What you want to do in this situation, overall, is make sure that you test the correctness and the performance of each optimization you are trying. Otherwise you are poking around in the dark.

Remember that fine optimizations at the C line level will virtually never trump higher-order algorithm/design optimizations.

D'Nabre
A: 

Yes, it can help. But as people have already stated, it depends and can even be counter productive. The reason why I think it can help, has to do with pointer aliasing. If you access your variables via a pointer, and the compiler can not guarantee that the structure was not changed elsewhere (via your pointer or another) he will generate code to reload or save the variable even if he could have hold the value in a register. Here an example to show what I mean:

calc = structurepointer1->member_variable * x + c;    
/* Do something in function which doesn't involve member_variable; */
function(structurepointer1);    

calc2 = structurepointer1->member_variable * y;

The compiler will make a memory access for both references to member_variable, because it can not be sure that the called function has modified that field. If you're sure the function doesn't change that value, doing this would save 1 memory access

int temp = structurepointer1->member_variable;
calc = temp * x + something;
function(structurepointer1);
calc2 = temp * y;

There's also another reason you can use a local variable for your member variables, it can make the code much more readable.

tristopia
If you function changes the member variable, it gets even more interesting to use a temporary. In my example above, the call to function will in all cases force a memory write before the function call, even if it is not used in the function, and this is more serious than read access.
tristopia