由于打包,我想计算/总结一个目标文件的开销(理想情况下,让gcc最小化它)。
例如,请考虑以下结构(32位x86,gcc):
struct a {
uint8_t a_char;
uint32_t an_integer
uint8_t another_letter;
};
虽然实际数据只占用6个字节,但结构在内存中占用12个字节,因为两个字符后跟3个填充字节。通过重新排序结构如下:
struct b {
uint32_t an_integer
uint8_t a_char;
uint8_t another_letter;
};
结构只有sizeof(struct b)== 8(仍然是4字节的开销)。
(1)理想情况下,我希望gcc重新安排struct a
到struct b
并为我节省空间,但我的版本(4.2)似乎没有针对任何优化级别执行此操作
(2)或者,给定struct a
,我想(自动)获得数字6
(总开销量)或4
(最小开销量,如果成员是“理想地”订购的)。这样做的目的是确定手动重新排序结构是否值得花时间(可能不是)。
gcc是否有办法(1),是否有一个可以执行(2)的工具?我能想到的最接近的事情(1)是#pragma pack(1)
,但是(我猜)通过使大部分/全部内存访问不对齐,它会产生严重的性能影响。对于(2),我认为解析调试符号的Perl脚本可能能够做到这一点,但我对DWARF不太熟悉,无法确切知道。
答案 0 :(得分:8)
对于#1,未完成的原因是C和C ++标准都禁止结构成员重新排序。
是的,结构打包通常会降低性能。并且,正如评论中所提到的,在非x86架构的某些情况下,如果您尝试对成员进行操作,则可以获得SIGBUS。
对于#2,是的perl脚本可能能够做到这一点。您可以尝试扫描结构定义的源代码,而不是解析DWARF信息,也可以生成一些小的测试程序来检查结构和成员的sizeof()等。
答案 1 :(得分:3)
在linux中有一个名为pahole的工具,它将解析一个ELF文件,其中包含每个结构的调试信息和打印输出,每个成员的对齐方式以及编译器完成的填充量。如果您发现开销太大,可以使用该信息指导您手动打包。
答案 2 :(得分:0)
这并不总是可以解决的问题是在所有体系结构上都不允许访问未对齐的内存。这也简化了编译器的一些代码,允许优化存储器本身的某些访问。重组结构也许不值得花时间,因为每个结构的4-8字节开销并不是什么大问题,除非你运行的是非常敏感的内存软件。至于你的问题,我不确定是否有办法,但我确定是否有人知道他们会让你知道(也许gcc-4.6有最高优化标志吗?)