当前位置: 首页 > news >正文

PolyBench基准程序详解:编译器优化评测指标

PolyBench基准程序详解:编译器优化评测指标

PolyBench基本概念

PolyBench(Polyhedral Benchmark)是由UCLA(加州大学洛杉矶分校)的Louis-Noël Pouchet及其研究团队开发的基准测试套件,专门用于评估多面体编译技术和循环优化效果。该套件位于 ucla.edu/pouchet/software/polybench,提供了一组标准化的计算密集型内核,这些内核包含嵌套循环和规则的数组访问模式,非常适合应用多面体编译技术进行优化。

PolyBench的核心价值在于提供小而精的基准程序,这些程序能够代表科学计算、线性代数和数据处理领域中常见的计算模式。通过这些基准程序,研究人员可以评估编译器优化技术、硬件性能和并行化策略的效果。

引言

看论文傻傻不懂指标,2nm?3nm?什么鬼? 本文详解
在这里插入图片描述
在这里插入图片描述
GPU测试速度参考,A100 ,400w, 数据来源
在这里插入图片描述

重点基准程序详解

本文将重点介绍几个关键的PolyBench基准程序:2MM、3MM、ATAX、BICG、GEMM、GESUMMV、MVT、SPAM-FILTER和DOITGEN。这些程序代表了线性代数和数据挖掘领域中的典型计算模式,是评估编译器优化和硬件性能的重要指标。

基准程序计算模式关键优化点应用领域
2MM D = α ⋅ A × B × C + β ⋅ D D = \alpha \cdot A \times B \times C + \beta \cdot D D=αA×B×C+βD循环平铺、循环交换、向量化、并行化数值模拟、物理模拟、图像处理、机器学习
3MM G = ( A × B ) × ( C × D ) G = (A \times B) \times (C \times D) G=(A×B)×(C×D)多级循环平铺、中间结果缓存、多级并行化气象模拟、流体动力学、复杂物理系统模拟、高级图形渲染
ATAX y = A T × ( A × x ) y = A^T \times (A \times x) y=AT×(A×x)循环融合、向量化、缓存阻塞、数据布局优化数字信号处理、图像处理、特征转换、线性变换
BICG q = A × p q = A \times p q=A×p, s = A T × r s = A^T \times r s=AT×r循环交换、向量化、并行化、缓存阻塞稀疏矩阵求解、计算机图形学、有限元分析、线性系统求解
GEMM C = α ⋅ A × B + β ⋅ C C = \alpha \cdot A \times B + \beta \cdot C C=αA×B+βC循环平铺、循环展开、向量化、并行化、BLAS库机器学习、图像处理、数值模拟、科学计算
GESUMMV y = α ⋅ A × x + β ⋅ B × x y = \alpha \cdot A \times x + \beta \cdot B \times x y=αA×x+βB×x循环融合、向量化、预取、数据布局优化数据压缩、图像滤波、数字信号处理、线性变换组合
MVT x 1 = A × y 1 x1 = A \times y1 x1=A×y1, x 2 = A T × y 2 x2 = A^T \times y2 x2=AT×y2循环融合、向量化、缓存阻塞、数据布局优化数据分析、科学模拟、线性系统求解、特征提取
DOITGEN A [ r ] [ q ] [ s ] = ∑ p = 0 N P − 1 A [ r ] [ q ] [ p ] × C 4 [ p ] [ s ] A[r][q][s] = \sum_{p=0}^{NP-1} A[r][q][p] \times C4[p][s] A[r][q][s]=p=0NP1A[r][q][p]×C4[p][s]多维循环平铺、多级缓存优化、向量化、数据布局转换信号处理、图像压缩、多分辨率分析、张量操作

1. 2MM(Two Matrix Multiplications)

计算模式:
2MM实现了两次矩阵乘法运算的序列,表示为:
D = α ⋅ A × B × C + β ⋅ D D = \alpha \cdot A \times B \times C + \beta \cdot D D=αA×B×C+βD

这可以分解为两步:

  1. 计算临时矩阵: E = A × B E = A \times B E=A×B
  2. 计算最终结果: D = α ⋅ E × C + β ⋅ D D = \alpha \cdot E \times C + \beta \cdot D D=αE×C+βD

