SC 19:我们赢了!

从 11/15 到 11/22 的一周多的时间里,超算队前往美国丹佛参加了 SC19 SCC。这是今年的第三场超算比赛,也是收官之战。由于在前两场都拿了第二,大家都格外期待这次的结果。我们最终不负众望,成功地得到了第一(Overall Winner),也是第二年蝉联了 SC SCC 的冠军。我比完赛写博客好像已经成了传统,居然还被人催更了。刚好回国这几天因为种种原因不太想认真工作,于是决定摸摸鱼写写这次比赛的回顾。

赛题

SC19 的赛题在暑假前就发布了,大约有以下部分:

关于机器

选型

不同于 ASC 和 ISC,我们在 SC 依旧是由比特大陆赞助,因此需要我们对机器配置进行规划。我一开始今年还是按照去年的经验,选择了超微的两款机型:2029GP-TR 是 2U 的机器,至多可以插 3 个 PCI-E x16 设备,我们用作 CPU 节点;4029GP-TRT 是 4U 的丹炉,至多可以插 8 块卡和 3 个 x8 设备(但还是 x16 的槽),我们用作 GPU 节点;CPU 一概配置为双路 8280,内存 32GB * 12;互联使用了最新的 Infiniband HDR。

然而第一版配置交出去以后问题立刻来了:真的太贵了。我掐指一算,似乎预算都花在 CPU 上了,于是又找陈老师从 Intel 顺利地借来了 12 块 8280(甚至还是 8280L)的工程样片。这下价格问题都解决了,但是又被告知 HDR 的卡和交换机都有很长的货期。无奈之下,我把卡换成了 HDR100(虽然速率一样,但是延时比 EDR 有优势),而交换机就好在现场从 Mellanox 借 EDR 了。而同时,hkz 他们因为另一个比赛从 Mellanox 弄到了一种神奇的 HDR100 卡,有两个 PCI-E x16 的接口;一查才知道,这是一种叫 Socket Direct 的技术,这样两个 CPU 都可以直接和卡通信。我们的插法也比较神奇,把它们插在丹炉的两个 x8 口上,这样事实上单个插槽的速率只剩下了一半,但是加起来还是能打满带宽。

安装与调试

机器在十月下旬运到学校,我们大概有一个多星期的时间调试。上面提到,我们其实并没有 IB 交换机,而 fgy 告诉我们这种卡支持 VPI 技术,在使用 QSFP56 物理层的情况下,能够随意将链路层在 IB 和以太网之间切换。而在以太网模式下,它支持 Host Chaining 功能,就是能够支持硬件的链转发。但是事实上这一功能非常缺乏文档,表现也非常玄学。首先,它需要特别的 MPI(即 Mellanox 的 HPC-X)才能正常工作;在普通的 MPI 点对点通信模式下,性能在包大小较大时会产生断崖式下跌(大概是因为以太网的 MTU 比 IB 小多了,于是 fallback 回了 TCP 模式),而一些集合通信需要配置极其复杂的 UCX 参数才能进行,性能更是不正常。来回折腾了三天以后,我们终于决定,放弃这个方法,直接上交换机;国内没有,我们就从 BIC 上飞了无数的线解决这个问题。

然而集群装上以后大家发现了一个问题:Intel RAPL 不好用了,看起来是被 BIOS 锁了。我们功耗控制非常依赖这个功能,而重新刷了 BIOS 也没有用。危难时刻,坏人站了出来,从网上找到了一个神秘的修改 AMI BIOS 的工具,把默认配置里面的 RAPL 打开,然后刷进机器……果然这世界上是有奇迹的。

机器运输的过程按下不表,确实很累也很麻烦,中间还因为箱子里夹带了锂电池(一起寄过去的电动螺丝刀里的)被机场打回过一次。比赛的前两天是装机时间。到现场以后一开始我们并没有找到它们,后来才在相隔挺远的新竹清华附近找到。现场装机过程比较顺利(flag),上电跑起来也看起来没什么问题(flag * 2),所以装机第一天晚上(周五)大家都回去睡觉了,晚上还参加了一个 SC Student Mixer,是请大家到酒吧吃东西(排队好长啊)和玩游戏(hkz 居然夹起来了一个球!)。

