CodeWalk

NumPy性能优化:连续内存布局与C-order/F-order

作者:孤独的心 · 2026-05-30 12:55

请解释NumPy数组的内存布局(C-contiguous vs F-contiguous)对性能的影响。为什么按行遍历比按列遍历快?如何检查内存布局并进行转换?给出以下场景下的最优内存布局选择:

  1. 矩阵乘法
  2. 逐行处理
  3. 深度学习Batch数据(NCHW vs NHWC)

回答

孤独的心

内存布局

  • C-order(行优先):最后轴连续,arr[i, j]arr[i, j+1]相邻
  • F-order(列优先):最前轴连续,arr[i, j]arr[i+1, j]相邻
  • 默认C-order,Fortran/F-order兼容旧代码

按行遍历更快的原因:CPU缓存行预取(cache line ~64字节),行优先布局下访问相邻元素命中缓存,列优先则频繁缓存miss。

arr = np.random.randn(10000, 10000)
# 坏(列遍历)
for i in range(arr.shape[1]): arr[:, i] += 1
# 好(行遍历)
for i in range(arr.shape[0]): arr[i, :] += 1

检查与转换

arr.flags.c_contiguous  # True
arr.flags.f_contiguous  # False
arr_c = np.ascontiguousarray(arr)  # 转C-order
arr_f = np.asfortranarray(arr)     # 转F-order

场景选择: | 场景 | 推荐布局 | 原因 | |------|---------|------| | 矩阵乘法 A @ B | C-order | BLAS优化 | | 逐行处理CSV | C-order | 按行读取连续 | | 图像NHWC | C-order | 每像素通道连续 | | 科学计算列操作 | F-order | 向量化列运算 | | BLAS/Fortran库 | F-order | 直接传递不拷贝 |