2024 PKU HPCGame WP
今年参加了第一届PKU HPCGame,这是一场由北京大学计算中心等组织举办的个人超算竞赛。
题解情况如下:AC题目 A,B,C,D,F,I,L ; E,G,H 拿到部分分数;J,K,M,N 无解。这篇WriteUp主要是对我解决的题目的记录,以及一些解题思路的总结。
A. 欢迎参赛!
签到
B. 流量席卷土豆
小 X 为了让你学习超算知识,要求你必须使用 4 个计算节点,每个节点 4 个 tshark 进程同时从 16 个 PCAP 文件中提取 SSH 流量。为此,他要求你使用集群上的 Slurm 调度器运行这一步骤,同时把进行这一计算的 Slurm JobID 和最终使用 quantum-cracker 获得的密码同时交付给他。他会检查这一 JobID 对应的 Slurm Job 是否使用了 4 个计算节点,每个节点 4 个进程。否则他不会动用他的量子纠缠能力。
1 |
|
此题只需要满足两个要求:
- 写slurm脚本在一个进程中调用4个节点,每个节点上4个核,一共十六个进程提流量
- 使用给出的quantum-cracker破解流量中的ssh密码
判定较为宽松,不是严格要求必须分配进程,所以只需要调用到足够的核就能满足第一个条件。
C. 简单的编译
在本题中,你需要写一个简单的Makefile文件,和一个简单的CMakeLists.txt文件,来编译 Handout 中所提供的三个简单程序。
1 | CC=g++ |
1 | #CMakeLists.txt |
makefile和cmakefile编写,套模板即可。
D. 小北问答CLASSIC
非常棒的知识问答,爱来自Neur0_5ama。

