前面我们讨论了内存的工作原理,也进行了一些性能相关的测试。那么今天开始我们来看几个在实践中的应用。首先我们先从php开始。2015年,php7的发布可以说是在技术圈里引起了不小的轰动,因为它的执行效率比php5直接翻了一倍。php7在内存方面,你是否知道作者都进行了哪些优化?几个核心结构体的改进只是表面上看起来优化的几个字节那么简单?让我们从几个核心的数据结构改进开始看起。
1 php7 zval的变化
1、php5.3中的zval:
我们这里只讨论64位操作系统下的情况。该zval_struct结构体中的由四个成员构成,其中zvalue_value稍微复杂一些,是一个联合体。联合体中最长的成员是一个指针加一个int,8+4=12字节。但是默认情况下,会进行内存对齐,故zval_struct会占用16字节。 那么。
_zval_struct总的字节 = value(16)+ refcount__gc(4)+ type(1)+ is_ref__gc(1)= 占用22字节。
最后再考虑下内存对齐,实际占用24字节。(如果算的有点晕话,感兴趣的同学可以写段简单的测试代码,使用sizeof查看一下)
2、php7.2中的zval
7.2中的zval_struct结构体里由3个成员构成,其中zend_value看起来比较复杂,实际上只是一个8字节的联合体。 u1也是一个联合体,占用是4个字节。u2也一样。这样zval_struct就实际占用16个字节。
2 php7 hashtable的变化
1、php5.3里的hashtable:
在5.3里hashtable就是一个大struct, 有点小复杂,我们拆开了细说,
uint ntablesize 4字节
uint ntablemask 4字节
uint nnumofelements 4字节,
ulong nnextfreeelement 8字节 注意这前面的4个字节会被浪费掉,因为nnextfreeelement的开始地址需要对齐
bucket *pinternalpointer 8字节
bucket *plisthead 8字节
bucket *plisttail 8字节
bucket **arbuckets 8字节
dtor_func_t pdestructor 8字节
zend_bool persistent 1字节
unsigned char napplycoun 1字节
zend_bool bapplyprotection 1字节
最终,总字节数 = 4+4+4+4(nnextfreeelement前面这四个字节会留空)+8+8+8+8+8+8+1+1+1 = 67字节。再加上结构体本身要对齐到8的整数倍,所以实际占用72字节。
2、php7.2里的hashtable:
在7.2里hashtable
zend_refcounted_h gc 看起来唬人,实际就是个long,占用8字节
union... u 占用4字节
uint32_t 占用4字节
bucket* 指针占用8字节
uint32_t nnumused 占用4字节
uint32_t nnumofelements 占用4字节
uint32_t ntablesize 占用4字节
uint32_t ninternalpointer 占用4字节
zend_long nnextfreeelement 占用8字节
dtor_func_t pdestructor 占用8字节
总占用
字节数 = 8+4+4+8+4+4+4+4+8+8 = 56字节,并且正好达到了内存对齐的状态,没有额外的浪费。
另外还有php源代码里经常出镜的buckets也从72下降到了32字节,这里我就不翻源代码了。
3 优化思想精髓
当当当,敲黑板,重点来了!我们看了两个核心数据结构的结构体变化,这上面的优化都是什么含义呢? 拿hashtable举例,貌似从72字节优化到了56字节,这内存节约的也不是特别多嘛,才20%多而已!但这中间其实隐藏了两个较深层次优化思路:
第一、你是否记得我们前面cpu在向内存要数据的时候是以cache line为单位进行的,而我们说过cache line的大小就是64字节。回过头来看hashtable,在7.2里的56字节,只需要cpu向内存进行一次cache line大小的burst io,就够了。而在5.3里的72字节,虽然只比cache line大了那么一丢丢,但是对不起,必须得进行两次burst io才可以。 所以,在计算机里,56字节相对72字节实际上是翻倍的性能提升!!
第二、cpu的l1、l2、l3的容量是固定的几十k或者几十m。假设cache的都是hashtable,那么cache容量不变的条件下,能cache住的hashtable将会翻倍,缓存命中率提升一大截。要知道l1命中后只需要1ns多一点的耗时,而如果穿透到内存的话可能就需要40多纳秒的延时了,整整差了几十倍。
所以php内核的作者大牛深谙cpu与内存的工作原理,表面上看起来只是几个字节的节约,但是实际上爆发出了巨大的性能提升!!
手触式定时供水控制阀电路
特斯拉Model 2渲染图疑似曝光
洲明新项目或创LED显示行业新记录
高通5G调制解调器应用场景广阔 不止于骁龙5G手机
国产伺服电机借工业机器人市场崛起
PHP7在内存方面你是否知道都进行了哪些优化
人工智能是新基建中最重要的投资发展领域之一
单片机系统硬件的抗干扰措施解析
君林科技:用声纹识别来解放你的双手
如何选择变压器的类型,从哪些方面去看
荣耀V40上市卖爆,极致产品力透露背后实力
碳化硅器件在UPS中的应用研究
博世汽车产业转型,裁1500人
干货 红宝石电解电容寿命权威计算
安立公司荣膺Frost & Sullivan“年度最佳全球测试与测量公司”大奖
旭创科技全新推出的相干光通信模块
发夹型微带滤波器的设计方法
什么是精密电阻?工作原理是什么?贴片电阻该如何测量?
中国电信利用智算能力构建2+4+31+X+O的云计算力布局体系
转型升级在即,看泛瑞如何发力风光储