使用鲲鹏BoostKit数学库优化程序性能

举报
yd_248943075 发表于 2026/01/07 16:36:08 2026/01/07
【摘要】 本案例将以KML_VML和KML_BLAS为例,介绍鲲鹏数学库获取和编译,然后使用C语言编写demo进行性能测试查看KML优化前后的性能效果。一、概述1. 案例介绍鲲鹏数学库(KML, Kunpeng Math Library)是基于鲲鹏平台优化的高性能数学函数库,由多个子库组成,广泛应用于科学计算、HPC等领域。 通过本案例,用户可以快速掌握鲲鹏数学库的安装与使用,并对所涉及的数学库性能表...
本案例将以KML_VML和KML_BLAS为例,介绍鲲鹏数学库获取和编译,然后使用C语言编写demo进行性能测试查看KML优化前后的性能效果。

一、概述

1. 案例介绍

鲲鹏数学库(KML, Kunpeng Math Library)是基于鲲鹏平台优化的高性能数学函数库,由多个子库组成,广泛应用于科学计算、HPC等领域。 通过本案例,用户可以快速掌握鲲鹏数学库的安装与使用,并对所涉及的数学库性能表现有清晰认识。

4. 案例流程


1.JPG

二、操作步骤

1. 云开发环境准备

登录华为开发者空间,点击开发平台 > 云开发环境 > 开发桌面,点击创建按钮,创建开发环境:

2. 安装数学库

打开Terminal,执行以下命令下载数学库软件包,本次案例使用的是1.7.0版本。

wget https://repo.oepkgs.net/openeuler/rpm/openEuler-20.03-LTS-SP3/extras/aarch64/Packages/b/boostkit-kml-1.7.0-1.aarch64.rpm

2.JPG

解压软件包:

rpm2cpio boostkit-kml-1.7.0-1.aarch64.rpm | cpio -div

添加软链接,使用ln -s命令创建软链接,类似于Windows中的快捷方式,它是一个特殊的文件,其内容是指向另一个文件或者目录的路径,当访问软链接时,系统会根据软链接中的路径找到实际指向的目标文件或目录来进行操作。

下面三组命令分别创建了libkspblas.so、libkvml.so和libkm.so三个软链接,分别指向根据find命令找到对应实际的kspblas.so、kvml.so和km.so文件。

sudo cp -R ./usr/local/kml/ /usr/local/
sudo cd /usr/local/kml
sudo ln -s 'find ./ -name *kspblas.so* -type f' ./libkspblas.so
sudo ln -s 'find ./ -name *kvml.so* -type f' ./libkvml.so
sudo ln -s 'find ./ -name *km.so* -type f' ./libkm.so

3.JPG


3. 修改环境变量

在 Linux 系统中,LD_LIBRARY_PATH是一个重要的环境变量,它用于指定动态链接库(.so文件)的搜索路径。当程序在运行时需要加载动态链接库,系统会首先在默认的系统库路径中查找,然后会按照LD_LIBRARY_PATH环境变量所指定的路径顺序进行查找。

将多个与/usr/local/kml相关的库目录添加到LD_LIBRARY_PATH环境变量中,是因为程序依赖于这些目录下的动态链接库来正确运行。通过将这些目录添加到LD_LIBRARY_PATH,可以确保程序在运行时能够找到所需的库文件。

echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kblas/locking:$LD_LIBRARY_PATH' | sudo tee -a /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib:$LD_LIBRARY_PATH' | sudo tee -a /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kblas/nolocking:$LD_LIBRARY_PATH' | sudo tee -a /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kblas/omp:$LD_LIBRARY_PATH' | sudo tee -a /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kblas/pthread:$LD_LIBRARY_PATH' | sudo tee -a /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kvml/multi:$LD_LIBRARY_PATH' | sudo tee -a /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kvml/single:$LD_LIBRARY_PATH' | sudo tee -a /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kspblas/multi:$LD_LIBRARY_PATH' | sudo tee -a /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kspblas/single:$LD_LIBRARY_PATH' | sudo tee -a /etc/profile

执行命令使环境生效。

source /etc/profile

4. 数学库性能测试

4.1 KML_VML测试

矢量数学库(Vector Math Library)借助计算密集型核心数学函数(幂函数、三角函数、指数函数、双曲函数、对数函数等)的矢量实施显著提升应用速度。

使用命令创建测试文件test_sin.c文件。

cd
vi test_sin.c

进入到vim编辑器界面后,按下“i”键后,复制以下代码粘贴到编辑器中,复制完成后按下“ESC”键输入“:wq”,退出编辑器界面,该段代码主要功能是:初始化长度为100000的向量src,分别用计时器对循环使用系统函数库的sin函数求解以及调用KML_VML提供的向量三角函数vdsin求解,记录两种方法的耗时,对比KML_VML与系统函数库的性能。

