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

问题描述 投票:0回答:4

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

c gcc padding c99 memory-alignment
4个回答
21
投票

以前的 GCC 版本具有

-fipa-struct-reorg
选项,允许在
-fwhole-program
+
-combine
模式下进行结构重新排序。

  • -fipa-struct-reorg

    进行结构重组优化,改变C类结构布局,以更好地利用空间局部性。这种转换对于包含结构数组的程序是有效的。有两种编译模式可用:基于配置文件(使用

    -fprofile-generate
    启用)或静态(使用内置启发式方法)。要求
    -fipa-type-escape
    提供此转换的安全性。它仅在整个程序模式下工作,因此需要启用
    -fwhole-program
    -combine
    。此转换所考虑的结构
    'cold'
    不受影响(参见
    --param struct-reorg-cold-struct-ratio=value
    )。

由于发行说明中的以下原因,它自 GCC 4.8.x 起已被删除

结构重组和矩阵重组优化(命令行选项

-fipa-struct-reorg
-fipa-matrix-reorg
)已被删除。它们并不总是正确工作,也不支持链接时优化 (LTO),因此仅适用于由单个翻译单元组成的程序。

但是,您仍然可以在

GCC SVN
github 镜像 上尝试 struct-reorg-branch,但风险自负,因为它仍在积极开发中。

您还可以使用 clang-tools-extra 中的 clang-reorder-fields

工具对字段重新排序

另请参阅


5
投票

顺便说一句,Linux 内核实现了一个 gcc plugin 来引入名为

randomize_layout
的属性。目标是在结构的定义中使用它,以使编译器随机化字段的顺序。 Linux 内核使用它是为了为了安全来对抗需要知道结构布局的攻击。例如,
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))

2
投票

GCC 中没有这样的选项。而且,我确信,它不能以任何明智的方式引入。关于填充优化请查看此讨论

我知道的唯一例外是热/冷结构字段分割,在某些情况下可以完成(我仍然不确定,GCC 即使在配置文件引导模式下也可以做到,我知道 ICC 可以)。此功能不受用户控制,并且在调用图上执行,其中可以证明这种数据流转换的保守性。


1
投票

我认为在编译整个程序时可以重新组织/拆分结构体的元素(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

© www.soinside.com 2019 - 2024. All rights reserved.