struct { /* Fileheader */
uchar file_version[4];
uchar options[2];
uchar header_length[2];
uchar state_info_length[2];
uchar base_info_length[2];
uchar base_pos[2];
uchar key_parts[2]; /* Key parts */
uchar unique_key_parts[2]; /* Key parts + unique parts */
uchar keys; /* number of keys in file */
uchar uniques; /* number of UNIQUE definitions */
uchar language; /* Language for indexes */
uchar max_block_size_index; /* max keyblock size */
uchar fulltext_keys;
uchar not_used; /* To align to 8 */
} header;以上内容是从MySQL源码中提取出来的。
为什么要纠结于8?
发布于 2011-10-24 10:54:56
这是一种优化,允许CPU更有效地访问内存中的结构。
http://en.wikipedia.org/wiki/Data_structure_alignment
发布于 2011-10-24 11:17:21
原因1:地址计算更快、更小。
在x86和其他一些架构上,如果元素大小是一个“漂亮的四舍五入数”,那么访问数组的元素会更有效率。对于“好的,四舍五入的数字”的定义,学习x86汇编。但是对于以下代码,您可以看到在程序集中访问具有不同大小元素的数组的效果:
struct s { char c[N]; };
int func(struct s *p, int i) { return p[i].c[0]; }当N为23时(上述结构无填充的大小):
leaq (%rsi,%rsi,2), %rax
salq $3, %rax
subq %rsi, %rax
movsbl (%rax,%rdi),%eax当N为24时(上述结构的大小带填充):
leaq (%rsi,%rsi,2), %rax
movsbl (%rdi,%rax,8),%eax当N为32时(具有附加填充的上述结构的大小):
salq $5, %rsi
movsbl (%rsi,%rdi),%eax请注意,访问包含23字节元素的数组中的元素的代码有多复杂。
原因2:对于磁盘上的结构,它允许通过对齐的加载和存储来访问文件中的其他元素。
看起来结构出现在磁盘上。使用填充,32位字可以紧跟在结构之后出现并对齐。这使得访问速度更快--对于内存中的结构,编译器会自动执行此操作,但对于磁盘上的结构,则需要手动执行此操作。如果您尝试访问未对齐的数据,某些架构甚至会崩溃。
unsigned char *data = ...;
header *h = (header *) data;
do_something_with(h);
uint32_t x = *(uint32_t *) (data + sizeof(header));如果sizeof(header)不是4的倍数,上面的代码将导致SPARC崩溃,并且在x86上,除非sizeof(header)不是4的倍数,否则速度会更慢。
发布于 2011-10-24 11:11:59
如果头结构在数组中,则数组的所有元素都将以相同的方式对齐。否则,情况就不会是这样。您可以查看下面的代码/输出来验证这一点。
如果Dani在他们的评论中是正确的,用户打算将像file_version这样的东西转换为uint32_t,那么这种对齐将非常重要。
一些代码
#include <stdio.h>
struct padded {
unsigned char file_version[4];
unsigned char options[2];
unsigned char header_length[2];
unsigned char state_info_length[2];
unsigned char base_info_length[2];
unsigned char base_pos[2];
unsigned char key_parts[2];
unsigned char unique_key_parts[2];
unsigned char keys;
unsigned char uniques;
unsigned char language;
unsigned char max_block_size_index;
unsigned char fulltext_keys;
unsigned char not_used;
};
struct unpadded {
unsigned char file_version[4];
unsigned char options[2];
unsigned char header_length[2];
unsigned char state_info_length[2];
unsigned char base_info_length[2];
unsigned char base_pos[2];
unsigned char key_parts[2];
unsigned char unique_key_parts[2];
unsigned char keys;
unsigned char uniques;
unsigned char language;
unsigned char max_block_size_index;
unsigned char fulltext_keys;
};
int main() {
printf("size padded: %lu\n", sizeof(struct padded));
printf("size unpadded: %lu\n", sizeof(struct unpadded));
printf("size padded[2]: %lu\n", sizeof(struct padded[2]));
printf("size unpadded[2]: %lu\n", sizeof(struct unpadded[2]));
}输出
size padded: 24
size unpadded: 23
size padded[2]: 48
size unpadded[2]: 46https://stackoverflow.com/questions/7870903
复制相似问题