C 结构中的自动字段重新排序以避免填充 [英] Automated field re-ordering in C structs to avoid padding

查看:11
本文介绍了C 结构中的自动字段重新排序以避免填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我花了几分钟手动重新排序结构中的字段以减少填充效果[1],这感觉就像几分钟太多了.我的直觉告诉我,我的时间可能最好花在编写 Perl 脚本或诸如此类的东西上来为我做这种优化.

I've spent a few minutes manually re-ordering fields in a struct in order to reduce padding effects[1], which feels like a few minutes too much. My gut feeling says that my time could probably be better spent writing up a Perl script or whatnot to do this kind of optimization for me.

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

My question is whether this too is redundant; is there already some tool that I'm not aware of, or some compiler feature that I should be able to turn on[2] to pack structs?

这个问题更加复杂,因为这需要在几个不同的架构中持续优化,所以无论使用什么工具都需要能够考虑不同的结构对齐和指针大小.

The issue is even more complicated by the fact that this needs to be consistently optimized across a few different architectures, so whatever tool used needs to be able to account for different struct alignments and pointer sizes as well.

快速澄清——我想要做的是重新排序源代码中的字段以避免填充,而不是像编译时那样在没有填充的情况下打包"结构.

A quick clarification -- what I want to do is re-order the field in the source code in order to avoid padding, not "pack" the struct as is compiling without padding.

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

EDIT #2: Another complication: depending on the configuration, sizes of some data types may also change. The obvious ones are pointers and pointer-diffs for different architectures, but also floating-point types (16, 32 or 64-bit depending on the 'exactness'), checksums (8 or 16-bit depending on 'speed') and some other non-obvious stuff.

[1] 有问题的结构在嵌入式设备上实例化了数千次,因此结构每减少 4 字节可能意味着 gono-go 之间的区别 用于这个项目.

[1] The struct in question is instantiated thousands of times on an embedded device, so each 4-byte reduction of the struct could mean the difference between a go and no-go for this project.

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

[2] Available compilers are GCC 3.* and 4.* , Visual Studio, TCC, ARM ADS 1.2, RVCT 3.* and a few others more obscure.

推荐答案

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

If every single word you can squeeze out of the storage is critical, then I have to recommend optimizing the struct by hand. A tool could arrange the members optimally for you, but it doesn't know, for example, that this value here that you're storing in 16 bits actually never goes above 1024, so you could steal the upper 6 bits for this value over here...

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

So a human will almost certainly beat a robot on this job.

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

But it seems like you really don't want to hand-optimize your structs for each architecture. Maybe you really have a great many architectures to support?

我确实认为这个问题不适用于通用解决方案,但您可以将您的领域知识编码到自定义 Perl/Python/某个脚本中,为每个架构生成结构体定义.

I do think this problem isn't amenable to a general solution, but you might be able to encode your domain knowledge into a custom Perl/Python/something script that generates the struct definition for each architecture.

此外,如果您的所有成员的大小都是 2 的幂,那么您只需按大小对成员进行排序(最大的在前)即可获得最佳打包.在这种情况下,您可以使用良好的老式基于宏的结构-building - 像这样:

Also, if all your members have sizes that are powers of two, then you will get optimal packing simply by sorting members by size (largest first.) In that case, you can just use good old-fashioned macro-based struct-building - something like this:

#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
};

这篇关于C 结构中的自动字段重新排序以避免填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