其他总有很多人想把某个细分领域做到极致:
- fasthttp
- fastpb
- sonic - json解析
其他高级主题汇编/SIMD一些涉及大量计算的热点,可以采用汇编来优化 。
golang使用plan 9汇编的语法,门槛还是比较高的 。(经过半年断断续续的学习,我已经知道怎么看注释了)
所幸的是,懂C的人可以通过工具一步步把C代码翻译成plan 9汇编 。
我自己做了个尝试:《玩一玩golang汇编》(师从于这篇:《Go的2个黑魔法技巧》)
注意:https://github.com/Maratyszcza/PeachPy这个库的代码翻译能力有限,我就发现有的代码无法翻译的情况 。且,只支持amd64平台下的翻译 。如果大家遇到更好的汇编翻译工具,请推荐给我 。使用汇编的最佳理由是SIMD指令集 。
通常,一条指令只处理一条数据 。而simd中,一条指令可以处理多条数据,当数据由多个128bit或者256bit构成的时候,使用SIMD指令可以取得较好的收益 。
以strcmp()函数为例,传统的写法是逐个字符比较;而使用SIMD的话,可以把连续的16字节或者32字节(AVX2) load 到寄存器中,然后一次性比较 。
这块知识体系较为庞大,有兴趣请自行搜索 。
JIT技术当前流行的OLAP数据库clickhouse为何性能如此卓绝?其两个核心技术点就是SIMD和JIT 。
在计算机技术中,即时编译(英语:just-in-time compilation,缩写为JIT;又译及时编译[1]、实时编译[2]),也称为动态翻译或运行时编译[3],是一种执行计算机代码的方法,这种方法涉及在程序执行过程中(在执行期)而不是在执行之前进行编译 。[4]通常,这包括源代码或更常见的字节码到机器码的转换,然后直接执行 。实现JIT编译器的系统通常会不断地分析正在执行的代码,并确定代码的某些部分,在这些部分中,编译或重新编译所获得的加速将超过编译该代码的开销 。JIT在JAVA圈耳熟能详,通常指把字节码编译为机器码 。但是golang没有机器码,所以golang中JIT并不用于字节码翻译 。
JIT编译是两种传统的机器代码翻译方法——提前编译(英语:ahead-of-time compilation)(AOT)和解释——的结合,它结合了两者的优点和缺点 。[4]大致来说,JIT编译,以解释器的开销以及编译和链接(解释之外)的开销,结合了编译代码的速度与解释的灵活性 。JIT编译是动态编译的一种形式,允许自适应优化(英语:adaptive optimization),比如动态重编译和特定于微架构的加速[nb 1][5]——因此,在理论上,JIT编译比静态编译能够产生更快的执行速度 。解释和JIT编译特别适合于动态编程语言,因为运行时系统可以处理后期绑定(英语:Late binding)的数据类型并实施安全保证 。
——维基百科-即时编译
我觉得golang中的JIT可以这样定义:为特定的功能点,动态生成特定的机器码,以提高程序性能 。
关于如何实现一个golang中的JIT,可以阅读这篇:《使用 Go 语言写一个即时编译器(JIT)》
像把大象放进冰箱里一样总结一下:1.把一些机器码,放到一个数组中;(已经知道这些机器码是干啥的了)2.使用mmap系统调用分配一块内存,把内存设置为可执行,把上面的机器码拷贝进去;(然后这片内存就成为了程序的代码段)3.定义一个函数指针指向mmap的内存;4.执行函数 。也有golang库提供动态生成机器码的能力:https://github.com/goccy/go-jit 。支持的指令有限,而且,猜测没人愿意这么写代码 。
(读者一定在想这么鸡肋的东西介绍给我干啥……)
经验总结扩展阅读
- 持续集成指南:GitLab 的 CI/CD 工具配置与使用
- 信用卡怎么查消费明细
- 消费贷款申请产生的费用高吗
- oppo账号的姓名怎么修改
- 租房可以换锁芯吗合法么 租房换锁费用谁来承担
- 特斯拉可以用家用电充电吗
- 拆线多久可以用祛疤膏?
- 卫生间和厨房用什么瓷砖?
- 肉苁蓉副作用是什么
- 计米器怎么设置参数