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.

[参考译文] 编译器/MSP430G2744:指定打包结构的内存对齐

Guru**** 2538950 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/591294/compiler-msp430g2744-specify-memory-alignment-of-a-packed-structure

部件号:MSP430G2744

工具/软件:TI C/C++编译器

6.1 ,MSP430编译器TI 4.3 ................................................................8.

以下是代码段:

typedef结构__attribute___(packed)
{
uint8 d0[4];
uint8 d1[2];
UINT32 D2[2];
uint16 SlotInfo_Start;
UINT32 EdBitmap[2];
UINT16 SlotInfo_slotNum;
ChannelIdT F0Channel;
}RfMsgDGroupEdInfoWithSlotsT; RfMsgDEdInfoWithSlotsT*

groupEdInfoMsgP2=(RfMsgDGroupEdInfoWithInfoSlotsT*)组EdInfoMsgP;

UINT32 Bitmap[Edmap] Bitmap[Edmap_Edmap]
=组<1 Edmap_Edmap_Edmap_Edmap_P2=

编译器将生成复杂代码以复制EdBitmap[0]和EdBitmap[1],如下所示。 但实际上groupEdInfoMsgP2指向一个在我的代码中对齐了4字节的地址。 我能不能  
向编译器指定groupEdInfoMsgP2是4字节对齐的(因此结构中的成员EdBitmap[2]也是4字节对齐的),以便复制到EdBitmap[2]的速度可以快得多?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我有一个建议供您考虑。  但是,我不能保证它会带来您想要的性能提升。

    Jianyi Bao 说:
    我是否可以 向编译器指定groupEdInfoMsgP2是4字节对齐的[/QUOT]

    是的。  以下是如何...

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

    该行是通知编译器指针已与4字节边界对齐的方式。  您有责任确保这一点始终正确。  编译器可能会生成依赖于此对齐的代码。  如果未对齐,生成的代码可能会以静默方式访问错误的地址。  这是很难调试的。

    [QUETE USER="Jianyi Bao "]这样,复制到EdBitmap[2]的速度会快得多?[/QUET]

    我无法保证,当您使用此_nassert时,您将获得性能改进。  我会自己尝试,但我不能。  我需要一个完整的测试用例,它可以构建到您展示的相同装配体中。  当我尝试执行此操作时,我必须猜测构建选项,ChannelIDT的类型等内容。  我猜错了,因为我得到了非常不同的装配体输出。

    谢谢,此致,

    -George

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢。

    我尝试了_nassert。 版本可以通过,但没有优化。

    我在MSP430 C/C++编译器用户指南(SLAU132)中找不到任何有关_nassert的描述,因此我想它不会进行这样的优化。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Jianyi Bao 说:
    在MSP430 C/C++编译器用户指南(SLAU132)

    中找不到任何有关_nassert的描述

    C28x编译器手册中的_nassert说明 也适用于MSP430编译器。

    Jianyi Bao 说:
    我想它不会进行这样的优化。[/QUOT]

    很遗憾,对于您的具体情况,答案是正确的。

    谢谢,此致,

    -George

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我做了一些实验。 packed属性似乎导致编译器假定结构成员可以与原子类型不对齐。 删除压缩的属性会导致每个32位副本产生2 MOV.W。 从我可以看到的您的结构中,您可能不需要"打包"属性。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我必须使用packed,因为最后一个成员ChannelIdT是uint8

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    通常,您需要打包的唯一原因是您的数据直接从流中读取(例如, UART)直接进入结构。 并且仅当结构与处理器具有不同的对齐时。 如果您使用的是打包的RfMsgDGroupEdInfoWithSlotsT元素的压缩数组,则肯定需要所有该字节访问代码。 某些元素将奇数对齐。

    如果在奇数大小结构上使用sizeof(),则packed将准确返回大小。 否则,sizeof()将返回对齐的填充大小,而不是声明成员大小的总和。 您可以使用逻辑大小的硬编码散列定义和未打包的结构。 或者只需在结构中添加一个PAD字节。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    实际上,信息来自对讲机,因此必须尽可能小。 在正常情况下,除非内存极其有限,否则不应使用packed。

    在我的情况下,我通常手动调整结构的顺序,以便uint16和UINT32的成员实际上对齐到2个字节,这样编译器就有机会优化代码。 在我的情况下,如果我告诉编译器结构确实与4字节对齐,它就能够进行优化。 也许TI编译器可以在这方面进行增强。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    不确定我是否理解您的上一篇帖子。 您正在做什么吗? 或者您打算做什么? 或者,在理想情况下您会怎么做? 在MSP430上,我认为2字节对齐是最小的。 4字节值通常用于真正的32位处理器。

    假设ChannelIdT是uint8,我在RfMsgDGroupEdInfoWithSlotsT的成员上检查了offsetof(),打包和解包之间没有区别。 sizeof()对于packed为27,对于unpacked为28。 理论上,您直接从对讲机读取到一个解包结构,其硬编码大小值为27,而不是sizeof()值为28。 它只是意味着结构有一个看不见和未使用的PAD字节。