【开发者空间实践指导】使用鲲鹏BoostKit数学库优化程序性能

举报
开发者空间小蜜蜂 发表于 2025/01/07 16:41:43 2025/01/07
【摘要】 通过本实验,用户可以快速掌握鲲鹏数学库的安装与使用,并对所涉及的数学库性能表现有清晰认识。

一、案例介绍

鲲鹏数学库(KML, Kunpeng Math Library)是基于鲲鹏平台优化的高性能数学函数库,由多个子库组成,广泛应用于科学计算、HPC等领域。 本实验将以KML_VML和KML_BLAS为例,介绍鲲鹏数学库获取和编译,然后使用C语言编写demo进行性能测试查看KML优化前后的性能效果。通过本实验,用户可以快速掌握鲲鹏数学库的安装与使用,并对所涉及的数学库性能表现有清晰认识。

二、免费领取云主机

如您还没有云主机,可点击链接 ,根据领取指南进行操作。

如您已领取云主机,可直接开始实验。

三、实验流程

说明:

  1. 自动部署并连接鲲鹏服务器
  2. 安装数学库
  3. 修改环境变量
  4. 数学库性能测试

四、实验资源

本次实验预计花费总计0元。

资源名称

规格

单价(元)

时长(h

云主机

2vCPUs | 4GB RAM

免费

0.5

五、实验步骤

5.1 自动部署鲲鹏服务器

本实验中,使用云主机提供的鲲鹏沙箱资源,只需要执行简单的自动部署命令即可拉起一台免费的鲲鹏服务器。

在云主机桌面右键选择“Open Terminal Here”,打开终端命令窗口。

输入自动部署命令,命令如下:

hcd deploy --password abcd1234! --time 1800

命令的参数说明:

passwordpassword关键字后设置的是鲲鹏服务器的root用户密码,命令中给出的默认为abcd1234!开发者可以替换成自定义密码(至少8个字符)。

timetime关键字后面设置的为鲲鹏服务器的可用时间,单位为秒,至少600。当前实验预估需要20分钟,为了保证时间充足,在命令中申请的时间为30分钟1800

记录下自动部署后生成的弹性公网IP地址。

5.2 安装数学库

使用命令登录到鲲鹏服务器,命令如下:

ssh root@鲲鹏服务器公网IP

输入密码,密码为步骤2.1中自动部署命令行中“--password”后面的参数,命令中给出的默认为abcd1234!,如果没有修改,就使用abcd1234!进行登录,如果设置了自定义密码,直接输入自定义的密码(注意:输入过程中密码不会显示,密码输入完成按回车键结束)。

使用命令下载数学库软件包,本次案例使用的是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

解压软件包。

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文件

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

5.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' >> /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib:$LD_LIBRARY_PATH' >> /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kblas/nolocking:$LD_LIBRARY_PATH' >> /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kblas/omp:$LD_LIBRARY_PATH' >> /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kblas/pthread:$LD_LIBRARY_PATH' >> /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kvml/multi:$LD_LIBRARY_PATH' >> /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kvml/single:$LD_LIBRARY_PATH' >> /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kspblas/multi:$LD_LIBRARY_PATH' >> /etc/profile
echo 'export LD_LIBRARY_PATH=/usr/local/kml/lib/kspblas/single:$LD_LIBRARY_PATH' >> /etc/profile

执行命令使环境生效。

source /etc/profile

检查环境变量。

env | grep LD_LIBRARY_PATH

5.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

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

./test

结果显示,对于一个长度为100000的数组,用C语言的for循环实现求正弦函数值,需要6666微秒,而使用KML_VML仅需要779微秒,性能提升8倍。

2. KML_BLAS测试

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

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

vi test_gemv.c

进入到vim编辑器界面后,按下“i”键后,复制以下代码粘贴到编辑器中,复制完成后按下“ESC”键输入“:wq”,退出编辑器界面,该段代码主要功能是:初始化规模为1000*300的矩阵A,长度为300的向量x,长度为1000的向量y1和y2,分别用计时器对按照矩阵-向量的成家规则实现算法求解,即y=alpha*A*x+beta*y,以及调用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

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

./test2

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

至此,本次实验全部完成。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

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

全部回复

上滑加载中

设置昵称

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

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

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