我的编程历程

整理回顾我的编程、计算机探索历程。写于2022-06月。

早期阶段

在高二之前,就是在小学六年级左右,家里就有了一台计算机,AMD K6-II 266MHz的处理器。最初除了打字以外没做过别的,每周开机怕坏了。 后来是因为迷上了星际争霸(以及后来一些其他的游戏),才对电脑感兴趣的。除了玩游戏、看一些R18网站之外,就是捣鼓DOS命令,装系统, 还有CPU超频啥的(因为没几年K6就过时了,性能不足)。

真正接触编程的话,最早可以追溯到高二了,那时候参加过省内(新疆省)举办的编程大赛,用的是Pascal语言。 记得当时参赛的就有用c语言的,觉得倍儿牛逼。

后来高考不是很顺利,差一分上一志愿,结果分配了个北京的二本,好在专业是计算机专业,懒得复读就去了。 好像大一下学C语言了,我的课题还做了个图形界面的菜单,可以加载其他人的程序(分组做,组长的程序是个加载器)。

后来参加过三届智能车比赛,都是用C语言,说实话这些比赛对提升编程能力没啥帮助,反倒是练就我一身diy的本领。画电路图、PCB、 去知春路买配件、制板、焊接 等等,都是搞这个学会的,还给CPLD写过VHDL程序。单片机也是用过日立和飞思卡尔的。

毕业设计的时候,给一个小企业搞了一套单片机+传感器+键盘+显示屏的系统,用来做dna浓度检测的。

毕业后,因为做过很多单片机的事情,又对硬件感兴趣,阴差阳错就进入了北京君正。后来想想,我毕业的时候正是Android刚刚兴起,智能手机 开始冒头的时候,如果去做了Android开发(后面肯定也会涉及iOS等),是不是早就财务自由了呢。事实上,同时毕业的就有几个干了几年就创业了, 只是后来做到多大就不知道了。反而自己一直在硬件公司做软件,这种工作环境就感觉别扭不给力,很不是滋味。不过,又有什么关系呢? 神给的就是最好的,祂的智慧良善远远高过我这地上的尘土。

基础积累

毕业之后,机缘巧合去了君正面试,笔试题其实挺难的,需要有扎实的C基础,懂二进制位操作。

进入君正之后,首次接触Linux工作环境,vim以及Emacs都是在那时候接触开始使用的。一开始的工作是基于GDB/mips-sim开发了一个程序分析器, 简单说就是用GDB里面的一个simulator跑mips程序,统计分析程序的热点片段之类的。后来还基于它搞了一个顺序流水线的CPU性能模型(很简陋)。

之后被安排去做内存一致性测试,就是在多核的开发板上运行各种同步测试,那是都是在网上找一些测试。记得测信号的时候还测出一个内核bug。 后来还做过一些内核移植的工作,简单的驱动开发之类的,自己开发的驱动记得有串口、GPIO、SD卡、网卡吧,其实很多是基于兴趣在做,并非工作需要(偷笑)。

当时基于君正芯片(好像是4780)的平板电脑,有个看视频卡顿不流畅的问题,还是我找到原因的。说来也很有趣,就是视频解码的进程优先级被调的太高了, 甚至比mmc内核线程还高,导致总是解码把输入数据消耗完了才轮到mmc读取数据,于是就卡顿了。把优先级调一下就正常了。不过定位原因还是花了不少功夫。

后来还是一致性测试的工作,我们基于linux进行测试不是那么好做了,因为线程调度复杂(当时也不会做更多的线程控制),后来就想抛开linux, 直接写程序在芯片上运行进行测试,也就是裸机程序。 基于这个需求逐步开发出来的就是ObjMips了,一个测试平台,同时融入了很多操作系统的元素 (就是我从linux内核里面学来的),最后测试平台做成了一个简易OS。这个还是很有趣很锻炼编程能力的。

在君正最后一项比较大的工作就是开发MagicCode了,内部叫AKIM(ARM killer is MIPS),这是一个动态二进制转码工具。当时公司也是从外面买的, 记得代码其实是某种arm32的游戏机模拟器。我在完全搞明白那个代码之后,几乎全新开发的就是AKIM了。AKIM集成在Android系统中,对Andriod linker 动态连接器和内核代码都有修改,用来在加载动态库、可执行程序的时候,遇到arm的就同时加载动态翻译器(作为一个动态库被加载)。

当时整数部分优化的重点就是nzcv的处理,最后影响性能最大的是返回地址查询的问题(无法直接返回,部分程序会出问题)。其他部分就是浮点问题了, 记得当时是arm v7,VFP处理就挺麻烦了,还有neon指令的翻译,浮点翻译之后的效率都是很低的。

