Skip to content

性能分析

基准测试方法论

测试环境

组件规格
GPUNVIDIA RTX 3090 (Ampere, SM 8.6)
理论带宽936 GB/s
CUDA 版本12.0
CPUAMD Ryzen 9 5900X
操作系统Ubuntu 22.04 LTS

指标

  • 执行时间: 10 次预热后的 100 次运行中位数
  • 有效带宽: (读取字节数 + 写入字节数) / 时间
  • 利用率: 有效带宽 / 理论带宽

矩阵测试集

矩阵类型描述生成方法
对角矩阵仅对角线有非零元合成
均匀矩阵随机均匀分布sprand(n, n, density)
幂律矩阵无标度分布sprand(n, n, density, 'power')
带状矩阵带状结构合成
真实矩阵SuiteSparse 矩阵下载

内核性能对比

按矩阵模式

模式大小非零元ScalarVectorMergeELL
对角矩阵100K100K37.2%69.1%72.4%74.8%
均匀矩阵100K5M41.5%71.8%70.9%82.3%
幂律矩阵100K5M32.1%45.6%69.2%34.7%
带状矩阵100K5M28.4%64.9%58.1%41.2%

关键发现:

  1. ELL 在均匀矩阵上表现最佳 (82.3%),因为内存访问完全合并
  2. Merge Path 对不规则模式最稳健,跨多种稀疏模式保持高性能
  3. Scalar CSR 仅适用于非常稀疏的矩阵

性能可视化

均匀矩阵 (100K × 100K)
ELL 内核
82.3%
Vector CSR
71.8%
Merge Path
70.9%
Scalar CSR
41.5%
幂律矩阵 (100K × 100K)
Merge Path
69.2%
Vector CSR
45.6%
ELL 内核
34.7%
Scalar CSR
32.1%

按矩阵规模

规模非零元ScalarVectorMergeELL
10K × 10K500K42.1%70.2%68.5%78.3%
100K × 100K5M36.7%68.7%71.5%73.7%
1M × 1M50M34.8%65.5%70.8%71.2%
10M × 10M500M33.2%62.1%69.4%68.9%

扩展性分析:

  • 所有内核在大规模矩阵上保持 >60% 利用率
  • Vector CSR 在 10M 规模略有下降(L2 缓存压力)
  • Merge Path 保持一致的性能表现

内核选择准确率

自动选择算法在 95%+ 的情况下实现最优或接近最优的选择:

各模式选择准确率

模式正确选择率相对最优性能
对角矩阵98%99.2%
均匀矩阵96%98.5%
幂律矩阵94%97.1%
混合模式92%96.3%

内存访问分析

合并访问效率

内核平均每事务线程数效率
Scalar CSR1.2
Vector CSR8.4
Merge Path12.1
ELL 内核16.0完美

L2 缓存命中率

内核命中率说明
Scalar CSR45%局部性差
Vector CSR72%中等重用
Merge Path68%均衡
ELL 内核85%优秀的局部性

与参考实现对比

vs. cuSPARSE

矩阵GPU SpMVcuSPARSE加速比
均匀 100K71.5%68.2%1.05×
幂律 100K69.2%52.1%1.33×
真实矩阵 (webbase)67.8%61.4%1.10×

优势:

  • 不规则矩阵性能更优(Merge Path 算法)
  • 自动内核选择(无需手动调优)
  • 开源代码(完全透明)

vs. 通用 SpMV

矩阵GPU SpMV通用实现加速比
均匀 100K71.5%35.2%2.03×
幂律 100K69.2%28.7%2.41×

性能优化建议

1. 矩阵格式选择

cpp
// 对于均匀矩阵,转换为 ELL 格式
if (is_uniform(csr)) {
    ELLMatrix* ell = csr_to_ell(csr);
    // 使用 ELL 内核获得更好性能
}

2. 批量处理

对于多次 SpMV 操作,复用配置:

cpp
SpMVConfig config = spmv_auto_config(csr);

for (int i = 0; i < num_iterations; i++) {
    spmv_csr(csr, x[i], y[i], &config, n);
}

3. 内存预分配

预分配输出向量避免重复分配:

cpp
CudaBuffer<float> y(num_rows);  // 一次性分配
for (auto& x : inputs) {
    spmv_csr(csr, x, y.device_ptr(), &config, n);
    // 处理 y...
}

基准测试复现

复现库构建并采集你自己的计时数据:

bash
# 克隆并构建
git clone https://github.com/AICL-Lab/gpu-spmv.git
cd gpu-spmv
cmake --preset release
cmake --build --preset release

之后请在你自己的驱动程序或应用里,对目标 spmv_csr / spmv_ell 调用做计时和 profile。仓库不再内置单独的 benchmark 可执行程序,这样能让核心库的维护面更小。

MIT License