You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何宽矩阵乘法比方阵乘法运算速度更慢?

矩阵乘法性能差异:为何方阵运算更快?

我在优化代码性能时观察到以下现象:

>>> a, b = torch.randn(1000,1000), torch.randn(1000,1000)
>>> c, d = torch.randn(10000, 100), torch.randn(100, 1000)
>>> e, f = torch.randn(100000, 10), torch.randn(10, 1000)
  
>>> %timeit torch.mm(a, b)
17 ms ± 303 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
>>> %timeit torch.mm(c, d)
24.4 ms ± 575 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
>>> %timeit torch.mm(e, f)
138 ms ± 590 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

从理论上讲,上述每个矩阵运算都需要10^9次乘法操作,但实际耗时却存在显著差异!矩阵越趋于矩形,性能就越差。我曾将缓存未命中视为原因之一,但似乎这些乘法操作均具备缓存友好性,那么为何方阵乘法的速度更快?


核心原因解析

  • CPU缓存的实际利用率差异:
    虽然总乘法次数相同,但矩阵形状直接影响缓存行的重复利用效率。方阵的行列尺寸接近,BLAS库常用的分块乘法优化中,分块大小能更好适配CPU的L1/L2缓存,同一块数据可以在缓存中被多次复用,减少内存-缓存的数据交换次数。而极端矩形矩阵的分块会让缓存内的数据复用率大幅降低,更多数据需要频繁从主存加载,拉高整体延迟。

  • BLAS库的针对性优化倾斜:
    底层BLAS实现(如OpenBLAS、MKL)会优先对方阵运算做深度优化——因为方阵在线性代数求解、神经网络全连接层等场景中更常见,厂商会投入更多资源适配SIMD指令(AVX、AVX2等)、循环展开等技术。而窄/宽矩形矩阵的运算,SIMD寄存器无法被充分填满(比如10列的矩阵,单条AVX指令能处理8个float32元素,剩余2个元素无法凑满寄存器),导致计算单元闲置,效率下降。

  • 内存访问模式的适配性:
    矩阵乘法中,一个矩阵按行访问、另一个按列访问。方阵的列尺寸适中,缓存预取机制能更精准地预测后续需要加载的列数据,提升预取命中率。而窄矩阵的列数据量过小,预取的效率极低;宽矩阵的列数据则容易超出缓存容量,导致缓存淘汰频率升高,进一步增加内存访问开销。


内容的提问来源于stack exchange,提问作者Fırat Kıyak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 08:00:05