核心代码结构:

/* 第一次矩阵乘法:E = A*B */
for (i = 0; i < ni; i++) {
  for (j = 0; j < nj; j++) {
    E[i][j] = 0;
    for (k = 0; k < nk; k++) {
      E[i][j] += A[i][k] * B[k][j];
    }
  }
}

/* 第二次矩阵乘法:D = alpha*E*C + beta*D */
for (i = 0; i < ni; i++) {
  for (j = 0; j < nl; j++) {
    D[i][j] *= beta;
    for (k = 0; k < nj; k++) {
      D[i][j] += alpha * E[i][k] * C[k][j];
    }
  }
}

优化空间:

  • 循环平铺以提高缓存利用率
  • 循环交换以优化内存访问模式
  • 向量化内部循环以利用SIMD指令
  • 并行化外部循环以利用多核处理器

应用领域:

  • 数值模拟
  • 物理模拟
  • 图像处理
  • 机器学习中的复合矩阵运算

2. 3MM(Three Matrix Multiplications)

计算模式:
3MM实现了三次矩阵乘法运算的序列,计算:
G = ( A × B ) × ( C × D ) G = (A \times B) \times (C \times D) G=(A×B)×(C×D)

这可以分解为三步:

  1. 计算 E = A × B E = A \times B E=A×B
  2. 计算 F = C × D F = C \times D F=C×D
  3. 计算 G = E × F G = E \times F G=E×F

核心代码结构:

/* 第一次矩阵乘法:E = A*B */
for (i = 0; i < ni; i++) {
  for (j = 0; j < nj; j++) {
    E[i][j] = 0;
    for (k = 0; k < nk; k++) {
      E[i][j] += A[i][k] * B[k][j];
    }
  }
}

/* 第二次矩阵乘法:F = C*D */
for (i = 0; i < nj; i++) {
  for (j = 0; j < nl; j++) {
    F[i][j] = 0;
    for (k = 0; k < nm; k++) {
      F[i][j] += C[i][k] * D[k][j];
    }
  }
}

/* 第三次矩阵乘法:G = E*F */
for (i = 0; i < ni; i++) {
  for (j = 0; j < nl; j++) {
    G[i][j] = 0;
    for (k = 0; k < nj; k++) {
      G[i][j] += E[i][k] * F[k][j];
    }
  }
}

优化空间:

  • 多级循环平铺
  • 中间结果的缓存优化
  • 多级并行化(任务级和数据级)
  • 矩阵乘法算法的选择(如Strassen算法)

应用领域:

  • 气象模拟
  • 流体动力学
  • 复杂物理系统模拟
  • 高级图形渲染

3. ATAX(Matrix Transpose and Vector Multiplication)

计算模式:
ATAX计算矩阵转置与向量乘积:
y = A T × ( A × x ) y = A^T \times (A \times x) y=AT×(A×x)

这可以分解为两步:

  1. 计算 t m p = A × x tmp = A \times x tmp=A×x
  2. 计算 y = A T × t m p y = A^T \times tmp y=AT×tmp

核心代码结构:

/* 初始化输出向量 */
for (i = 0; i < ny; i++)
  y[i] = 0;

/* 计算 y = A^T * (A * x) */
for (i = 0; i < nx; i++) {
  tmp[i] = 0;
  for (j = 0; j < ny; j++)
    tmp[i] += A[i][j] * x[j];
    
  for (j = 0; j < ny; j++)
    y[j] += A[i][j] * tmp[i];
}

优化空间:

  • 循环融合以减少临时存储和提高数据局部性
  • 向量化内部循环
  • 缓存阻塞以优化大矩阵的处理
  • 数据布局优化以提高空间局部性

应用领域:

  • 数字信号处理
  • 图像处理
  • 机器学习中的特征转换
  • 科学计算中的线性变换

4. BICG(BiConjugate Gradient Method Kernel)

计算模式:
BICG实现了双共轭梯度法的子内核,计算:
q = A × p q = A \times p q=A×p
s = A T × r s = A^T \times r s=AT×r

核心代码结构:

/* 初始化输出向量 */
for (i = 0; i < m; i++)
  s[i] = 0;
