在Agner Fog's Optimizing Software in C++ book中,他有以下建议(第94页)
联合体如何防止寄存器变量被使用?在编译器资源管理器(o3)中运行一些玩具示例没有发现这样的限制。
o3
ff29svar1#
这将是ABI特定的答案,但如果您有union与int...并传递给函数,则必须将union压入堆栈,其中int可以在寄存器中传递,指针、浮点类型等也是如此. a.但这适用于structs/class instances,所以对我来说,这似乎不是一个很大问题...... unions是嵌入式编程之外的代码,因为如果您使用它们来进行解析之类的操作,那么解析器(例如,将char[]覆盖到struct)只有在它工作的情况下才能保证工作,结构体打包取决于编译器,即使有提示,它也可以做它想做的事情,同样明显的是,字节存储顺序的改变将破坏每个多字节成员。在这个例子中,如果你使用枚举作为一个函数参数,它将不得不进入堆栈,但一个指向任何成员的指针可以在寄存器中传递,但...一个指向枚举的指针无论如何都可以进入寄存器...它们只是不像数组那样衰减到指针。
union
int
structs
class instances
unions
char[]
struct
xyhw6mcr2#
实际的答案是:这并不重要。只有当节省的内存很大时,联合体才是值得的(问题中的例子只节省了几kB,这可能只在嵌入式系统上才有意义)。但是寄存器注解只对足够小的联合体有意义,因为它们的成员适合寄存器。即使对于嵌入式系统,这也是几个数量级的差异。底线:避免联合,直到分析显示出直接的内存压力问题,然后看看是否可以用派生类来解决if,或者std::variant。union是一个C解决方案。
std::variant
2条答案
按热度按时间ff29svar1#
这将是ABI特定的答案,但如果您有
union
与int
...并传递给函数,则必须将union
压入堆栈,其中int
可以在寄存器中传递,指针、浮点类型等也是如此. a.但这适用于structs
/class instances
,所以对我来说,这似乎不是一个很大问题......unions
是嵌入式编程之外的代码,因为如果您使用它们来进行解析之类的操作,那么解析器(例如,将char[]
覆盖到struct
)只有在它工作的情况下才能保证工作,结构体打包取决于编译器,即使有提示,它也可以做它想做的事情,同样明显的是,字节存储顺序的改变将破坏每个多字节成员。在这个例子中,如果你使用枚举作为一个函数参数,它将不得不进入堆栈,但一个指向任何成员的指针可以在寄存器中传递,但...一个指向枚举的指针无论如何都可以进入寄存器...它们只是不像数组那样衰减到指针。
xyhw6mcr2#
实际的答案是:这并不重要。只有当节省的内存很大时,联合体才是值得的(问题中的例子只节省了几kB,这可能只在嵌入式系统上才有意义)。但是寄存器注解只对足够小的联合体有意义,因为它们的成员适合寄存器。即使对于嵌入式系统,这也是几个数量级的差异。
底线:避免联合,直到分析显示出直接的内存压力问题,然后看看是否可以用派生类来解决if,或者
std::variant
。union
是一个C解决方案。