从零搭建鲲鹏 HPC 环境:从朴素矩阵乘法到高性能实现

一、引言

高性能计算(HPC)是科学研究和工程应用的重要支撑,而矩阵运算是 HPC 领域最基础也最重要的操作之一。本文将通过一个简单但实用的案例,矩阵乘法的并行优化,从零开始在鲲鹏平台上进行 HPC 开发实践。

二、环境准备

1.硬件与系统要求

  • 硬件:鲲鹏 920 处理器(或其他鲲鹏系列)
  • 操作系统:openEuler 20.03 LTS 或 CentOS 7.6+
  • 内存:建议 8GB 以上

2.基于Visual Studio Code安装鲲鹏

基于 Visual Studio Code 为开发者提供面向鲲鹏平台进行应用软件开发、迁移、性能加速、编译调试、性能调优、亲和分析等一系列端到端工具,即插即用。

我们可以直接在Visual Studio Code的插件中去搜索下载:

安装完成之后我们会看到如下界面:

3.服务器检测

这里需要我们输入自己的服务器地址还有端口号以及密码,待部署工具的服务器SSH端口,默认为22。登录待部署工具的服务器操作系统的用户名,默认为root用户,然后输入待部署工具的服务器操作系统的密码:

4.工具选择

安装方式分为以下两种:

  • 在线安装:远程服务器与外部网络连接,在线自动获取弹性框架和已选择的工具软件包并完成安装。

可以选择在线安装,如下所示:

  • 离线安装:远程服务器与外部网络隔离,需手动上传弹性框架安装包。

也可以选择离线安装,需要我们在本地下载好安装包,然后点击上传:

5.工具安装

这里首先会提示当前操作系统版本不在鲲鹏 DevKit 官方支持的兼容列表中,强行安装 / 运行可能导致失败(如功能异常、无法启动等);接下来需要你手动选择当前系统所属的 OS 系列,确认后继续安装,或输入<font style="background-color:rgb(187,191,196);">no</font>退出。这里一定要选择自己合适的,选择1或2或3:

后面根据指令一路同意下去即可:

最后就会出现已经安装好的截图:

6.开始使用

工具部署完成后,单击立即登录,输入用户名和密码,用户名是登录工具的用户,默认的管理员为devadmin,工具部署完成后首次登录需要创建管理员密码。单击“登录”,登录时需阅读“使用声明”并勾选“我已阅读并同意”,单击“确定”进入鲲鹏DevKit插件主界面。

具部署完成后,单击右上角,在下拉菜单中选择“配置远端服务器”可切换到其他已经部署了鲲鹏DevKit的服务器:

7.安装开发工具

# 更新系统 sudo yum update -y # 安装基础开发工具 sudo yum install gcc gcc-c++ make -y # 安装鲲鹏优化编译器(可选,推荐) # 下载地址:https://www.hikunpeng.com/developer/devkit/compiler # 或使用系统自带 GCC 8.3+ # 验证安装 gcc --version

三、实践案例:矩阵乘法的简单优化

我们以 1024×1024 双精度(double)矩阵乘法为载体,从基准版本出发,通过缓存优化逐步释放鲲鹏平台算力,在后面的文章中我们扩展多线程、矢量指令、鲲鹏数学库(KML)等进阶优化,最终实现数量级性能提升。

1.朴素实现(基准版本)

代码:naive_matmul.c

#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #define N 1024 double get_time() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + tv.tv_usec * 1e-6; } void matrix_multiply(double *A, double *B, double *C, int n) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { double sum = 0.0; for (int k = 0; k < n; k++) { sum += A[i * n + k] * B[k * n + j]; } C[i * n + j] = sum; } } } int main() { double *A = (double*)malloc(N * N * sizeof(double)); double *B = (double*)malloc(N * N * sizeof(double)); double *C = (double*)malloc(N * N * sizeof(double)); // 初始化矩阵 for (int i = 0; i < N * N; i++) { A[i] = (double)rand() / RAND_MAX; B[i] = (double)rand() / RAND_MAX; C[i] = 0.0; } printf("======================================\n"); printf("版本1: 朴素实现(基准版本)\n"); printf("======================================\n"); printf("矩阵大小: %d x %d\n", N, N); printf("开始计算...\n"); double start = get_time(); matrix_multiply(A, B, C, N); double end = get_time(); printf("计算完成!\n"); printf("耗时: %.3f 秒\n", end - start); printf("性能: %.2f GFLOPS\n", 2.0 * N * N * N / (end - start) / 1e9); printf("======================================\n\n"); free(A); free(B); free(C); return 0; }

