我知道为什么GCC默认不重新排序结构的成员,但我很少编写依赖于结构顺序的代码,所以有什么方法可以标记我的结构自动重新排序吗? / p>
答案 0 :(得分:10)
之前的GCC版本具有-fipa-struct-reorg
option,允许在-fwhole-program
+ -combine
模式下重新排序结构。
中的以下原因,它已从GCC 4.8.x中移除
-fipa-struct-reorg
执行结构重组优化,改变C类结构布局以更好地利用空间局部性。此转换对包含结构数组的程序有效。提供两种编译模式:基于配置文件(使用-fprofile-generate
启用)或静态(使用内置启发式)。要求-fipa-type-escape
提供此转换的安全性。它仅适用于整个程序模式,因此需要启用-fwhole-program
和-combine
。通过此转换考虑'cold'
的结构不受影响(请参阅--param struct-reorg-cold-struct-ratio=value
)。
已删除struct reorg和matrix reorg optimizations(命令行选项
-fipa-struct-reorg
和-fipa-matrix-reorg
)。它们并不总是正常工作,也不适用于链接时优化(LTO),因此仅适用于由单个翻译单元组成的程序。
但是,您仍然可以自行承担struct-reorg-branch
{{1}}的风险,因为它仍在积极开发中。
答案 1 :(得分:1)
GCC没有这样的选择。而且,我确定,它不能以任何合理的方式介绍。关于填充优化,请查看this discussion。
我知道的唯一例外是热/冷结构字段拆分,在某些情况下可以完成(我仍然不确定,GCC甚至可以在配置文件引导模式下执行此操作,我知道ICC可以)。此功能不受用户控制,并且在调用图上执行,其中可以证明此类转换对数据流的保守性。
答案 2 :(得分:0)
我认为在编译整个程序时可以重新组织/拆分struct的元素(lto模式,使用-flto标志)。在这种情况下,您可以获得程序的完整图片,对于不能转义的符号,应该可以重新排序它们以获得更好的缓存行为等。
在gcc主干中,这是在积极发展。这是在GNU cauldron 2015中提出的。您可能想尝试gcc trunk或struct-reorg-branch。
答案 3 :(得分:0)
作为附带说明,Linux内核实现了 gcc plugin,以引入名为 randomize_layout 的服装。目的是在结构的定义中使用它,以使编译器将字段的顺序随机化。 Linux内核将其用于the sake of security,以抵抗需要了解结构布局的攻击。例如, cred 结构在 include / linux / cred.h 中定义如下:
struct cred {
atomic_t usage;
#ifdef CONFIG_DEBUG_CREDENTIALS
atomic_t subscribers; /* number of processes subscribed */
void *put_addr;
[...]
struct user_struct *user; /* real user ID subscription */
struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
struct group_info *group_info; /* supplementary groups for euid/fsgid */
/* RCU deletion */
union {
int non_rcu; /* Can we skip RCU deletion? */
struct rcu_head rcu; /* RCU deletion hook */
};
} __randomize_layout;
__ randomize_layout 标签在Linux源代码树的 include / linux / compiler-gcc.h 中定义为:
#define __randomize_layout __attribute__((randomize_layout))