第二天各个应用都试着跑了跑,压了压复现的功耗,一切看起来都很好。直到下午 hkz 指出了一个问题:机器的功耗抖动非常严重,哪怕只是 ssh 到一台机器上都能引起将近 100W 的功耗尖峰,而 clush 一下就有将近 500W。我们多次测试,果然如此,于是大家慢慢开始慌了。再看 Grafana 里面的功耗日志,是在学校就有这样的情况,但我们并没有非常留意。而一旦这个问题无法解决,我们的很多应用就只能非常保守地跑,必然带来被动的局面。一开始,我发现 CPU 电源的 governor 不对,似乎是 BIOS 里面的 P States 没打开;打开之后,功耗抖动的问题消失了,但是尖峰问题依旧。我们也考虑更换备用机(多带了两个 CPU 节点)、拆掉多余的硬件控制变量(包括 SSD 和 IB 卡),但是问题并没有任何环节。此时已经是第二天晚上快十点了,第二天上午就要开始 benchmarking 了,而我们因为这个问题并没有认真地开始调。

手足无措之下,我做了一个 Arch 启动盘,把服务器从 U 盘启动,尖峰居然不会出现了!观察了二十分钟以后,我确定真的是消失了。对比了一下环境的差异,我灵机一动:会不会是 Debian 9.8 的内核太老了,和最新的 8280 CPU 有奇怪的兼容性问题?于是我立刻找了台机器从 backports 升级了最新的内核和 microcode,重启,问题解决!此时已经是晚上十一点多。大喜过望,我和傲傲留在现场,我负责升级机器,他负责之后的 benchmarking 调参。到一点左右,六台机器都升级完了(除了系统,还有显卡驱动、IB 驱动等),功耗问题彻底消失,并且待机功耗也减少了 200W 左右。到两点多,傲傲还在调 HPL(不停爆功耗),我没有太多事做就回去睡觉了。

装机的这两天还发生了一件有趣的事情:我忘了带 console 线,并且到处借不到,于是去 TUNA 技术群不抱希望地问了一下有没有人来 SC 的话能帮我捎一根。没想到真的有人响应了,并且还帮我问了个“搞网络的朋友”并且借到了。第二天,当一个带着 committee 手环的人(黄华)给我 console 线的时候,我确实非常震惊,惊讶程度不亚于后来知道这个“朋友”其实是江大的时候……果然 TUNA 群友是万能的啊。

比赛环节

Benchmarking

第三天几乎整天是 benchmarking,要跑 HPL、HPCG 和 IO-500 三个基准测试。前两者要求比较严格,两个测试之间间隔不能超过半小时;并且用于 benchmark 的硬件不能再有任何改动(包括重启)。因为前一天 cggg 把空调调得太高,这一天我醒过来的时候口干舌燥,头疼欲裂。虽然意识到自己发烧了,我还是硬着头皮去了赛场。

一开始我们的过程比较顺利,用一个多小时就跑完了 HPL 和 HPCG,并且结果得到了组委会的认可。于是我就闭着眼睛跑了一发 IO-500,得到了一个还不错的结果,就赶紧回去睡觉了。睡了两个多小时,打开微信一看:IB 卡从系统消失了,说是自己过热了。这可是一个大问题,没有 IB 卡我们肯定无法正常运行程序,而使用 PCI 子系统的 removerescan 也没法把它找回来,恐怕是只能重启了,但是重启意味着所有测试需要重新运行。这时候我才想起来,其实上午发生过一次这个问题,hkz 来的时候直接重启了,我也忽略了这件事情。问题的根源是,在 CPU 节点中,IB 卡被安装在 GPU 位,而我给复现题压功耗的时候想到没有 GPU 就把风扇完全关掉了。于是只要复现题稍微运行一段时间,IB 卡就会因为过热报警,然后自杀。

这时候是下午三点多,没有任何别的方法,痛定思痛,我们只好从头来过。然而上午还能顺利跑完的 HPCG 可能因为会场过热或者电压不稳定,连续爆了好几次。我们不敢再冒险,只能留着 100W 的裕量跑完了它,然后是 HPL 和 IO-500(这其中还发生我因为忘了放开 CPU 功耗限制让 IO-500 变得奇慢无比的乌龙)。好在结果没有太差,少了 5% 左右。有惊无险地交掉了结果,就等着晚上正式比赛开始了。

说到 IO-500,这是今年 SCC 新增的项目,只需要完整运行测试就可以得到 1 分的加分,而分数最高的队伍可以得到 2 分。要跑的就是 这个程序,分成 iormdtest 两部分,分别测试文件读写带宽和元数据操作性能。测试总共分成 8 个阶段,原本每个写阶段都要跑 5 分钟成绩才有效,不过 SCC 的规则下只需要跑 30 秒。它的最终分数是带宽(单位 GB/s)和元数据性能(单位 kIOPS)的几何平均值,而这两个值本身又是它们对应所有阶段结果的几何平均。

