HPCGame25 Write up

A

签到,看到18()()时候就知道是1898了。

B

浮点数那道题试了几次,感觉好像和CSAPP的IEEE754不太一样,在若干答案中试出来了最终的答案。CXL题是完整扔给AI做出来的,截图放在工作区压缩包里了。其他基本上可以在互联网上找到答案。

C

  • 感觉Intel编译器在Intel处理器上不会太慢
  • -x c来使得icx把F90的Fortran源文件认成C语言源文件
  • -xHost-fast来使得icx/icpx使用最新的CPU指令集和最快的编译选项

D

经典动态规划。定义动态规划状态矩阵dp[i][j]

如果将dp[0][0]看作左上角的点(一般矩阵就是如此),那么从dp[0][0]开始的每一条反对角线都只依赖前面两条反对角线,而每条反对角线内部可以openmp并行。可以用三个rolling array来优化空间复杂度。

这个问题比较tricky的点在于,感觉Kunpeng 920的分支预测不太行。我个人本来习惯了循环范围大一些,在循环内部用if-continue来跳过不需要的部分,但是这样会导致分支预测不准确,对性能有很严重影响。所以必须保证循环范围精确。问题的核心:

1
2
3
4
for (int d = 1; d <= len_1 + len_2; ++d) {
        #pragma omp parallel for schedule(static)
        // for (size_t i = 0; i <= len_1; ++i) THIS WONT WORK FOR KUNPENG
        for (size_t i = max(1, d - l2); i <= min(d-1, l1); ++i)

E

MPI基础题。这题ChatGPT就能写出一半了。

https://chatgpt.com/share/679469e9-3794-800f-80cb-85a0f62f7984

改一个时间从1还是0计数的问题,再把魔法事件列表同步到所有进程,就几乎是满分了。

F

题里说使用高斯消元,但感觉完整的矩阵存不下,不太确定该怎么做了。

G

输入数组分成nthreads份,每个线程计算自己的部分,最后用串行排序合并结果。

经比赛群里提示Julia原生TopK性能很差,重新使用堆排序实现了TopK。

Julia确实挺有意思,可以当个强类型带模板的Matlab写。

H

没做

I

想了很多插值的方法等技巧,最后误差都太大,放弃

J

本质找blas题,用blas替换blas.c里面的函数即可。我们在run.sh里面加载了KML和毕昇编译器。

1
2
3
4
#!/usr/bin/bash
module load /opt/huawei/HPCKit/24.12.30/modulefiles/bisheng/kml2.5.0/kml 
module load /opt/huawei/HPCKit/24.12.30/modulefiles/bisheng/compiler4.1.0/bishengmodule
source /opt/huawei/HPCKit/24.12.30/setvars.sh --force --use-bisheng

(重复加载就重复加载吧,总归是能用的)

blas.c里面有一个函数是lapack的,KML的Lapack需要用Netlib Lapack补全,但是在上面尝试了几次,没成功。给那个函数简单进行OpenMP加速,其他调用使用blas就能拿到大部分分数了。

K

谨慎使用你不熟悉的技术栈。我做科学计算,我只会OpenMP,用pthread写半天没写出来😂

由于算法的随机性,每个任务一个线程会导致程序运行时间为耗时最长任务的时间(“长板效应”?)。在完成每个任务时,把这个任务分给所有线程才是合适的选择。

对我来说OpenMP比pthreads好写多了,直接把可并行的部分找出来加#pragma,处理点同步问题就行了。

改变了随机库的使用,不再使用/dev/random,怀疑一起读取导致线程不安全。

使用 Hugo 构建
主题 StackJimmy 设计