二进制翻译程序大概是我当时的集大成之作了,C语言编写,对编译、链接、加载、指令集、寄存器、内存空间、线程、ABI等等都有了一个深刻的理解。

为了实现这些指令的翻译以及功能验证,最多的时候带了十几个人在做。不过最后还是没有做到很完善,运行游戏还是会偶尔出现闪退现象,这些问题的 定位简直就是噩梦了。后来arm发布了cortex A系列处理器,性能开始逐年飙升,mips在平板、手机产品上面已经毫无优势,翻译执行就更是用不上了。 (这些都是后话了)

最后在13年的时候,那边空降了一个领导,加上工作也不是那么开心了,意气用事也好、年轻气盛也罢,就裸辞了。不过空降的领导倒是挺乐意的,或许我在 对他来说还是弊大于利吧。

辞职之后玩了一个多月,之后找工作就碰巧找到华为海思,是要做自研核的,在组建团队,对我的吸引力很大。同时还有个晶晨的机会也很好,做内核开发的。 我还是选择了去华为,继续追CPU的梦。不过华为就是大公司,从面试通过到发offer入职,足足拖了我一个多月,也真是靠毅力才能坚持下来。因为在等 offer期间不得不推掉其他不错的offer,真是磨人。不过同时期面试的清华大佬,比我晚面试,比我早入职,两周offer就拿到了,看来学历还是很有用的啊。

放开眼界

在君正的三年,编程技能都是C为主,我也喜欢linus反对在内核使用c++的观点,认为C才是最好的。除了C以外,也学过用过perl python,不过都是些皮毛。 编辑器主要使用Emacs,从君正那边延续下来的。

进入华为之后,也不管你啥背景,哪儿缺人就去哪。进来就被安排去做RTL验证,负责模块是Rename,后来也涉及到mapq。那时才首次接触verilog和system-verilog, 谁也想不到我首个正式使用的面向对象编程语言是system-verilog,真是有趣。不过学了就会发现也不难,我很喜欢使用里面的对象和系统组件,后来还 开发了一个checker框架,安排这活儿的是余红斌,他后来没多久就走了,后来还开发了高性能RISCV的CPU。

我在OOO里面做模块验证后一段时间后,就被安排去了TOP层做了一段时间的MMU验证,LSU验证。

在验证的这段时间,有很多log需要处理,还有一些运行环境要管理,当时就深度学习了perl语言,开发了好些脚本,perl的使用也有长足的进步,直到用perl写 面向对象程序之后,感受到了perl的瓶颈,那种没有原生支持对象的确实不太好用。

验证做了一段时间之后,又被安排去做性能模型,这些安排也没啥特别的原因,就是哪里缺人,自己又愿意服从安排。当然去做模型还是跟我又软件背景有关系吧。 再干几年验证我只怕要忘了自己时做软件的人了(哭)。

性能模型时C++开发的,公司从外面雇佣的专家搭了个架子,我们进一步完善它。之前也有开发的性能模型,结果模型本身的性能太差,没法使用。 开始搞模型之后,就不得不好好补补C++了,好在当时C++11标准已经普及了,我当时看到C++11标准的时候,简直快要两眼放光了,新特性让c++好用了十倍(开玩笑)。

C++11的闭包是我最喜欢的,其次是auto。原先在c++里面想要做回调特别麻烦,感觉比C还有麻烦,也可以用c的方式去做,但是感觉就是不爽,不是那么的 符合优雅。新的闭包(匿名函数),可以简洁的实现回调。另外auto和for语法糖大大简化写迭代遍历的过程,而这还正是常用过程。

C++的历程就不赘述了,作为伴随我多年的语言,用的最多,了解也最多。

在14年的时候,碰巧买了两本书,是松本行弘写的,代码的未来 和 松本行弘的程序世界,从这里我开始学习使用ruby。书里面对比了不同的编程语言,还有不同的 语法特性,让我大开眼界,也是从这时候起,我对编程语言本身开始感兴趣了,也开始学习各种编程语言,对比学习。

Ruby确实是很棒的编程语言,正如起设计者松本行弘所说的,他想设计一个有趣的语言,一个对程序员友好的语言。Ruby确实友好也有趣,用过ruby之后才明白, 写代码可以这么自由。DSL概念也是这个时候接触到的,并且我在一个波形文件提取工具里面就好好的实践了一次DSL。用Ruby开发DSL还是很容易的,不过也有局限。

未来

我一直对编译器感兴趣,也想自己试着开发一门语言,也有很多幼稚的构思。或许有机会实现,或许没有吧。

神用话语(words)创造了世界,这是事实,我相信但是不明白,希望能不断地有所领悟,向真理前行吧。