我们最后选用了 Intel P4618 这款 SSD 用来单机跑测试,这几乎是市面上单盘性能最强的 NVMe SSD 了。结果换上以后发现居然默认配置根本跑不满 30 秒,需要通过调参增大程序的写入量才能解决。一开始跑出来的成绩并不理想,然后我就进入了艰苦的调参阶段,尝试了各种不同的参数组合(包括进程数量/每个进程的写入量/文件数量等等),也尝试了用两块盘做 RAID 之类或者换文件系统之类的方案。踩了无数的坑(尤其是不知为何它很容易让 EXT4 元数据损坏,所以我一度把它称为 Corrupt-500)以后,最后我还是乖乖选择了单盘 EXT4 的方案,挂载时开 noatime,并且测试前进行一次全盘 erase 和格式化。最后我们的得分是 30.56(带宽 3.08028 GB/s,IOPS 303.121 kiops),这也是我历史上跑出来过的最高的分数(之前即使两盘也没有过这么高的时候)。

到了现场我才发现,很多队伍都对 IO-500 有所准备,甚至有人带了 16 块 NVMe SSD 的阵列来跑。我看到这些配置的时候一度觉得不可能有希望得第一了,没想到最后的 结果 非常出人意料。当然在带宽上,我们的确远远比不过单机多盘或者多机 PFS 的队伍;但是 P4618 的随机性能实在强劲,IOPS 这一项吊打了所有队伍(第二高的南洋用了四块盘也只有我们的 64%,当然也可能是调参的问题)。拿到这部分的加分实属意外,这也意味着明年大家应该都能摸清门道,大概又会是一场腥风血雨吧(笑)。

神秘应用

第一天也发布了神秘应用,叫做 Sparkler,是一个用 CUBLAS 计算稠密矩阵乘法的程序。要求很简单,把给出的 testcase 都跑完,并且不让动代码。我第一天晚上很快就编译出来了,然后简单尝试了一下运行也没有问题。总共有四个点,分别是(1 GPU)几分钟、(2 GPU)十几分钟、(3 GPU)一个多小时、(6 GPU)五个小时。由于第一天晚上要跑复现,所以我就委托在场的人在我回去睡觉的时候穿插跑一些小点。第二天来的时候,复现已经跑完了,正当我愉快地起一个大点的时候……断电了!此时我们心中一阵暗爽(因为几乎没有丢失任何进度),然而电一恢复就因为我把 3 + 6 GPU 两个点一起跑而爆了一下功耗(事后被告知不扣分)。我手忙脚乱地掐掉了程序,发现它的功耗曲线实在是抖得厉害,就像是我们来的路上坐的飞机(大雾)。虽然大部分时间每个 GPU 的功耗都很低,满是冷不防就会出现一个峰;没有什么好办法,只能压着最高功耗慢慢跑跑了将近五个小时,然后交了结果。

SST

SST 全称是 Structural Simulation Toolkit,是一个模拟计算机系统结构的软件,代码都在 这里。它分为两部分,Core(模拟引擎)和 Elements(各种组件);各种 Elements 通过一致的接口连接起来,并通过事件驱动的方式进行模拟。比赛需要我们运行的组件是 Miranda(一个 pattern 驱动的 CPU 模拟器,能够产生访存序列)和 Ember(一个模拟 MPI 通信的网络组件)。赛前下发的 testcase 跑起来的结果让我们非常震惊,Miranda 的扩展性奇差,单进程和 20 进程花的时间没多少区别,大部分的时间都花在进程间同步上,可见负载不均衡问题的严重。当时我和傲傲都在 CNCC 愉快地玩耍,然后看到结果两个人集体开始自闭……它模拟的是一个 KNL 架构的 CPU,从中间对称地切开能够有一些作用,然而作用也不明显。正当我们继续自闭时,傲傲突然发现了 Miranda 里面一个神奇的依赖处理写得很愚蠢,改完了以后有 7 倍性能提升。大喜过望,我们开始继续 tune 它,我也改掉了一些奇怪的数据结构,获得了进一步优化。另一个比较有意思的改进是,它在打印日志的时候先生成再根据 log level 判断是不是打印,然而恰好有一些日志的生成非常慢……总之,我们对于 SST 的代码质量确实比较无语。

虽然做了优化,但是并不能根本上解决负载不均衡的问题,所以我们选择让 SST 在云上单进程尴尬并行。这次给的 case 之一就需要用 Miranda 跑 5760 组不同的参数组合找到最优的,于是傲傲愉快地写了一个脚本来做这件事情(听说有些队伍常使用一些启发式的方法剪枝,然而我和傲傲都觉得一把梭跑完就完事了)。每个 case 大概要跑十分钟左右,我们用了 88 个核来跑,所以十几个小时也就跑完了。另一个任务是两种大规模的 Ember 网络,都要求跑 10 个 iteration,基本上每个 iteration 的时间都要一个多小时。那怎么办…跑呗!

