Enhance struct pointer access, by placing scalars at the beginning and arrays as sub-sequent struct members.
Thumb2 instructions encode a limited displacement for memory access. When a struct is accessed via a pointer, scalar variables at the beginning of a struct can be directly accessed. Arrays always require address calculations. Therefore, it is more efficient to place scalar variables at the beginning of a struct
-------------------------------------------------------------------------------------- Frankly speaking, I don't understand above form uvision4 tutorial. English is not my native language.
anybody can help explain its details? why scalar variables at the beginning of a struct will bring more efficiency? Thank you very much.
typedef struct { int x; int arr[10]; } sx; int f (sx xdata *sp, int i) { return sp->arr[i]; }
BR,
Write some code, compile the code and then debug it in assembler view and look at the instructions. That should give you an indication.
When you have a struct and assign the variable to a pointer, you may then use the pointer to access members of the struct.
If you have the struct:
struct my_struct { int a; int b; char c,d,e,f; int more[10]; }; struct my_struct my_var; struct my_struct *p = &my_var;
Now, if you want to use the pointer p, to access a, you find that p points to the start of the struct. And a is at the start of the struct. So p will directly point to the member a. Very efficient.
If you want to access the member b, then you need to add an offset of 4 (a is 4 bytes large), so the processor (having loaded the value pointer p into a register) needs to add an offset of 4. This is efficiently done with the existing assembler instructions.
But when the struct gets too large, member variables at the end, will have too large offset, so the compiler can't directly add the required offset without extra instructions. The THumb instructions are only 16-bit large while the ARM instructions are 32-bit large. That affects how large offsets you can fit in a single instruction without having to switch to more complex addressing methods.
And the text is saying that whenever the compiler generates code that accesses a member of an array inside a struct it will first have to create a new pointer that points to the start of the array. And then it will add any offset to reach the specific element of the array. Since the compiler always needs extra instructions to reach the requested array elements, they don't suffer any extra penalty for being last in a struct. But a scalar member does suffer if it is too far down in the struct so it can't be directly indexed.
Hi Per Westermark,
Thanks a lot for your help. I know about what you says.
I have 2 addition questions, could you please help me?
(1)what is the max offset allowed which disable complier to switch to more complex addressing methods when scalars is at the beginning of Struct? how many bytes?
(2)where such description document can be found ?
thanks.
Fisher
infocenter.arm.com/.../QRC0001_UAL.pdf
Page 4 have load and store instructions, and mentions sizes of offsets. So many load/store operations have +/- 4095 as max offset.
Full description of all instructions can be found directly from infocenter.arm.com
Sorry, I'm a bit tired today. For thumb-2 mode, you normally have a limit of +255 instead of +4095. And array indexing can only scale with left-shift 0 to 3 steps, i.e. 1, 2, 4 and 8 byte large array entries can be quick-accessed.
Thank you very much.