英伟达Compiler岗面经

最近在往外投简历, 心想拿着两年LLVM的经验投SDE多少有点委屈, 索性看了看有没有做compiler的我还能用得上, Nvidia, AMD, Intel就都看了。 最后Nvidia看起来最猛, 第一天投简历第二天约面试, 刚刚收到下一轮面试邀请。

面试的老哥是在Nvidia待了12年的老哥了, 口音有点印度/中亚感觉, 估计应该是入职以后的team leader。 以下是聊天经过。

开头先介绍了一下他们组是做什么的。 大致上就是中间层代码优化(IR Optimization), 底层代码优化有做芯片的一帮人,上层应用有cuda及其他(其实是除了cuda其他应用我都没听说过也没记下来…)。 大概说了五分钟。

然后我花十分钟说了下我简历上过去两个LLVM相关的项目具体做的是什么。 他也不太关心我除开LLVM的贡献, 更多是关心我具体用LLVM写了啥。

之后就是一些琐碎的问题, 可以看出来面试官并没有抱着一个要考倒我的心态, 而是一步步在摸索我什么知道什么不知道, 对不知道的东西也会耐心的指导一下(墙裂好评。

“你对LLVM的熟悉程度怎么样”。 对前端clang那边了解不多,中间层(IR)做过很多工作也读了一些代码, 后端代码生成只是读了些代码和文档没有上过手。

那你有没有读过LLVM IR的文档, 这个我读过。 那你知不知道getelementptr这个指令, 我给他解释了一遍, 也说了一下我之前一个项目是怎么用的这个指令。 进一步问你知不知道什么是inbound,我说这个我不知道。 他解释说getelementptr本质上只是帮你算一个index,参数给的不好的话可以算出任何奇怪的结果, inbound修饰保证了算出来的结果不会出界。

“你一般用什么编译器”, LLVM

“有没有读过optimization的代码”, 无,但是我知道工作原理

“你知道哪些optimization”, 这个地方聊的比较多。 常数替换, Loop unrolling, function inline, 代码序替换 然后深入问了loop unrolling和function inline的motivation。 这个除了说减少jump以外我还真不熟, 他就举了个例子, 如果函数参数是常数就可以移除一部分branch然后做inline。

你上过哪些编译原理的课。 我说我本科修了编译原理, 前端从finite automata,Lexical analysis, 到pushdown automata, parser; 类型系统semantic analysis都讲了。 中间代码生成,后端优化讲了但是比较浅。 (其实我可以吹一下本科把斯坦福哪个COOL compiler从头到尾写了一遍, 但是这个属于远古历史没有太大讲的必要我估计) 然后研究生在Davis修了Programming languages(ECS 240), 更多是讲CFG,DFG;静态分析,代码优化的。 老哥听我一大摞说了这么多估计是我都熟也就没继续问下去

问我C/C++怎么样。 这话真把我问怂了, 千把行也不是没有写过, 但是远没有Rust来的舒心, 我就说C++还行吧, 不敢说bug free, 反正能写能debug 那C呢, 我说这个我行, C++就是有太多不读文档都不知道哪来的隐式语义。 老哥会心一笑, 被坑过的都懂

然后问了点C/C++的基础。 这部分我是真的菜。 先是两个struct的size, 第一个我倒是说出来了, 第二个不知道怎么脑子抽的说了个5, 然后面试官问我那我给一个Dummy2[2]尺寸是多少吗, 意识到了自己的错误。

struct Dummy1 {
    char c;
    int i;
}
struct Dummy2 {
    int i;
    char c;
}

啥是多态,这个我倒是答出来了; 进一步问我有没有静态多态(static polymorphism), 我想了想你说的别是函数重载把? 他说是。

最后算是一个应用题。 说你写了个编译器, 编译了一个30个文件的应用, 结果应用炸了, 怎么debug。 我说先用正常编译器看看, 如果应用也炸了那就和我编译器无关。 否则就前后端分离测试, 我编译一个IR给LLVM的后端;然后用LLVM编出来的IR给我的后端就知道bug在前端后端了。 我说实际上我上次遇到类似的问题就是这么debug的。

面试官说可能我的前端输出没问题,但是和LLVM不一样, 实际上问题在后端。 我说这个不应该,但是我是假设了前端结果一致,这个假设其实没有道理的。 他说搞优化的日常就是前端结果不一样,debug半天是后端的锅, 这里看起来还是我经验不足。

这个时候其实预约的45分钟就到了, 但是我问的几个问题愣是聊到了一个小时。