#include <stdio.h>
#include <sys/time.h>
#include <math.h>
#include "kvml.h"
#define LEN 100000
int main()
{
        double src[LEN] = {0};
        double dst1[LEN] = {0};
        double dst2[LEN] = {0};
        for(int i = 0; i < LEN; i++){
                src[i] = i;
        }
        struct timeval start, end;
        long t;
gettimeofday(&start, NULL);
        for(int i = 0; i < LEN; i++){
                dst1[i] = sin(src[i]);
        }
gettimeofday(&end, NULL);
        t = 100000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
        printf("Calculate Time without KML_VML: %ld us \n", t);
gettimeofday(&start, NULL);
        vdsin(LEN, src, dst2);
        gettimeofday(&end, NULL);
        t = 100000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
        printf("Calculate Time with KML_VML: %ld us \n", t);

        return 0;
}

编译文件, 编译时添加动态库和头文件所在路径,并链接系统数学库和KML_VML动态库。

gcc test_sin.c -o test -L/usr/local/kml/lib/kvml/single -lkvml -lm -I/usr/local/kml/include -fopenmp -std=c99

使用ldd指令检查程序依赖库是否准确链接。

ldd test

5.JPG


执行可执行文件,进行性能对比。

./test

结果显示,对于一个长度为100000的数组,用C语言的for循环实现求正弦函数值,需要2712微秒,而使用KML_VML仅需要828微秒。

6.JPG


4.2 KML_BLAS测试

BLAS(Basic Linear Algebra Subprograms)提供了一系列基本线性代数运算函数的标准接口,包括矢量线性组合、矩阵乘以矢量、矩阵乘以矩阵等功能。BLAS已被广泛的应用于工业界和科学计算,成为业界标准。KML_BLAS库提供BLAS函数的C语言接口。

使用命令创建测试文件test_gemv.c文件。

vi test_gemv.c

进入到vim编辑器界面后,按下“i”键后,复制以下代码粘贴到编辑器中,复制完成后按下“ESC”键输入“:wq”,退出编辑器界面,该段代码主要功能是:初始化规模为1000300的矩阵A,长度为300的向量x,长度为1000的向量y1和y2,分别用计时器对按照矩阵-向量的成家规则实现算法求解,即y=alphaAx+betay,以及调用KML_BLAS提供的函数cblas_dgemv求解,记录两种方法的耗时,对比KML_BLAS与手动实现矩阵乘加的性能。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include "kblas.h"  
#define M 1000
#define N 300
int main() {
    double alpha = 1.0;
    double beta = 1.0;
    double (*A)[N] = (double (*)[N])malloc(M * N * sizeof(double));
    double *x = (double *)malloc(N * sizeof(double));
    double *y1 = (double *)malloc(M * sizeof(double));
    double *y2 = (double *)malloc(M * sizeof(double));
    srand((unsigned int)time(NULL));
    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
            A[i][j] = (double)rand() / RAND_MAX;
        }
    }
    for (int i = 0; i < N; i++) {
        x[i] = (double)rand() / RAND_MAX;
    }
    for (int i = 0; i < M; i++) {
        y1[i] = (double)rand() / RAND_MAX;
        y2[i] = (double)rand() / RAND_MAX;
    }
    // 方法一:按照矩阵-向量的乘加规则实现算法求解
    struct timeval start, end;
    long t;
gettimeofday(&start, NULL);
    for (int i = 0; i < M; i++) {
        double sum = 0.0;
        for (int j = 0; j < N; j++) {
            sum += A[i][j] * x[j];
        }
        y1[i] = alpha * sum + beta * y1[i];
    }
gettimeofday(&end, NULL);
        t = 100000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
        printf("Calculate Time without KML_BLAS: %ld us \n", t);
    // 方法二:调用KML_BLAS提供的函数cblas_dgemv求解
gettimeofday(&start, NULL);
    cblas_dgemv(CblasRowMajor, CblasNoTrans, M, N, alpha, (const double *)A, N, x, 1, beta, y2, 1);
    gettimeofday(&end, NULL);
    t = 100000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
    printf("Calculate Time with KML_BLAS: %ld us \n", t);

    return 0;
}

编译文件,编译时添加动态库和头文件所在路径,并链接KML_BLAS动态库。

gcc test_gemv.c -g -o test2 -L /usr/local/kml/lib/kblas/locking/ -lkblas -I /usr/local/kml/include -std=c99

使用ldd指令检查程序依赖库是否准确链接。

ldd test2

7.JPG


执行可执行文件,进行性能对比。

./test2

结果显示,计算一个1000*300的矩阵-向量乘加运算,用C语言的for循环实现,需要1653微秒,而使用KML_BLAS仅需要187微秒,性能提升将近8倍。

8.JPG



【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。