当前位置:  开发笔记 > 编程语言 > 正文

C结构中的自动字段重新排序以避免填充

如何解决《C结构中的自动字段重新排序以避免填充》经验,为你挑选了2个好方法。

我花了几分钟手动重新排序结构中的字段,以减少填充效果[1],这感觉就像几分钟太多.我的直觉是说我的时间可能更好地花在编写Perl脚本上,或者为我做这种优化.

我的问题是这是否也是多余的; 是否已经有一些我不知道的工具,或者我应该能够启用[2]打包结构的一些编译器功能?

由于需要在几种不同的体系结构中进行一致优化,因此使用的任何工具都需要能够考虑不同的结构对齐和指针大小,这个问题更加复杂.

编辑:快速澄清 - 我想要做的是重新排序源代码中的字段,以避免填充,而不是"编译"结构,而不是填充编译.

编辑#2:另一个复杂因素:根据配置,某些数据类型的大小也可能会发生变化.显而易见的是针对不同体系结构的指针和指针差异,但也有浮点类型(16,32或64位,取决于'精确性'),校验和(8位或16位取决于"速度")和一些其他不明显的东西.

[1]所讨论的结构在嵌入式设备上被实例化了数千次,因此结构的每个4字节减少可能意味着该项目的gono-go之间的差异.

[2]可用的编译器是GCC 3.*和4.*,Visual Studio,TCC,ARM ADS 1.2,RVCT 3.*以及其他一些更加模糊的编译器.



1> Charlie..:

如果您可以挤出存储的每个单词都很重要,那么我必须建议手动优化结构.一个工具可以为你最佳地安排成员,但是它不知道,例如,你在这里以16位存储的这个值实际上永远不会超过1024,所以你可以窃取这个值的高6位这里 ......

因此,人类几乎肯定会在这份工作中击败机器人.

[编辑]但似乎你真的不想为每个架构手动优化你的结构.也许你真的有很多架构需要支持?

我认为这个问题不适用于一般解决方案,但您可能能够将您的领域知识编码为自定义Perl/Python/something脚本,为每个体系结构生成结构定义.

此外,如果所有成员的大小都是2的幂,那么只需按大小排序成员(最大的第一个),您就可以得到最佳的包装.在这种情况下,您可以使用良好的老式基于宏的结构构建 - 这样的事情:

#define MYSTRUCT_POINTERS      \
    Something*  m_pSomeThing;  \
    OtherThing* m_pOtherThing; 

#define MYSTRUCT_FLOATS        \
    FLOAT m_aFloat;            \
    FLOAT m_bFloat;

#if 64_BIT_POINTERS && 64_BIT_FLOATS
    #define MYSTRUCT_64_BIT_MEMBERS MYSTRUCT_POINTERS MYSTRUCT_FLOATS
#else if 64_BIT_POINTERS
    #define MYSTRUCT_64_BIT_MEMBERS MYSTRUCT_POINTERS
#else if 64_BIT_FLOATS
    #define MYSTRUCT_64_BIT_MEMBERS MYSTRUCT_FLOATS
#else
    #define MYSTRUCT_64_BIT_MEMBERS
#endif

// blah blah blah

struct MyStruct
{
    MYSTRUCT_64_BIT_MEMBERS
    MYSTRUCT_32_BIT_MEMBERS
    MYSTRUCT_16_BIT_MEMBERS
    MYSTRUCT_8_BIT_MEMBERS
};


从最大到最小的排序通常不是最佳的.一般情况是垃圾箱包装问题,这是NP难的 - 有一些有趣的结果,如果你好奇,你可以谷歌.仅在特殊情况下,尺寸为2的幂才能完美包装,不留间隙; 通过观察这种情况很容易看出原因.每个大小为2 ^ k的对象在2 ^ k对齐的边界上结束,该边界也是2 ^ k-1对齐的边界,因此"降低"到较小的大小永远不会导致间隙.

2> sigjuice..:

有一个名为pstruct的Perl脚本通常包含在Perl安装中.该脚本将转储结构成员偏移量和大小.您可以修改pstruct或使用其输出作为制作实用程序的起点,该实用程序按您希望的方式打包您的结构.

$ cat foo.h 
struct foo {
    int x;
    char y; 
    int b[5];
    char c;
};

$ pstruct foo.h
struct foo {
  int                foo.x                      0       4
  char               foo.y                      4       1
                     foo.b                      8      20
  char               foo.c                     28       1
}

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有