This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: TI C/C++ Compiler
Hello,
I would appreciate if you can clarify about the aligned and unaligned access in the C66xx DSP.
From what i understood the DSP supports both aligned and unaligned accesses but each has its own syntax.
When writing is C, what is the default assumption of the compiler when accessing memory through a pointer (i.e. uint32_t *ptr or uint64_t *ptr)?
When do i need to use the mem4/mem8 or amem4/amem8 intrinsics?
What about 16bit word accesses (i.e. uint16_t) , what happens if the pointer is not aligned to 16bit (there is no mem16)?
What happens with void pointers ?
Thanks
I think most of your questions are answered in the section titled Methods to Align Data in the C6000 compiler manual.
However, there is an error in that section. When compiling for C6600, arrays are aligned on an 8-byte boundary, and not a 16-byte boundary. Therefore, the example macro ALIGNED_ARRAY is incorrect. I filed CODEGEN-5247 in the SDOWP system to have this error corrected.
Thanks and regards,
-George
Guy Mardiks said:I looked at the section you mentioned and this made things even more unclear.
I agree that the section is not written on point to your questions. But it does make clear some details I think are relevant.
Thanks and regards,
-George
Generally speaking ... The compiler assumes a scalar is aligned to the size of the type, i.e. char is 1-byte aligned, short is 2-byte aligned, etc. Otherwise, nothing is assumed about alignment. The compiler, as an optimization, attempts to determine when a greater alignment must be in effect. When a greater alignment can be proven, it is used.
To make this a bit more concrete ... For a function with this prototype ...
int fxn(int *ptr, int length);
The compiler presumes ptr contains an address that is aligned to 4 bytes. But suppose you always pass the base address of an array as the first argument. This means ptr is actually aligned to 8 bytes. Then you can inform the compiler about this fact by adding ...
_nassert((int) ptr % 8 == 0);
This extra information makes it possible for the compiler to use SIMD instructions that require 8-byte alignment of the memory operands.
Guy Mardiks said:1. Does that mean that when having an array that is shared between multiple cores - does this mean i always make it aligned to 8bytes, otherwise DSP might get a different address than other cores?
No. But if you do make it 8-byte aligned, inform the compiler with an _nassert.
Guy Mardiks said:3. when cannot be certain of an alignment of a given address and still need to read more than 1 byte (16bits / 32bits /64 bits),
does this mean i must use the mem4/mem8 intrinsics?
Yes
Guy Mardiks said:2. when array is under a struct, does the compiler always generate unaligned accesses
For a reference like ptr->array[i], the compiler can determine the alignment automatically, and act accordingly.
Guy Mardiks said:4. how do void pointers treated (as 32bit aligned?)?
The C language does not allow a void pointer to be dereferenced. You first have to copy it to a pointer that is a non-void type. It is the user's responsibility to insure the alignment requirements of that non-void type are always met.
Thanks and regards,
-George
Guy Mardiks said:You answered no about needing to have an array aligned to 8bytes when the array is shared between different cores (no all DSP cores).
Can you explain why it will be OK?
I need to refine my answer. It is not always OK.
The C6000 compiler aligns all arrays to an 8-byte boundary. If it sees something like ...
extern int int_array[];
... the compiler presumes int_array is aligned on an 8-byte boundary. But if it sees ...
int fxn(int *ptr, int length)
Because ptr points to an int, the compiler presumes the address is aligned to a 4-byte boundary. Even though it is likely ptr is the base address of an array, it may not be, and so the compiler conservatively presumes ptr is not aligned to an 8-byte boundary.
So, depending on how you present a shared memory object to the C6000 compiler, you may or may not have to worry with 8-byte alignment.
Guy Mardiks said:char *ptr;
x = *((int *)ptr) -- will the compiler generate 4bytes access
The compiler presumes the type being casted to is in effect, and not the type casted from. In this specific case the compiler presumes ptr is aligned to a 4-byte boundary.
Thanks and regards,
-George