for (i = 0; i < n; i++)
  q[i] = 0;

/* 计算 q = A*p 和 s = A^T*r */
for (i = 0; i < m; i++) {
  for (j = 0; j < n; j++) {
    s[i] += A[i][j] * r[j];
    q[j] += A[i][j] * p[i];
  }
}

优化空间:

  • 循环交换以优化内存访问模式
  • 向量化和并行化
  • 缓存阻塞以处理大矩阵
  • 数据布局优化以减少缓存未命中

应用领域:

  • 稀疏矩阵求解
  • 计算机图形学
  • 有限元分析
  • 大规模线性系统求解

5. GEMM(General Matrix Multiplication)

计算模式:
GEMM实现了通用矩阵乘法:
C = α ⋅ A × B + β ⋅ C C = \alpha \cdot A \times B + \beta \cdot C C=αA×B+βC

核心代码结构:

/* 计算 C = alpha*A*B + beta*C */
for (i = 0; i < ni; i++) {
  for (j = 0; j < nj; j++) {
    C[i][j] *= beta;
    for (k = 0; k < nk; k++) {
      C[i][j] += alpha * A[i][k] * B[k][j];
    }
  }
}

优化空间:

  • 循环平铺和缓存阻塞
  • 循环展开以减少循环开销
  • 向量化和并行化
  • 专用矩阵乘法算法(如BLAS库)

应用领域:

  • 机器学习(尤其是深度神经网络)
  • 图像处理
  • 数值模拟
  • 几乎所有科学计算领域

GEMM是线性代数中最基础也是最重要的操作之一,是评估编译器性能的关键指标。它直接影响到许多科学计算和机器学习应用的性能。GEMM也是BLAS(基础线性代数子程序)库的核心,是优化库和硬件加速器的主要目标。

6. GESUMMV(Scalar, Vector and Matrix Multiplication)

计算模式:
GESUMMV计算两个矩阵-向量乘积的加权和:
y = α ⋅ A × x + β ⋅ B × x y = \alpha \cdot A \times x + \beta \cdot B \times x y=αA×x+βB×x

核心代码结构:

/* 计算 y = alpha*A*x + beta*B*x */
for (i = 0; i < n; i++) {
  tmp[i] = 0;
  y[i] = 0;
  for (j = 0; j < n; j++) {
    tmp[i] += A[i][j] * x[j];
    y[i] += B[i][j] * x[j];
  }
  y[i] = alpha * tmp[i] + beta * y[i];
}

优化空间:

  • 循环融合以提高数据局部性
  • 向量化内部循环
  • 预取以减少内存延迟
  • 数据布局优化以提高缓存命中率

应用领域:

  • 数据压缩
  • 图像滤波
  • 数字信号处理
  • 线性变换组合

7. MVT(Matrix Vector Product and Transpose)

计算模式:
MVT计算两个矩阵-向量乘积:
x 1 = A × y 1 x1 = A \times y1 x1=A×y1
x 2 = A T × y 2 x2 = A^T \times y2 x2=AT×y2

核心代码结构:

/* 计算 x1 = A*y1 */
for (i = 0; i < n; i++) {
  for (j = 0; j < n; j++) {
    x1[i] += A[i][j] * y1[j];
  }
}

/* 计算 x2 = A^T*y2 */
for (i = 0; i < n; i++) {
  for (j = 0; j < n; j++) {
    x2[i] += A[j][i] * y2[j];
  }
}

优化空间:

  • 循环融合以提高数据重用
  • 向量化内部循环
  • 缓存阻塞以处理大矩阵
  • 数据布局优化以提高转置操作的效率

应用领域:

  • 数据分析
  • 科学模拟
  • 线性系统求解
  • 特征提取

9. DOITGEN(Multi-resolution Analysis Kernel)

计算模式:
DOITGEN实现了多分辨率分析内核,涉及多维数组操作:
A [ r ] [ q ] [ s ] = ∑ p = 0 N P − 1 A [ r ] [ q ] [ p ] × C 4 [ p ] [ s ] A[r][q][s] = \sum_{p=0}^{NP-1} A[r][q][p] \times C4[p][s] A[r][q][s]=p=0NP1A[r][q][p]×C4[p][s]

