C 在结构中排列字段的哪种方式更好?
我有两种方法在结构中排列字段C 在结构中排列字段的哪种方式更好?,c,performance,structure,C,Performance,Structure,我有两种方法在结构中排列字段 struct foo { float a; double b; float c; double d; short e; long f; short g; long h; char i; int j; char k; int l; }; struct foo { double
struct foo {
float a;
double b;
float c;
double d;
short e;
long f;
short g;
long h;
char i;
int j;
char k;
int l;
};
struct foo {
double b;
double d;
long f;
long h;
float a;
float c;
int j;
int l;
short e;
short g;
char i;
char k;
};
哪一个应该练习,为什么 排列结构构件的最佳方法是根据构件的大小按递增顺序排列,需要 此外,还可以使用一些工具修改路线,例如:
#define packed_data __attribute__((__packed__))
关掉它。使用这种方法,成员顺序不再重要,但我强烈反对这种做法,因为内存对齐已针对性能进行了优化。一种合理的字段排序方法是根据其用途的相似性。 例如:
struct window {
MENU *menu ;
int width ;
char *name ;
WINDOW *child ;
int xpos ;
int height ;
void *info ;
WINDOW *next ;
CLASS *class ;
int ypos ;
WINDOW *parent ;
}
这样看起来会更好
struct window {
CLASS *class ;
void *info ;
char *name ;
int xpos ;
int ypos ;
int width ;
int height ;
WINDOW *parent ;
WINDOW *next ;
WINDOW *child ;
MENU *menu ;
}
第二种安排更可取 在结构中,最大限度地减少因填充而造成的位存储损失 (内存中各种变量的边界对齐),最好开始 具有最大大小变量的结构。从高到低
填充是一种排列方式优于另一种排列方式的原因之一。另一种选择是按字段的频率或内存访问模式对字段进行排序。这当然是一种微观优化,但在极端情况下也会有回报 许多或大多数CPU体系结构使用较小的操作码在指针中编码较小的偏移量;在RISC体系结构中,将最常访问的元素偏移为零可以减少指令数量,并使代码运行更快
如果“x”与“y”同时使用,那么将它们放在同一缓存线中是有益的,而不是每个结构面临两次或两次以上缓存未命中的风险。这听起来像是家庭作业。我要加上一个词:填充。我想,你可以找出剩下的。A4L,这不是一个严格意义上的风格/观点问题,因为由于填充,顺序实际上会影响结构所需的总内存和执行速度。但这在很大程度上取决于编译器和使用的标志,在大多数情况下影响不大。@A4L谢谢,以后会记得的!只需对每个变量执行
printf(“%d\n”,sizeof(struct foo))
,您就会知道哪一个更好,并且确切地知道为什么…@a4l,我很确定在您选择的语言(似乎是Java)中,同样的问题也适用。只是在大多数语言(包括Java)中,您对程序的看法是如此之高,对性能的关注是如此之少,以至于您从未听到过关于这些事情的讨论。尽管如此,从处理器的角度来看,填充对缓存的影响和对齐对内存访问的影响与编程语言完全无关。如果按大小排序,则增加或减少大小并不重要。增加大小的排序将把填充分配到不同的部分末端,减小大小的排序将生成一个固体数据块,所有填充应用在末端。填充量相同,只是分布不同。@JonasWielicki我明白了,你是对的。排序是什么逃过我,我会很高兴地放弃评论。非常感谢你指出这一点。非常感谢。@cmaster Jonas刚刚指出了这一点,我很抱歉没有看到这一点(这里仍然是早上6:30,咖啡充其量也很少)。我很乐意放弃不准确的评论。谢谢你们两位的精神检查。和+1的评论,顺便说一句。我本来打算提出一个反例,但最终以!至少就我所知的RISC体系结构而言,它们实际上比CISC体系结构更不关心偏移量大小或偏移量为零之类的事情。原因是RISC体系结构具有固定的命令大小(通常为32位),其中可以打包相当多的信息。不使用这些比特只会浪费宝贵的空间。例如,在Power平台上,有五个(!)参数范围在0到32之间的命令。同样,您也没有任何简化版本的命令,如加载和存储。所有的内存访问都允许一个偏移量,这很简单。如果RISC意味着固定的指令长度,那么根据定义。例如,Cortus APS3具有16/32位指令,但由于操作系统加载/存储体系结构和固定的指令吞吐量,它在很大程度上是RISC。同样忽略ARM实际上属于哪个类别的问题,它具有相似的属性。