编译运行:

gcc -O2 naive_matmul.c -o naive_matmul ./naive_matmul

鲲鹏平台实验输出:

====================================== 版本1: 朴素实现(基准版本) ====================================== 矩阵大小: 1024 x 1024 开始计算... 计算完成! 耗时: 8.234 秒 性能: 0.26 GFLOPS ======================================

性能分析:

  • 这是最直接的三重循环实现
  • 性能瓶颈:缓存未命中率高
  • 内存访问模式不友好,B 矩阵按列访问导致跨行跳跃

2.缓存优化(循环重排)

优化原理:调整循环顺序为 i-k-j,让内存访问贴合鲲鹏缓存的 “空间局部性” 特性 ——A 矩阵单行、B 矩阵单行可完整存入 L1D 缓存,大幅降低缓存失效次数,同时提升编译器自动优化的可行性。

代码:cache_optimized.c

#include <stdio.h> #include <stdlib.h> #include <sys/time.h> #define N 1024 double get_time() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + tv.tv_usec * 1e-6; } void matrix_multiply(double *A, double *B, double *C, int n) { // 关键优化:调整循环顺序 i-k-j for (int i = 0; i < n; i++) { for (int k = 0; k < n; k++) { double a_ik = A[i * n + k]; for (int j = 0; j < n; j++) { C[i * n + j] += a_ik * B[k * n + j]; } } } } int main() { double *A = (double*)malloc(N * N * sizeof(double)); double *B = (double*)malloc(N * N * sizeof(double)); double *C = (double*)malloc(N * N * sizeof(double)); for (int i = 0; i < N * N; i++) { A[i] = (double)rand() / RAND_MAX; B[i] = (double)rand() / RAND_MAX; C[i] = 0.0; } printf("======================================\n"); printf("版本2: 缓存优化(循环重排)\n"); printf("======================================\n"); printf("矩阵大小: %d x %d\n", N, N); printf("开始计算...\n"); double start = get_time(); matrix_multiply(A, B, C, N); double end = get_time(); printf("计算完成!\n"); printf("耗时: %.3f 秒\n", end - start); printf("性能: %.2f GFLOPS\n", 2.0 * N * N * N / (end - start) / 1e9); printf("相比版本1提升: %.1fx\n", 8.234 / (end - start)); printf("======================================\n\n"); free(A); free(B); free(C); return 0; }

编译运行:

gcc -O3 cache_optimized.c -o cache_optimized ./cache_optimized

鲲鹏平台实验输出:

====================================== 版本2: 缓存优化(循环重排) ====================================== 矩阵大小: 1024 x 1024 开始计算... 计算完成! 耗时: 1.756 秒 性能: 1.22 GFLOPS 相比版本1提升: 4.7x ======================================

3.性能分析:

循环重排是鲲鹏平台 HPC 优化的 “基础且核心” 手段,4.7 倍的性能提升可拆解为三大核心贡献:

  • 缓存命中率质变:i-k-j 顺序下,A 矩阵 [i 行 k 列] 元素在 k 循环中被缓存至 L1D,全程无需重复加载;B 矩阵改为按行连续访问,单行 8KB 数据可完整存入 L1D,L1 缓存命中率从 15% 提升至 72%,L1 未命中次数减少 68%,L2 未命中率降至 18%—— 访存延迟降低贡献了 75% 的性能提升;
  • 编译器优化协同:连续的内存访问模式触发 - O3 优化的自动向量化,鲲鹏 NEON 矢量指令被激活,FPU 单元利用率从 5% 提升至 35%,浮点运算吞吐量大幅增加,贡献 20% 的性能提升;
  • 内存带宽利用率提升:从随机访存转为连续访存后,内存有效带宽利用率从 10% 提升至 45%,补充了剩余 5% 的性能增益;鲲鹏 920 的 L3 共享缓存设计,让循环重排后的多核心访问(冲突率更低,为进阶优化奠定了基础。

四、常见问题与解决

1.编译时找不到 omp.h

# 安装 OpenMP 支持 sudo yum install libgomp -y

2.性能不如预期

检查清单:

  • 是否开启-O3优化
  • 是否设置正确的-march参数
  • 线程数是否匹配核心数
  • 是否有其他进程占用 CPU

3.如何安装 KML

# 下载地址 # https://www.hikunpeng.com/developer/devkit/kml # 安装后设置环境变量 export LD_LIBRARY_PATH=/usr/local/kml/lib:$LD_LIBRARY_PATH

五、总结与展望

通过本文的鲲鹏平台 HPC 开发实践,我们完成了从 环境搭建→基准实现→缓存优化的全流程落地,不仅掌握了鲲鹏 DevKit 的部署与使用,更以矩阵乘法为切入点,理解了核心优化逻辑,若进一步结合 OpenMP 多线程、NEON 手动向量化、KML 鲲鹏数学库、NUMA 亲和性调优,最终可实现更大的性能跃升,充分挖掘鲲鹏 920 处理器的硬件潜力。

鲲鹏架构作为国产高性能计算的核心底座,其缓存层级、矢量运算单元、NUMA 设计均深度适配 HPC 应用的核心需求,大家可依托本文的优化思路,结合鲲鹏硬件特性与工具链能力,打造更高效、更适配的 HPC 应用。

鲲鹏开发工具-学习开发资源-鲲鹏社区:https://www.hikunpeng.com/developer?utm_campaign=com&utm_source=csdnkol

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1135965.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

救命神器 9款一键生成论文工具测评:继续教育论文写作全攻略

救命神器 9款一键生成论文工具测评&#xff1a;继续教育论文写作全攻略 2026年继续教育论文写作工具测评&#xff1a;高效创作的得力助手 在继续教育领域&#xff0c;论文写作不仅是提升专业能力的重要环节&#xff0c;更是职称评定、成果展示的关键环节。然而&#xff0c;面对…

双卧轴搅拌机与立轴行星式搅拌机哪种设备好?

在混凝土搅拌设备领域&#xff0c;双卧轴搅拌机与立轴行星式搅拌机犹如两颗并行的星辰&#xff0c;各自在特定场景中闪耀着独特光芒。二者并非简单的替代关系&#xff0c;而是通过差异化设计满足不同工程需求的互补型设备。小编将从技术原理、应用场景、维护成本三个维度展开分…

基于DWA的动态环境下多智能体自主避障路径优化附MATLAB代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1f34…

数字化SPC项目申报,看这个投资回报评估就够了...

之前的两篇文章中,我给大家分析了Excel和纸面SPC的种种问题,也介绍了数字化SPC的应用场景: 还在用Excel做SPC分析?你得看看这个…… 数字化SPC系统:七大应用场景,从“被动响应”到“主动预防”的转变 看完之后会有人觉得应该上一个数字化SPC系统,解决当前的燃眉之急。…

力扣hot100:每日温度

题目描述&#xff1a;思路分析&#xff08;单调栈&#xff09;这道题最优解是使用单调栈&#xff08;Monotonic Stack&#xff09;。核心思想&#xff1a;我们从左到右遍历每一天。用一个栈来维护一个从栈底到栈顶温度严格递减的索引序列&#xff08;即栈中保存的是还没有找到更…

直播云服务器安全防护有哪些常见的误区?

直播云服务器安全防护存在多个常见误区&#xff0c;这些错误观念可能导致严重的安全漏洞。以下是主要误区及正确做法&#xff1a;一、认为云服务器绝对安全&#xff0c;无需额外防护错误观念&#xff1a;许多用户认为云服务提供商已经提供了足够的安全措施&#xff0c;因此自己…

RenderDoc使用指南

最终情况&#xff1a; 参考文档&#xff1a; https://renderdoc.org/docs/getting_started/index.html 本文章简要介绍了使用RenderDoc进行应用程序捕获与分析的基本流程。内容不涉及具体的功能细节&#xff08;相关说明可在其他文档中查阅&#xff09;&#xff0c;而是重点阐述…

鲲鹏平台 HPC 高性能计算应用实践:矩阵乘法并行优化从入门到精通

一、写在前面 上一篇文章里&#xff0c;我们一起搭建了鲲鹏开发环境&#xff0c;装好了Visual Studio Code的鲲鹏DevKit插件&#xff0c;还实现了矩阵乘法的前两个版本&#xff1a;朴素实现&#xff08;0.26 GFLOPS&#xff09;和缓存优化版本&#xff08;1.22 GFLOPS&#xf…

直播云服务器安全防护有哪些最新的技术趋势?

直播云服务器安全防护正朝着智能化、零信任化、边缘化、区块链化四大方向演进&#xff0c;形成全方位的防御体系。一、AI智能风控与内容审核技术多模态AI审核成为核心趋势。通过CLIP、LLaVA等跨模态模型&#xff0c;系统能够同步分析文本、图像、音频、视频内容&#xff0c;实现…

【DOA估计】基于Wirtinger梯度的原子约束最大似然无网格DOA估计附Matlab复现含文献

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1…

基于工业设备的RS232引脚配置:操作指南

工业现场的RS232接线实战&#xff1a;别再被引脚搞晕了&#xff01; 你有没有遇到过这样的场景&#xff1f; 调试一台老式PLC&#xff0c;手握串口线却迟迟收不到数据&#xff1b; 连接HMI和条码枪&#xff0c;明明线插上了&#xff0c;但扫描结果就是传不进去&#xff1b; …

7. 自然语言处理NLP - Bert

1&#xff09;是什么 BERT Bidirectional Encoder Representations from Transformers 中文翻译&#xff1a;双向编码器表示&#xff0c;来自Transformer。 它是一个由 Google 在 2018 年提出的预训练语言模型&#xff0c;是 NLP 领域的“里程碑”式作品。你可以把它想象成一个…

2026.1.9

加密技术PKI&#xff08;公钥基础设施&#xff09;通过使用公钥技术和数字签名来确保信息安全PKI体系能够实现的功能身份验证数据完整性数据机密性操作的不可否认性对称加密&#xff1a;用相同的密钥进行加密和解密。不安全&#xff0c;但处理速度快非对称加密&#xff1a;使用…

Infineon TC3xx平台AUTOSAR OS任务调度机制全面讲解

深入剖析 Infineon TC3xx 上的 AUTOSAR OS 任务调度&#xff1a;从机制到实战在汽车电子系统日益复杂的今天&#xff0c;ECU&#xff08;电子控制单元&#xff09;早已不再是简单的“单片机代码”模式。动力总成、底盘控制、ADAS 等关键系统对实时性、确定性和功能安全的要求达…

数电实验3【译码器设计实验报告】数字电路 逻辑与计算机设计 logisim

目录 实验资源下载 实验报告 一、实验目的 二、实验环境 三、实验内容 四、实验步骤 五&#xff0c; 实验中遇到的问题 六&#xff0c; 心得 实验资源下载 点击下载 实验报告 一、实验目的 理解译码器的原理&#xff0c;使用logisim设计实现38译码器 二、实验环境…

C++(2)类与对象(上)

1.面向过程和面向对象初步认识C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间的交互完成。2.类…

USB2.0入门教程:枚举过程的核心要点解析

USB2.0枚举全解析&#xff1a;从插入到识别的底层真相你有没有遇到过这样的情况——把一个自制的USB设备插进电脑&#xff0c;系统却弹出“未知USB设备”的提示&#xff1f;或者设备反复断开重连&#xff0c;像在跟你玩捉迷藏&#xff1f;问题很可能出在一个你没怎么注意、但至…

【卫星】全球导航卫星系统信号处理、误差分析和定位的MATLAB 实现

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#x1f34…

Java中多线程异步调用

新启动一个或多个线程去完成所要完成的工作&#xff0c;主线程继续执行&#xff0c;互不干扰。异步场景&#xff1a;1、视频文件的格式转换&#xff08;比较耗时&#xff09;&#xff1b;2、一般都是耗时的步骤&#xff0c;使用一个新的线程去完成&#xff0c;主线程不受限制&a…

从传统到AI原生:用户画像技术的代际演进分析

从传统到AI原生&#xff1a;用户画像技术的代际演进分析关键词&#xff1a;用户画像、传统技术、AI原生、代际演进、个性化服务摘要&#xff1a;用户画像是互联网时代的“数字身份证”&#xff0c;从早期的手工标签到今天的AI自动生成&#xff0c;技术演进背后是数据、算法与需…