原本我们很开心地觉得,别的队大概是跑不完这么多种 case 的(毕竟我们有常数级别的优化)。然而等我们都跑完了挑出结果,为了验证正确性使用原版的 SST 一跑才发现,我们仿佛比原版变得更慢了……?不过这也是在预期之中的,没有带来太大的影响。我们只好从 interview 的 PPT 当中去掉了这部分优化的内容。话虽如此,我们 interview 的时候根本没有等来作者 Clay,唯一的印象是前一天我晚上他跑来问了一句我们是不是有任何问题。最后面试的成绩是 8/10,四周问了一圈,凡是说没有问题的队伍都是 8 分,很少有 7 或者 9 分的。好吧,大概作者就是比较懒吧。

复现(reproducibility challenge)

复现题是 SC 的特色,要求复现前一年 SC 某篇论文的结论,今年是要验证 这篇文章 中间关于扩展性的一些部分。与往年不同,大家预估今年的复现要全机跑将近十个小时,时间比较长。由于担心第一天晚上就断电,所以原本的计划是先跑小点,等断电以后再跑大点。然而机智的 cggg 在第一天凌晨发现 committee 只剩下了一个人值夜班,推断其实不会断电,于是就大胆地开始跑耗时比较长的点,于是顺利地在第二天早上的时候跑完了所有的点(然后过了一个多小时就断电了)。

作者石嘉(Jia Shi)在比赛的时候一直在现场,所以 zcg 和 zc 和他也进行了比较多的交流,获得了很多的帮助。他告诉我们其实他对这次的题目也一无所知,出题和判分都是由组委会来负责的。复现还有一个特别的要求就是要写报告,虽然提前写了一个框架,很多数据还是要等现场跑出来再填进去。于是咸鱼的我就当起了报告的 proofreader,挑出了不少或大或小的错。最神奇的是组委会说了这次的数据是 Mars,但是复现的两位同学一个人也没听见,都还是按照原来的写的 Moon,一度导致我怀疑我的记忆的确出现了偏差。复现的 interview 环节也比较神奇,来的评委并没有问任何关于技术细节的问题,而都是情怀关于复现的意义之类比较 general 的问题。

VPIC

VPIC(Vector Particle-In-Cell)是一个粒子物理模拟器,可以用于模拟核聚变之类的过程。郑总和 hkz 在赛前一直想弄明白它的原理,找了续老师一起读论文,但是因为专业不对口好像没有太大的帮助。后来续老师介绍了魏文崟同学一起来,他是这方面的专家,把原理安排得明明表白的(误)。

比赛的时候拿到题目,他们就大呼坑爹:因为组委会给出的步骤数量根本不可能跑完,并且每次 checkpoint 的时候都要产生大概 120GB 的文件。考虑到赛场到云的链路质量其实比较差,所以完全无法进行迁移。权衡了一下,他们就在云上跑了。然而过了一晚上,题目负责人突然发了一个公告说给错了规模,但是新的规模还是很难跑完(200W 步,每小时大概 3W 步),并且 checkpoint 还是比较大(20GB)。虽然如此,考虑到复现和神秘应用跑完还有三十多个小时,他们还是决定把题目搬到本地来跑(这可能也成了面试的时候一个亮点)。当然,过程并不顺利,一开始遇到了 ulimit 的问题,后来晚上又被突如其来的第二次断电浪费了几乎整个下午的进度。好在之后就比较顺利,我们到比赛结束的所有时间都在努力地跑 VPIC,最后大约跑了 120W 步。有很多其他队伍报告自己把 VPIC 的一部分计算(甚至是整个 kernel)移植到了 GPU 上,但是因为种种原因效果并不十分显著。最终 ETHZ 跑了大约 150W 步,我们是第二多的。题目负责人告诉我们他期望大家至少能跑 10W 步,最好的在 100W 左右,而我们已经超出了他的预期。而 interview 的时候,评委显然对我们对于物理背景的了解比较满意,说我们基本把他想问的都先说完了。

其他

SC 还有一个传统项目就是 Poster,很不幸的是今年做 poster 的锅又到了我的头上,而我又抄起了昌老师的祖传模板。其实做的时候就发现 SC18 的时候已经有很多队伍或多或少地借鉴了我们的内容或者版式,而今年等到大家的 Poster 都贴出来的时候……好吧我输了,有一个队伍几乎原封不动地使用了我们的设计和框架内容。看来明年祖传模板是没法用了,需要找人再设计一个新版的了。最后 Poster 的分数不是很高,甚至比那个借鉴我们的队更低,这就有一点令人难受了。

