是否有GCC关键字允许结构重新排序?

时间:2013-02-03 09:52:15

标签: c gcc padding c99 memory-alignment

我知道为什么GCC默认不重新排序结构的成员,但我很少编写依赖于结构顺序的代码,所以有什么方法可以标记我的结构自动重新排序吗? / p>

4 个答案:

答案 0 :(得分:10)

之前的GCC版本具有-fipa-struct-reorg option,允许在-fwhole-program + -combine模式下重新排序结构。

  
      
  • -fipa-struct-reorg
      执行结构重组优化,改变C类结构布局以更好地利用空间局部性。此转换对包含结构数组的程序有效。提供两种编译模式:基于配置文件(使用-fprofile-generate启用)或静态(使用内置启发式)。要求-fipa-type-escape提供此转换的安全性。它仅适用于整个程序模式,因此需要启用-fwhole-program-combine。通过此转换考虑'cold'的结构不受影响(请参阅--param struct-reorg-cold-struct-ratio=value)。
  •   

由于release note

中的以下原因,它已从GCC 4.8.x中移除
  

已删除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。

https://gcc.gnu.org/wiki/cauldron2015?action=AttachFile&do=view&target=Olga+Golovanevsky_+Memory+Layout+Optimizations+of+Structures+and+Objects.pdf

答案 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))