矩阵化检查
矩阵化检查功能用于对可矩阵化片段进行检查,并提供矩阵化修改建议。
简介
矩阵化检查工具包含Stencil、GEMV和FFT三个技术点的检查与优化。工具支持C/C++/Fortran源码的检查与优化,检查流程在AST(抽象语法树Abstract Syntax Tree的缩写)上进行。其中,C/C++源码使用Clang进行AST的生成,Fortran源码使用Fparser进行AST的生成,优化流程则与各计算模式强相关。三个技术点简介如下:
- Stencil计算是科学应用中的一类重要计算,被广泛应用于偏微分方程求解、高斯赛德尔方法、流体力学计算以及地球系统模拟等方面。Stencil计算描述了一种在大量时间步迭代下遍历结构化网格并按固定模式更新网格点的算法。结构化网格中的每个点根据其邻居子集进行更新的固定模式称为Stencil。
- GEMV是矩阵向量乘法(General Matrix-Vector multiplication)的缩写,是一种常用的线性代数运算,它可以被高度优化以利用现代计算机体系结构的并行性和向量化指令。在计算机科学中,GEMV通常用于矩阵乘法的一部分,即将一个矩阵与一个向量相乘。
- 快速傅里叶变换(Fast Fourier Transform),即利用计算机计算离散傅里叶变换(DFT)的高效、快速计算方法的统称,简称FFT。这种方法的优点是计算效率非常高,可以在O(nlogn)的时间复杂度内完成计算,其中n是序列的长度。同时,它还具有良好的灵活性,可以根据需要选择不同的分解方式和计算算法。
快速傅里叶变换优化的技术点是基于FFTW(Fastest Fourier Transform in the West)加速库实现优化的,在扫描中需要在待识别文件所在目录下添加对应的FFTW加速库头文件(fftw3.h、fftw3-mpi.h),这样才能够有对应优化建议结果。
C/C++支持以下12种领域优化技术,具体如表1所示。
领域优化技术 |
描述 |
|---|---|
数学恒等变换 |
通过乘方展开的方式,替换为乘法运算使能向量化。 |
精度一致除转乘 |
外提计算倒数,将除法转为同精度的乘法计算。 |
通信隐藏优化 |
识别到代码中阻塞性通信函数调用前后,与通信变量无关的代码片段,提示将该无关片段移至函数后,并将阻塞性通信函数修改为非阻塞性通信函数,以提高代码并行性。 |
截断半径判断消除 |
将循环中依赖于循环变量的条件分支语句替换为条件表达式,从而消减分支预测失败带来的惩罚。 |
迭代算查拆分 |
针对循环中的条件分支语句,在代码结构复杂时,难以直接使用截断半径判断消除进行优化的代码,给出一个将循环结构按照条件分支进行拆分的优化建议示例代码。 |
粒子作用力迭代流程优化 |
针对循环中的条件分支语句,引入临时数组保存条件分支成立的结果,将原循环改写成两个,并将条件判断移至前一个循环改写成三目条件运算,后一个循环基于临时数组中存放的结果继续处理。 |
分子间作用力迭代展开 |
识别典型的分子间作用力核函数计算,对循环迭代进行展开,提高指令并行度。 |
定长循环完全展开 |
对上下界确定的最内层循环,自动添加编译制导语句进行循环完全展开,节省循环分支开销。 |
邻接表聚合 |
将处于同一计算阈值范围内的粒子聚合在同一分组,进而可对同一分组的粒子采用同种计算方式,消除计算前对粒子距离的判断。 |
邻接粒子作用力计算向量化 |
通过移动、拷贝或定义临时数组操作对循环内的代码进行重写,并对向量化循环添加制导语句,指导编译器实现向量化。 |
默认OpenMP线程数优化 |
将函数声明处默认的OpenMP线程数优化为OpenMP默认最大可用的线程数,实现多线程加速。 |
SPMV向量化 |
对CSR格式的SPMV计算,自动向量化。 |
Fortran支持以下19种领域优化技术,具体如表2所示。
领域优化技术 |
描述 |
|---|---|
数学恒等变换 |
通过乘方展开的方式,替换为乘法运算使能向量化。 |
消除冗余公共算子 |
提取公共子序列,通过临时数组存储该公共计算,实现跨Block的公共子序列提取,消除冗余计算。 |
单位阶跃计算优化 |
将循环中的判断及赋值语句中的sign函数,转为阶跃函数(max/min/merge)调用,使能向量化。 |
精度一致除转乘 |
外提计算倒数,将除法转为同精度的乘法计算。 |
查找算法领域优化 |
识别出代码中实现查找功能的代码,替换为二分查找算法,提高查找算法性能。 |
超大数据降维优化 |
检查代码中定义n维的数组,但只使用了m(m<n)维数组,此时存在访存优化机会重新定义为m维数组。 |
通信隐藏优化 |
识别到代码中阻塞性通信函数调用前后,与通信变量无关的代码片段,提示将该无关片段移至函数后,并将阻塞性通信函数修改为非阻塞性通信函数,以提高代码并行性。 |
归约计算并行化 |
当循环内存在归约计算时,通过循环展开,减少变量对自身依赖,增加并行度。 |
制导语句优化 |
通过制导语句,指导编译器实现向量化和预取优化。 |
sin/cos算子融合 |
通过合并sin/cos计算,减少函数调用,实现性能加速。 |
exp计算化简 |
将多个exp函数的乘法计算替换为单个exp函数内的加法计算,减少对exp函数的调用,进而减少计算量,实现性能加速。 |
循环合并 |
通过合并相邻循环,减少循环开销,提高数据局部性,实现性能加速。 |
常量计算消除 |
将常量除法转换为等价的乘法计算,提高计算性能。 |
数组维度交换 |
交换多维数组的维度,优化数组的访存性能,实现性能加速。 |
循环交换访存优化 |
针对循环迭代顺序与数组维度不一致,导致的访存不连续问题,通过数据流分析,拆分迭代过程并交换顺序。 |
集合通信优化 |
自动检查源码中点对点通信数据流,优化为广播集合通信。 |
向量掩码计算优化 |
将具有掩码的向量语句自动优化为Max、Min、Merge语句。 |
随机数算法优化 |
将并行计算中同步随机数生成算法优化为异步随机数生成。 |
SPMV向量化 |
对CSR格式的SPMV计算,自动向量化。 |
命令功能
对可矩阵化片段进行检查。
命令格式
devkit advisor matrix-check [-h | --help] {-i INPUT_PATH | --input INPUT_PATH} [-s SCAN_DIR | --scan-dir SCAN_DIR] [-b {make,cmake} | --build-tool {make,cmake}] [-c COMMAND | --cmd COMMAND] [-j COMPILE_JSON_PATH | --compile-command-json COMPILE_JSON_PATH] [-o OUTPUT_PATH | --output OUTPUT_PATH] [-r {all,html,csv} | --report-type {all,html,csv}] {-p {sme,domain} | --optimization {sme,domain}} [-m {compute,memory_access,communication} | --module {compute,memory_access,communication}] [-f CONFIGURE_FILE | --configure-file CONFIGURE_FILE] [-l {0,1,2,3} | --log-level {0,1,2,3}][--set-timeout TIMEOUT]
参数说明
参数 |
参数选项 |
参数说明 |
|---|---|---|
-h/--help |
- |
可选参数,获取帮助信息。 |
-i/--input |
- |
必选参数,待扫描的源码文件夹绝对路径。 |
-s/--scan-dir |
- |
可选参数,源码文件夹下要扫描的文件或文件夹的相对路径,支持多路径,多路径之间用空格分隔。 |
-b/--build-tool |
make/cmake |
可选参数,构建工具,默认为make,-b和-j必须指定其中一个且不能同时指定。 |
-c/--cmd |
- |
可选参数,源码构建命令,默认为make。在服务器中正常执行的构建命令,若存在多个构建命令需使用英文分号分隔并用英文单引号或双引号包裹;命令中如有空格,也需要用英文单引号或双引号包裹。-c和-j二者必填一项且不能同时指定。 例如:"mkdir build;cd build;cmake ..;make"。 说明:
命令行工具源码构建命令不支持设置变量和export环境变量。 例如:"CFLAGS='-O0 -g';make"或"export CFLAGS='-O0 -g';make"。 |
-j/--compile-command-json |
- |
可选参数,指定compile_commands.json文件的所在路径,关于如何生成json文件请参见生成JSON文件。 -b/-c和-j二者必填一项且不能同时指定。 |
-o/--output |
- |
可选参数,扫描报告的存放路径,默认存放在当前执行路径下,报告名称为模块名称_时间戳。 |
-r/--report-type |
all/html/csv |
可选参数,扫描报告的格式,默认为all。
|
-p/--optimization |
sme/domain |
必选参数,指定矩阵化优化方法。
|
-m/--module |
compute/memory_access/communication |
可选参数,指定领域优化方法。
当矩阵化优化选择domain时,必须至少选择一个领域优化方法。 |
-f/--configure_file |
- |
可选参数,根据配置文件中指定的源码优化行号范围,生成对应的优化后文件。需使用绝对路径,具体格式请参见配置文件使用说明(-f/--configure_file)。 |
-l/--log-level |
0/1/2/3 |
可选参数,设置日志级别,默认为1。
|
--set-timeout |
- |
可选参数,任务超时时间,单位为分钟,若执行时间超过超时时间则退出执行。默认无超时时间,任务将持续执行直到结束。 |
使用示例
此处以扫描“/home/test_code/data”路径下SurfHop.f90源码,且构建工具为make,构建命令为make,矩阵化优化方式为SME矩阵化和领域优化为例,请根据实际情况进行修改。
1 | devkit advisor matrix-check -i /home/test_code/data -s SurfHop.f90 -c make -b make -o /home/out/ -p domain,sme -m compute,memory_access,communication |
返回信息如下,并输出报告。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | Executing matricization check task, please wait... Current progress: ################################# [100%] Scanned time: 2025/11/18 09:37:36 Configuration: Scan source code path: /home/test_code/data Generate report path: /home/out Generate report type: all Task Timeout Interval: The timeout period is not set. Log level: info Summary: Scanned 1 file, there are 9 suggestions. For the details information, please check: /home/out/matrix-check_20251118093736_116c.html /home/out/matrix-check_20251118093736_116c.csv The random_lib.f90 is in /home/out/matrix-check_20251118093736_116c |
配置文件使用说明(-f/--configure_file)
默认扫描完成后,工具会生成额外的优化文件。用户可通过配置JSON文件指定源码文件的行号,从而控制优化范围。
如下为示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | { "/home/demo/file1.c": [ [ 20, 30 ] ], "/home/demo/file2.c": [ [ 76, 81 ], [ 93, 105 ] ] } |
- /home/demo/file1.c:表示源码文件,需指定绝对路径。
- [20,30]:表示生成优化文件时,会保留当前行号范围内代码段的优化项。
输出报告说明
参数 |
说明 |
|---|---|
配置信息 |
显示软件源码文件存放路径。 |
需要修改的源码文件 |
显示存在矩阵化问题,并需要进行修改的源码文件路径等相关信息。 |