常用的结构体布局方式

  1. 以从大到小的方式布局,这种布局好处是:
    a. 做到结构体padding浪费的空间是最小的
    b. 可以支持变长数组,即char[0]/char[1],这点若使用从小到大的布局则无法实现
struct foo {
		unsigned long long a;
		double b;
		unsigned long c; /* long比较坑,根据体系结构和平台长度不一致的 */
		int d;
		char e;
		char f[0];
};
  1. 以结构体成员的访问/修改的频繁程度进行布局,并且配合cacheline长度对齐进行声明,这种布局的好处是:
    a. 最大化了cpu的cache命中率,性能非常优越,避免false sharing带来的性能开销
    b. 举例:linux中mm模块的zone_struct采用了这种思想进行布局
    c. 注意点:要配合cacheline长度对齐声明,或者你的结构体大小本身就是cacheline的整数倍,否则如果有其他变量和你的结构体共享了相同的cacheline,那么很可能无法获得性能优势(比如该变量经常被修改,导致你的cacheline经常型的失效)
    d. 这种声明方式的基本思路:根据访问类型/频率/是否经常性的一起访问或修改,将成员变量归类放在同一条cacheline上.如: a/b是经常一起被修改的, c/d是极少被修改且极少被读取的, e/f是高频被读取极少被修改的.根据这种规律,将访问方式和时间局部性相近的成员变量放在一起.
    e. 错误的布局: 假设a/b是经常被修改的,但并不是经常一起被修改的,那么你将a/b放在一起就会导致false sharing.
    f. 这个思想只对c/c++中的POD类型有效,而非POD类型,比如c++ stl等,需要搞清楚这些类的结构体布局
// linux kernel mmzone.h
typedef struct zone_struct {
	/*
	 * Commonly accessed fields:
	 */
	spinlock_t		lock;
	unsigned long		offset;
	unsigned long		free_pages;
	unsigned long		inactive_clean_pages;
	unsigned long		inactive_dirty_pages;
	unsigned long		pages_min, pages_low, pages_high;

	/*
	 * free areas of different sizes
	 */
	struct list_head	inactive_clean_list;
	free_area_t		free_area[MAX_ORDER];

	/*
	 * rarely used fields:
	 */
	char			*name;
	unsigned long		size;
	/*
	 * Discontig memory support fields.
	 */
	struct pglist_data	*zone_pgdat;
	unsigned long		zone_start_paddr;
	unsigned long		zone_start_mapnr;
	struct page		*zone_mem_map;
} zone_t;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值