直接对比需重复5–10次取中位数或最小值,禁用多线程(omp_num_threads=1)、统一float32、固定随机种子,并预热以消除mkl初始化抖动;否则单次time.time()测量受调度、缓存等噪声影响,误差可能超50%。

直接测:用相同规模、相同 dtype、相同运算(比如 torch.mm vs np.dot),禁用多线程干扰,看 wall-clock 时间。PyTorch CPU 和 NumPy 在纯 CPU 场景下性能非常接近,但细节处理不当会放大误差。
为什么不能直接比 time.time() 包裹一次调用?
单次调用受 Python 解释器预热、缓存命中、系统调度等噪声影响太大,尤其对中小规模矩阵(如 1000×1000)可能误差超 50%。
- 必须重复运行至少 5–10 次,取中位数或最小值(推荐最小值,排除 GC 或调度抖动)
- 每次运行前加
torch.manual_seed()和np.random.seed(),确保数据一致 - NumPy 需显式关闭 OpenMP 干扰:
export OMP_NUM_THREADS=1(Linux/macOS)或os.environ["OMP_NUM_THREADS"] = "1"(Python 内) - PyTorch CPU 默认也走 MKL/OpenBLAS,但若装的是非 MKL 版本(如 conda-forge 默认),性能会明显下降
np.dot 和 torch.mm 的行为差异会影响结果吗?
会。它们底层调用的 BLAS 实现不同,且输入约束不完全等价:
-
np.dot(a, b)对 2D 输入等价于np.matmul,但对高维会触发广播规则;torch.mm严格只接受 2D 张量,维度不匹配直接报错 - 确保两者都用
float32:NumPy 默认float64,PyTorch 默认float32;不统一 dtype 会导致 NumPy 被拖慢 2 倍以上 - PyTorch CPU 张量默认使用与 NumPy 相同的 BLAS 后端(如 Intel MKL),但需确认:
torch.__config__.show()中查看是否含mkl
如何写出可复现的对比脚本?
关键不是“跑通”,而是控制变量。下面这段代码能排除常见干扰:
import torch
import numpy as np
import time
import os
<h1>固定随机种子 & 禁用多线程</h1><p>os.environ["OMP_NUM_THREADS"] = "1"
torch.set_num_threads(1)
np.random.seed(42)
torch.manual_seed(42)</p><p>size = 2000
a_np = np.random.rand(size, size).astype(np.float32)
b_np = np.random.rand(size, size).astype(np.float32)
a_t = torch.from_numpy(a_np)
b_t = torch.from_numpy(b_np)</p><h1>预热</h1><p>_ = np.dot(a_np, b<em>np)
</em> = torch.mm(a_t, b_t)</p><h1>测 NumPy</h1><p>times<em>np = []
for </em> in range(5):
s = time.time()
_ = np.dot(a_np, b_np)
times_np.append(time.time() - s)
print(f"NumPy median: {np.median(times_np):.4f}s")</p><h1>测 PyTorch CPU</h1><p>times<em>pt = []
for </em> in range(5):
s = time.time()
_ = torch.mm(a_t, b_t)
times_pt.append(time.time() - s)
print(f"PyTorch CPU median: {np.median(times_pt):.4f}s")</p>
注意:torch.from_numpy() 不拷贝内存,避免额外开销;预热步骤不可省——MKL 会在首次调用时做 JIT 初始化。
真正容易被忽略的是 BLAS 后端一致性。如果你用 conda 安装的 PyTorch 来自 pytorch channel,它绑定了 Intel MKL;而 pip 安装的可能用 OpenBLAS,此时和 NumPy(通常也来自 conda)就不在同一起跑线。别只看数字,先 torch.__config__.show() 和 np.show_config() 对齐后端再说快慢。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