往年的 SC 有一个 engagement 项目,要求队员去听 SC 的一些 talk 然后回答一些问题。今年我们很开心地发现,这个项目变成了 advisor engagement,要求 advisor 参与会议并且写一个报告。各个参赛队伍看起来对此都很开心,并且在后面的总结会上强烈要求保留这个环节。

此外在没事的时候我还去 SC 的展区逛了逛,又见到了 ISC 的时候好多熟悉的厂商(甚至是一摸一样的展台布置)。据说华为其实是很大一片展区的,但是因为种种原因没能用上,就成了满满当当的展览区里面很大的一块休息区。

赛后

第三天晚上五点半,比赛结束了。大家都被要求离开自己的 booth。当晚我们去了 SC 组织的 dinner with interesting people,我和傲傲、张晨在一桌上,听一个澳大利亚的教授讲和小动物相处的日常(大雾),而后又跑去了 Mellanox 的一个晚宴蹭吃蹭喝。第二天一觉醒过来已经不早了,我和傲傲就去给几个机器换了 CPU(虽然有一台的螺丝坏了并不能打开)。中午有一个 Awards Lunchoen,大家吃了一些比较神秘的菜。

接下来就是颁奖典礼了,我们刚进去的时候,黄华神神秘秘地对我们说,让我们坐在靠边一点的位置比较方便,这时候大家其实已经难以抑制心中的激动了。场地还有一个比较神奇的设计,就是提词器会比主持人说的话快一些,于是我们也提前一点确认了这个好消息。当然,最高的 LINPACK 还是南洋莫属,但是他们的最高 HPCG 事实上并没有我们第一次跑出来的高。无论如何,结果是让所有人都开心的:我们终于摆脱了悬在头上的“三亚”的诅咒,在今年最后一场比赛拿回了冠军。很遗憾的是,郑总因为吃饭迷路的缘故浪费了一些时间,一直到上台领奖的时候还没有出现,直到我们拍照的时候才匆匆忙忙地冒了出来。

Awards Ceremony 结束以后是 SCC 总结会,每个队领到了属于自己的奖,我们是两个 IO-500 的奖,分别来自于 SCC 委员会和发起方。结束之后就是拆机环节,直到这时候我才发现好像我不知道应该把机器寄到哪里去……于是又是一通折腾,好在最后问题也顺利解决了。晚上是 SC 的 Technical Program Reception,是在一个飞行器博物馆里面吃喝玩乐+聊天,大家都玩得挺开心的。

第二天是周五,丹佛下起了大雪。上午 Mellanox 的人拉着我们去了车程半个多小时的 Outlets,本来没打算买东西的我看到价钱还是买了两双鞋。万万没想到我的同学们购买力纷纷爆表,某年级第一 xl 同学在前一天逛了半天的前提下,又在 Outlets 整整买买买了一天,晚上七点多才回来。当然,也有和我一样的两个人不能忍受逛街的生活,下午就回了,在 Denver 的 downtown 转了一圈。我主要去了 Denver Public Library,感叹它在归档方面工作之完善。原本打算晚上一起吃顿饭,没想到他们从 Outlets 回来以后又去了 Apple Store 继续买买买……!好吧,有钱人的生活毕竟不是我可以理解的,就像某 cggg 一天花了一万多一样。

第三天是出发的日子,原本没什么好说的,然而我又不幸遇到了奇怪的事情。我们原本是 DEN-SEA-PEK 两程,而我发现除了我之外所有人的第二程都因为超售没安排座位。正在担心这件事情的时候,我们的第一程飞到一半备降在了 SLC,理由居然是。。厕所坏了。虽然 Delta 给我们换了一架飞机,但是无论如何都赶不上第二程了。正在我们盘算在西雅图该怎么玩的时候,地勤告诉我们,下一架飞机会等我们,但需要我们跑快一点。不知道怀着怎么样的心情,大家经历了可能是人生中最短的转机(在两架飞机中间的时间不超过两分钟),终于是踏上了回国的航班。这时候大家发现,好几个没被安排座位的人被升到了超值经济舱。好吧,风水轮流转……

最后的总结

越写越长,一回头才发现其实大多数是废话。不管怎么样,我终于把想说的都说完了。这是我第一次去 SC,也会是最后一次以 SCC 队员的身份去了,这个结果确实也确实了了我的心愿。前两篇文章,我在结尾都写下了加油;这一次,我想大声地喊出:

我们是冠军!