为什么我的 CPU 执行矩阵运算的速度比 GPU 快?

Why is my CPU doing matrix operations faster than GPU instead?

当我试图验证 GPU 对 CPU 进行矩阵运算时,我出乎意料 results.CPU 根据我的经验结果,性能比 GPU 好,这让我感到困惑。

我用cpu和gpu做矩阵乘法respectively.Programming环境是MXNet和cuda-10.1

使用 GPU:

import mxnet as mx
from mxnet import nd
x = nd.random.normal(shape=(100000,100000),ctx=mx.gpu())
y = nd.random.normal(shape=(100000,100000),ctx=mx.gpu())
%timeit nd.dot(x,y)

50.8 µs ± 1.76 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

与 cpu:

x1 = nd.random.normal(shape=(100000,100000),ctx=mx.cpu())
y1 = nd.random.normal(shape=(100000,100000),ctx=mx.cpu())
%timeit nd.dot(x1,y1)

33.4 µs ± 1.54 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

为什么CPU更快?我的CPU型号是i5-6300HQ,GPU型号是Nividia GTX 950M。

我不知道您使用的是什么模块,但是您的 CPU 可以更快地访问您的内存,并且还可以在缓存中保存很多内容。您的 GPU 需要更长的时间将数据加载到 GPU 内存中,并且从您的 CPU 调用数据也需要更长的时间。 这始终是 GPU 计算的缺点。当您可以将一堆数据加载到 GPU 内存中时,很有可能会更快。 顺便说一句,这就是深度学习框架批量工作的原因。当您不能使用批处理时,我总是使用 CPU。您还可以通过多处理获得一些性能改进的潜力。

TLDR:你的矩阵乘法实际上不是 运行ning :)

MXNet 是一个异步框架,它将工作请求堆积在一个队列中,由其执行引擎根据需要 运行 进行异步处理。所以你测量的只是发送请求所花费的时间,而不是执行它所花费的时间。这就是为什么它如此之小(在 100k*100k 矩阵上以微秒计会快得惊人)并且对于 CPU 和 GPU 来说大致相等。要强制执行,您需要添加一个强制生成结果的调用,例如 printnd.dot(x, y).wait_to_read()。在此处查看与您的基准测试非常相似的代码 https://github.com/ThomasDelteil/MXNetParisWorkshop/blob/master/FromNDArrayToTrainedModel.ipynb

额外评论:

  1. 与 CPU 相比,使用 GPU 的好处在于 并行机会。在简单的任务中,增益可能小到 不存在的。 CPU 核心频率实际上是原来的 2 到 3 倍 比 GPU 频率(您的 i5-6300HQ 可以达到 2.3GHz,提升 3.2GHz 能力,而你的 GTX 950M 可以达到 0.9GHz 并具有 1.1GHz 的提升能力)。

  2. MXNet ndarray 在 CPU 上的矩阵代数非常快,因为 (1) 它的异步范式优化了计算顺序 (2)它的 C++ 后端 运行s 是并行的,并且 (3) 我相信默认的 MXNet 构建带有 Intel MKL,这显着提高了 Intel CPUs 的代数能力 (https://medium.com/apache-mxnet/mxnet-boosts-cpu-performance-with-mkl-dnn-b4b7c8400f98)。例如,它在同一 API 内在 GPU 上进行 运行 计算的能力也是优于 Numpy 的一大优势。

  3. 我认为您的测试不会 运行 在 GPU 上:实例化这么大的矩阵 NVIDIA Tesla V100(16GB 男性,比 GTX 950M 多 4 倍)运行s “大张量大小错误”