核心代码结构:

/* 多维数组操作 */
for (r = 0; r < nr; r++) {
  for (q = 0; q < nq; q++) {
    for (p = 0; p < np; p++) {
      sum[p] = 0;
      for (s = 0; s < np; s++) {
        sum[p] += A[r][q][s] * C4[s][p];
      }
    }
    for (p = 0; p < np; p++) {
      A[r][q][p] = sum[p];
    }
  }
}

优化空间:

  • 多维循环平铺
  • 多级缓存优化
  • 向量化内部循环
  • 数据布局转换以提高多维数组访问效率

应用领域:

  • 信号处理
  • 图像压缩
  • 多分辨率分析
  • 科学计算中的张量操作

MLIR中的表示与优化

MLIR(Multi-Level Intermediate Representation)提供了强大的框架来表示和优化上述PolyBench基准程序。以下是如何在MLIR中表示和优化这些基准程序的示例:

1. 高级表示(Linalg Dialect)

以GEMM为例,在Linalg Dialect中的表示:

// C = alpha*A*B + beta*C
%result = linalg.generic {
  indexing_maps = [
    affine_map<(i, j, k) -> (i, k)>,  // A
    affine_map<(i, j, k) -> (k, j)>,  // B
    affine_map<(i, j, k) -> (i, j)>   // C
  ],
  iterator_types = ["parallel", "parallel", "reduction"]
} ins(%A, %B, %alpha, %beta : tensor<ni x nk x f32>, tensor<nk x nj x f32>, f32, f32) 
  outs(%C : tensor<ni x nj x f32>) {
  ^bb0(%a: f32, %b: f32, %alpha: f32, %beta: f32, %c: f32):
    %scaled_c = arith.mulf %c, %beta : f32
    %a_scaled = arith.mulf %a, %alpha : f32
    %ab = arith.mulf %a_scaled, %b : f32
    %result = arith.addf %scaled_c, %ab : f32
    linalg.yield %result : f32
}

Linalg Dialect对结构化数据进行结构化处理的通用表示,具有以下特点:

  • 既可以将tensor作为操作数,也可以将buffer作为操作数
  • 包含payload操作(执行具体运算)和struct操作(表示如何进行运算)
  • 在实际应用中,外部Dialect很多情况下会先转换到Linalg Dialect再执行后续优化

2. 仿射表示(Affine Dialect)

对于2MM,在Affine Dialect中的表示:

// 第一次矩阵乘法:E = A*B
affine.for %i = 0 to %ni {
  affine.for %j = 0 to %nj {
    %init = constant 0.0 : f32
    %sum = affine.for %k = 0 to %nk iter_args(%sum_iter = %init) -> f32 {
      %a = affine.load %A[%i, %k] : memref<ni x nk x f32>
      %b = affine.load %B[%k, %j] : memref<nk x nj x f32>
      %prod = arith.mulf %a, %b : f32
      %next = arith.addf %sum_iter, %prod : f32
      affine.yield %next : f32
    }
    affine.store %sum, %E[%i, %j] : memref<ni x nj x f32>
  }
}

Affine Dialect对多面体编译(polyhedral compilation)的实现,其主要特点:

  • 包含多维数据结构的控制流操作
  • 支持多维数据的循环和条件控制,存储映射操作等
  • 目标是实现多面体变换,如自动并行化、循环融合和平铺等
  • 使用仿射表达式描述循环边界和内存访问模式

3. 向量化表示(Vector Dialect)

Vector Dialect提供了对SIMD(单指令多数据)或SIMT(单指令多线程)模型的抽象:

// 对ATAX内部循环向量化
affine.for %i = 0 to %nx {
  %tmp_init = constant 0.0 : f32
  affine.store %tmp_init, %tmp[%i] : memref<nx x f32>
  
  // 向量化内部循环
  %tmp_val = affine.vector.load %tmp[%i] : memref<nx x f32>, vector<4xf32>
  %vec_sum = affine.for %j_unroll = 0 to %ny step 4 iter_args(%vec_acc = %tmp_val) -> vector<4xf32> {
    %x_vec = vector.load %x[%j_unroll] : memref<ny x f32>, vector<4xf32>
    %a_vec = affine.vector.load %A[%i, %j_unroll] : memref<nx x ny x f32>, vector<4xf32>
    %prod = arith.mulf %a_vec, %x_vec : vector<4xf32>
    %sum_vec = arith.addf %vec_acc, %prod : vector<4xf32>
    affine.yield %sum_vec : vector<4xf32>
  }
  
  // 存储结果
  affine.vector.store %vec_sum, %tmp[%i] : memref<nx x f32>, vector<4xf32>
}

Vector Dialect的特点:

  • 作为向量的中间表示,可以被转换到不同目标平台的底层表示
  • 实现Tensor在不同平台的支持
  • 包含向量化操作,如向量加载/存储、向量计算等

4. 结构化控制流(SCF Dialect)

SCF(Structured Control Flow)Dialect提供了比控制流图CFG更高层的抽象:

// 使用SCF表示GEMM
scf.for %i = %c0 to %ni step %c1 {
  scf.for %j = %c0 to %nj step %c1 {
    // 加载并缩放C
    %c_val = memref.load %C[%i, %j] : memref<ni x nj x f32>
    %c_scaled = arith.mulf %c_val, %beta : f32
    memref.store %c_scaled, %C[%i, %j] : memref<ni x nj x f32>
    
    // 计算矩阵乘法
    scf.for %k = %c0 to %nk step %c1 {
      %a_val = memref.load %A[%i, %k] : memref<ni x nk x f32>
      %b_val = memref.load %B[%k, %j] : memref<nk x nj x f32>
      %ab = arith.mulf %a_val, %b_val : f32
      %ab_scaled = arith.mulf %ab, %alpha : f32
      
      %c_current = memref.load %C[%i, %j] : memref<ni x nj x f32>
      %c_new = arith.addf %c_current, %ab_scaled : f32
      memref.store %c_new, %C[%i, %j] : memref<ni x nj x f32>
    }
  }
}

SCF Dialect的特点:

  • 提供结构化控制流操作,如并行的for和while循环以及条件判断
  • 通常Affine和Linalg会降低到SCF
  • SCF也可以降低为更底层的控制流表示

相关文章:

  • IDEA 出现 Cannot access aliyunmaven in offline mode 问题解决方案
  • 【愚公系列】《高效使用DeepSeek》020-专业术语解释
  • 脚本语言 Lua
  • K8S学习之基础四十:K8S配置altermanager发送告警到钉钉群
  • 在麒麟系统(基于Ubuntu或Debuntu)的离线环境中创建本地APT仓库
  • 基于django美团美食销售数据分析与可视化系统设计与实现(源码+lw+部署文档+讲解),源码可白嫖!
  • Redis 本地安装
  • 【Kafka】深入了解Kafka
  • 【文章写作】以数字素养筑基,绘治理现代化蓝图
  • CSS 用于图片的样式属性
  • STM32-汇编2、外设
  • EasyRTC嵌入式音视频通话SDK:微信生态支持、轻量化架构与跨平台兼容性(Linix/Windows/ARM/Android/iOS/LiteOS)
  • HarmonyOS 开发中条件渲染的选择:if/else 与取反操作的对比与实践
  • Chapter 4-16. Troubleshooting Congestion in Fibre Channel Fabrics
  • AcWing 838:堆排序 ← 数组模拟
  • (C语言)递归求整数的二进制(递归求法)(C语言教学)
  • VSCode创建VUE项目(三)使用axios调用后台服务
  • Android自动化测试终极指南:从单元到性能全覆盖!
  • [免费]SpringBoot+Vue城市交通管理系统【论文+源码+SQL脚本】
  • Visual Studio调试的技巧
  • 京东美团饿了么等外卖平台被约谈
  • 杭州钱塘区3宗涉宅用地均以底价成交,共计成交金额25.73亿元
  • 石家庄推动城市能级与民生福祉并进
  • 湖北石首市委副书记、市长付勇接受审查调查
  • 巴西总统卢拉昨晚抵达北京
  • 时代中国控股:前4个月销售额18.1亿元,境外债重组协议押后聆讯至5月底