参赛昵称为Neur0_5ama,尝试作为Neuro单推人混入其中
最有意思的选项:
在高性能计算集群中,哪个工具通常用于作业调度和资源管理? – Slurm 微信群 蜂群(确信)
E. 齐心协力
对于一百个(200, 40000)的矩阵 x ,计算如下结果,其中 A 、B 、C 和 D 都是 (40000, 40000) 的矩阵。其中四个矩阵需要被放置在四个不同的节点上,每个节点有4个核心、16G内存。你需要对于输入的每一个 x ,计算得出最终的 output 。
y1=ReLU(x A)
y2=ReLU(y1 B)
y3=ReLU(y2 C)
output=ReLU(y3 D)
1 | import os |
根据题意,需要使用Ray来进行分布式计算
这道题测评易出问题,后续需要排队测评,本地调试配环境比较困难,因此到最后一天才做出来,而且写的非常粗糙。题干说明了输入输出文件有高速io,但是权重文件没有,因此AC答案应该是 O(weight+100input) ,而我的答案是 O(100(weight+input)),因此只拿到了部分分数,解答仅作为参考。
补充了ray的相关知识,是一道很有新意的题,题目本身不算困难。关于Ray核心介绍。
F. 高性能数据校验
本题使用一种基于 SHA512 算法的可并行数据校验算法对数据进行分块校验。(SHA512 是一种高度安全的校验码实现,具体算法不需关心)
算法的流程如下(对算法的具体解释见 baseline 代码):
- 对数据进行分块,每一块的大小为 M=1MB,记划分的块数为 n。如果文件剩余内容不足一块的大小,则补二进制0至一个块大小。
- 对于第 i 个块,在其末尾连接上第 i-1 个块的 SHA512 校验码的二进制值,将所得到的 M + 64 大小的数据进行 SHA512 校验,得到第 i 个块的校验码。(i 从 0 开始) 注,第 -1 个块的校验码为空文件的校验码
- 最后一个块的校验码,即为文件的校验码 注,大小为0的文件的校验码定义为空文件的 SHA512 校验码
1 |
|
根据题意构造如下MPI流程:
- 同步加载文件,每个进程加载自己需要计算的部分
- 每个进程计算自己的部分的SHA512,将结果发给下一个进程
因为该题目要求计算的值是递归依赖的,所以不能单纯并行来计算。在我的算法中,实际上计算仍是串行的,另外采取了mmap的方式来加载文件(如果算法更好应该是不需要mmap也能AC)。
G. 3D生命游戏
在本题中,你将研究拓展到三维版本的康威生命游戏。在三维版本中,每个细胞有26个邻居,状态转移规则如下:
- 当细胞为存活状态时
如果周围存活的细胞低于5个(不包含5个)时,细胞变为死亡状态
如果周围存活的细胞有5到7个时(包含5和7),则细胞保持存活
如果周围存活的细胞超过7个(不包括7个)时,细胞变为死亡状态 - 当细胞为死亡状态时
如果周围有6个存活细胞时,该细胞变成存活状态
同时我们希望研究无限空间大小下的生命游戏。但是,无限空间难以在计算机中表示,因此,我们采取一种”循环“的策略,来模拟无限空间。具体规则为:若有效信息的块的边长为 M ,则无限空间中任意一点 (x,y,z) 对应有效信息块中的位置为 (xmodM,ymodM,zmodM) 。
提交单个cuda源代码文件,评测系统将会用nvcc -O3来编译你的程序。
1 | //cuda |
该题根据题意是编写3D生命游戏的cuda代码。根据baseline文件将其改写为cuda版本如上。因为没有优化,因此只有极少的分数。
我做此题时尝试不少优化方法,但没有成功。一个非常明显的优化方式是将读取的数据加载进共享内存,可以避免全局内存的频繁存取降低性能。由于时间原因,没有来得及实现。
H. 矩阵乘法
你需要从文件 conf.data 中读取两个矩阵 M1 ,M2 并计算乘积 M3 =M1 ⋅ M2 ,然后将结果写入文件 out.data 中。
输入文件为一个二进制文件,定义如下:
- 三个 64 位整数 N1 , N2 , N3 ;
- 第一个矩阵 M1 的数据,矩阵有 N1 行、N2 列,以 64 位浮点的形式存储,顺序为行优先;
- 第一个矩阵 M2 的数据,矩阵有 N2 行、N3 列,以 64 位浮点的形式存储,顺序为行优先。
将矩阵 M3 直接写入输出文件中,以 64 位浮点的形式存储,顺序为行优先。
1 |
|
该题目是非常经典的矩阵乘法计算。编译选项为 -O3 -fopenmp -mavx512f,因此根据题意使用GEMM算法,使用openmp/mavx512f进行优化。后续又尝试分块计算,或者循环展开,手写GEMM,提升效果均不明显。这道题也是我头疼时间比较长的,只拿到了部分分数。感觉没有GET到优化的点,后续有时间再研究。
I.LOGISTIC方程
计算 n 个 64 位浮点数的 itn 次 logistic 映射,所有浮点数会使用相同参数 r。n 为 1024 的整数倍。
1 |
|
该题使用基本的openmp/mavx512f进行优化后能拿到73分,只有用循环展开进行优化才能拿到满分,这道题也是比较需要GET到优化的点才能拿满的。
我一开始以为是要根据Logistic映射的特性,分收敛和周期范围的情况进行计算,能够收敛时检测是否收敛(差小于0.0000005,按题意取到这个精度)得到收敛的位置;能够进入周期时候检测进入周期的点(或者检测第一次出现最后结果的点,从那个点直接跳到结尾),这样最优情况下能将itn次计算减少到几十次,能够在几十ms内完成计算,有效验证了收敛和周期的情况(大嘘)。结果交上去发现测评值全是发散的(即上述判断的最坏情况,退化回itn次计算),一度怀疑自己,后来才想到循环展开。
写都写了,不能浪费,分收敛和周期范围的情况计算Logistic值的代码如下
1 | //如果您要引用这段代码,请标明出处 |
J. H-66
K. 光之游戏
L. 洪水困兽
我们提供了一个 Handout,提供了串行版本代码和测试数据。你需要在 Handout 的基础上,使用 OpenMP 实现并行化的 particle2grid 过程。以下是对这一过程算法的详细介绍。
1 |
|
按照一般思路进行并行优化即可。
一核有难,多核围观.jpg
M. RISC-V OPENBLAS
N. RISC-V LLM
总结
整体体验下来非常好,题目很有意思,分配的计算资源也很充足。虽然服务器不太稳定,但组委会的成员解决问题都很及时,总体来说是一场很棒的比赛。参加这次比赛收获良多,自身也有很多不足的地方,总之还是要多多学习,明年再来。 /heart
2024 PKU HPCGame WP