软件技术也在不断的更新换代,至少到目前为止,还没有看到软件技术有停滞的迹象,硬件在不断的升级,软件跟随硬件而变,也在大幅度进步,很多十年前的课本上的软件技术都落后于时代了,要继续学习。以我比较擅长的c++为例子,最近十年c++11/14/17/21的变化也都比较大。
最近2年在优化内存分配库,历史上已经有太多大神曾经写过这个库了,但是我们用最新软件技术重写后,依旧比十年前的库快了一两个数量级。发现基本上就是每个子方向只要用最新的软件技术方案重写一遍,性能都会大幅度提升,都是N倍提升,最近十年的软件技术进步非常大。这个内存分配库软件使用了全新的高性能软件技术体系,性能才做到那么高,并不是单一某个算法的优秀。目前申请4KB只需要6ns, 申请8字节只需要4.8ns,比十年前的库快太多了,我的专栏文章评论区有so下载链接和测试源码下载。
下面举一个子方向的例子。如果某人也想开发一套高性能的内存分配库,那么首先就会遇到需要写一个内部自用的 thread_local 算法的问题,避免循环依赖,另外大约 boost 库等自带的 thread local 算法自身的消耗就数ns了,这个开销比我们的 malloc / free的全部开销还要大,必须重写。重写一个高效的 thread local 算法,会遇到 std:: unordered map 的低效率问题,(KEY是整数的场景下)大约会比现代c++高效的 hash map 算法慢6倍左右,那么就需要找一个或者按照论文中的最新的算法重新实现一个,典型的算法就是开放地址法+线性探测+sse4.2 crc32c hash算法+长度2倍次扩容,相关的论文非常多。如果有了一个比较快的现代C++的高效 hash map 了,多线程下就会面临不能用锁,因为一旦用了锁, 那么性能就完全不能看了。现在问题就会变成如何实现一个无锁的 hash map, 找到一个 lock free 的 hash map, 测试一下就知道了, atomic 的存取就远远超过数ns,lock free 算法也太慢了不能用。现在的问题就会变成如何实现一个没有使用atomic的无锁的 hash map,就会找到 RCU 的方式,RCU有一堆的论文 hazard point 等一堆复杂算法。如果有耐心实现一个基于RCU理论基础的高性能的无锁的 hash map,很快就会发现,做一个传统的操作系统系统调用获取 thread id 就是上百纳秒,要用新的技术,这块新技术方法的例子就是C++11的 thread id 的方案,获取 size t thread_id 仅需要一个时钟周期。进入函数后第一个if else判断(是否是单线程的 if else 的判断)需要消耗掉 1ns,最新CPU硬件体系的乱序执行体系可以在单线程下彻底去掉这个判断的1ns开销,换一个写法就好。C++ object 对象内部访问提速,可以实现去掉 address + offset 的那一步计算直达目标,又去掉1ns的开销。使用非标的unordered map的find接口不使用iterator, 有新的技术方案,又提升1ns。给gcc的一些显性优化提示再提升1ns。。。。。。经过一段时间的整合优化,就实现一个高效的 thread local 方法,比传统方案快数倍,get thread local ptr 只需要大约0----2ns的开销,平均只有1ns,踏入了高性能内存分配库的大门口了。The battle has just began。
以上只是简单介绍了简单的 thread local 算法的一些优化思路,足以让大家初窥 高性能的内存分配库是如何设计/写/优化出来的,一些优化是现代C++基础软件体系的一部分,一些程序员并没有掌握这些新技术,还在使用十年前的老软件技术,因此,他们的代码就会慢N倍,如果掌握这些新技术的高手都不开源,那么就可以建立足够的技术壁垒。
到目前为止,自研内存分配库中有N项高性能软件技术国内外所有厂家都没有开源,例如 完全线程安全的高性能的shared ptr,16线程内并发线程越多性能越高的数ns级别的多生产者/多消费者高并发无等待队列 wait free queue,1----2ns find 开销的RCU技术方案的高并发 hash map 和 thread local 算法,比intel CPU硬件移位快3倍的1<<N软件移位算法,比最新intel CPU硬件整数除法快1倍比intel 九代以前的旧CPU硬件整数除法快一个数量级(N倍对齐没有余数场景下)的软件整数除法新算法,高性能的 bitmap 算法,高性能 bit cookie 算法,平均每次申请/释放只有2ns开销的高性能 pool 算法等。C++在内存安全和性能方向有很大的潜力可挖。
有很多其它厂家也已经开源的高性能组件库,我们也有独立的实现,以下性能均指比 gcc5 c++ std 库的实现,例如 push back pod 数据快数倍的 vector,占用空间小一倍性能平均快一倍最大数倍的map, 一些场景下 find 性能快一倍到10倍的 string,内部没有使用atomic的部分场景下有数量级提升的单线程或者某线程内部使用的智能指针 local ptr(单线程下代替shared ptr),快N倍的整数 to string的实现,常规小容量场景下快一倍的 deque 等。这些组件都是使用了最近十年的最新软件技术重写实现的,很多场景下都是性能大幅度提升。
以上。 |