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.

Compiler/MSP430G2744: Specify memory alignment of a packed structure

Part Number: MSP430G2744

Tool/software: TI C/C++ Compiler

CCS6.1, MSP430 compiler TI 4.3.8

Here is the piece of code:

typedef struct __attribute__((packed))
{
  uint8 d0[4];
  uint8 d1[2];
  uint32 d2[2];
  uint16 SlotInfo_Start;
  uint32 EdBitmap[2];
  uint16 SlotInfo_SlotNum;
  ChannelIdT F0Channel;
}RfMsgDGroupEdInfoWithSlotsT;

RfMsgDGroupEdInfoWithSlotsT* groupEdInfoMsgP2 = (RfMsgDGroupEdInfoWithSlotsT*)groupEdInfoMsgP;

uint32 EdBitmap[2];
EdBitmap[0] = groupEdInfoMsgP2->EdBitmap[0];
EdBitmap[1] = groupEdInfoMsgP2->EdBitmap[1];

The compiler will generate complex code to copy EdBitmap[0] and EdBitmap[1] as following. But actually groupEdInfoMsgP2 points to an address that is 4 byte aligned in my code. Can I 
specify to the compiler that groupEdInfoMsgP2 is 4 byte aligned (so member EdBitmap[2] in the structure is also 4 byte aligned), so that copying to EdBitmap[2] could be much faster?

  • I have a suggestion for you to consider.  However, I cannot guarantee it will result in the performance improvement you want.

    Jianyi Bao said:
    Can I specify to the compiler that groupEdInfoMsgP2 is 4 byte aligned

    Yes.  Here is how ...

     _nassert(((int)groupEdInfoMsgP2 % 4) == 0);
    

    That line is how you inform the compiler that pointer is aligned to a 4-byte boundary.  It is your responsibility to insure this is true at all times.  The compiler may generate code which relies on this alignment.  If it is ever not aligned, the generated code may silently access the wrong address.  That is very hard to debug.

    Jianyi Bao said:
    so that copying to EdBitmap[2] could be much faster?

    I cannot guarantee that, when you use this _nassert, you will get a performance improvement.  I'd try it myself, but I can't.  I need a complete test case that can be built to the same assembly you show.  When I try to do that, I have to guess at some things like the build options, the type of ChannelIDT, and so on.  I guessed wrong, because I get very different assembly output.

    Thanks and regards,

    -George

  • Thanks.

    I tried _nassert. The build can pass, but there is no optimization.

    I couldn't find any description about _nassert in MSP430 C/C++ Compiler User's Guide (SLAU132), so I guess it won't do such optimization.

  • Jianyi Bao said:
    I couldn't find any description about _nassert in MSP430 C/C++ Compiler User's Guide (SLAU132)

    The description of _nassert in the C28x compiler manual applies to the MSP430 compiler as well.

    Jianyi Bao said:
    I guess it won't do such optimization.

    Unfortunately, for your specific case, that is correct.

    Thanks and regards,

    -George

  • I did some experimention. The packed attribute seems to cause the compiler to assume that the structure members can be unaligned to atomic types. Removing the packed attribute results in 2 MOV.W for each 32-bit copy. From what I can see with your structure, you probably don't need the packed attribute.
  • I have to use packed, because the last member ChannelIdT is uint8

  • Usually the only reason you need packed is when your data is read directly from stream (eg. UART) directly into structure. And only if the structure has a different alignment than the processor. If you are using an packed array of packed RfMsgDGroupEdInfoWithSlotsT elements then all that byte access code is definitely required. Some elements will be odd aligned.

    If you are using sizeof() on a odd size structure, then packed would accurately return the size. Otherwise sizeof() would return the aligned padded size rather than the sum of declared member sizes. You could get away with a hard-coded hash define of the logical size and a unpacked structure though. Or just add a pad byte to your structure.
  • Actually the message is from radio, so it has to be as small as possible. In normal cases, packed should not be used, unless memory is extremely limited.

    In my case, I usually manually adjust the order of the structure, so that members of uint16 and uint32 are actually aligned to 2 bytes, so the compiler could have chance to optimize code. In my case, if I tell the compiler the structure is indeed aligned to 4 bytes, it has the ability to do optimization. Maybe TI compiler could do enhancement in this aspect.

  • Not sure I understand your last post. Is that what you are doing? Or what you intend to do? Or what you would do in an ideal situation? On the MSP430, I believe 2 byte alignment is the minimal. The 4 byte value is usually for true 32-bit processors.

    Assuming that ChannelIdT is uint8, I checked the offsetof() on members of RfMsgDGroupEdInfoWithSlotsT and there is no difference between packed and unpacked. The sizeof() is 27 for packed and 28 for unpacked. In theory, you read directly from the radio into an unpacked structure with a hard-coded size value of 27 rather than a sizeof() value of 28. It just means that the structure has a unseen and unused pad byte.