为什么numba cuda调用几次后运行速度变慢?

2024-04-21

我正在尝试如何在 numba 中使用 cuda。然而我却遇到了与我预想不同的事情。这是我的代码

from numba import cuda
@cuda.jit
def matmul(A, B, C):
"""Perform square matrix multiplication of C = A * B
"""
d=cuda.local.array((3,3),dtype=numba.float64)
i, j = cuda.grid(2)
if i < C.shape[0] and j < C.shape[1]:
    tmp = 0.
    for k in range(A.shape[1]):
        tmp += A[i, k] * B[k, j]
    C[i, j] = tmp

这是我自己定义的矩阵函数,用于使用numba.cuda进行测试。在运行测试之前,我还在以下代码中加载了数组:

import numpy as np
a=np.random.rand(2000,2000)
b=np.random.rand(2000,2000)
c=np.empty((2000,2000))
a1=cuda.to_device(a)
b1=cuda.to_device(b)
c1=cuda.to_device(c)

然后我用下面的代码进行实验:

from time import time
count =0
start=time()
for i in range(2000):
  matmul[(256,256),(16,16)](a1,b1,c1)
  count +=1
  print(count)

for 循环在前 1028 次运行中运行得非常快。然而,在 1028 号之后,它运行得非常慢。到底是什么导致了这个问题,我该如何解决它。顺便说一句,我是在win10上运行的。

这是我从 numba.cuda 调用的 cuda 信息

from numba import cuda
gpu = cuda.get_current_device()
print("name = %s" % gpu.name)
print("maxThreadsPerBlock = %s" % str(gpu.MAX_THREADS_PER_BLOCK))
print("maxBlockDimX = %s" % str(gpu.MAX_BLOCK_DIM_X))
print("maxBlockDimY = %s" % str(gpu.MAX_BLOCK_DIM_Y))
print("maxBlockDimZ = %s" % str(gpu.MAX_BLOCK_DIM_Z))
print("maxGridDimX = %s" % str(gpu.MAX_GRID_DIM_X))
print("maxGridDimY = %s" % str(gpu.MAX_GRID_DIM_Y))
print("maxGridDimZ = %s" % str(gpu.MAX_GRID_DIM_Z))
print("maxSharedMemoryPerBlock = %s" % 
str(gpu.MAX_SHARED_MEMORY_PER_BLOCK))
print("asyncEngineCount = %s" % str(gpu.ASYNC_ENGINE_COUNT))
print("canMapHostMemory = %s" % str(gpu.CAN_MAP_HOST_MEMORY))
print("multiProcessorCount = %s" % str(gpu.MULTIPROCESSOR_COUNT))
print("warpSize = %s" % str(gpu.WARP_SIZE))
print("unifiedAddressing = %s" % str(gpu.UNIFIED_ADDRESSING))
print("pciBusID = %s" % str(gpu.PCI_BUS_ID))
print("pciDeviceID = %s" % str(gpu.PCI_DEVICE_ID))

输出是:

名称 = b'GeForce GTX 1050 Ti'

每个块的最大线程数 = 1024

最大块尺寸X = 1024

最大块尺寸 = 1024

最大块尺寸Z = 64

maxGridDimX = 2147483647

最大网格尺寸 = 65535

最大网格尺寸Z = 65535

每个块的最大共享内存 = 49152

异步引擎计数 = 2

canMapHostMemory = 1

多处理器计数 = 6

扭曲大小 = 32

统一寻址 = 1

pci总线ID = 3

pci设备ID = 0


这是由与 GPU 内核启动相关的异步启动队列引起的。

当您告诉 numba 提交 GPU 内核时:

matmul[(256,256),(16,16)](a1,b1,c1)

该请求进入队列,发出该内核调用的 CPU 线程(即 python)可以继续,即使 GPU 内核尚未完成或什至尚未启动。

CUDA 运行时将这些请求排队并在 GPU 准备好执行更多工作时发出它们。

在 for 循环快速递增期间,您最初看到的是队列填满了工作请求。这并不代表 GPU 执行工作所需的实际时间。

最终队列填满,CUDA 运行时在内核启动时暂停 CPU 线程(即 python),直到队列槽打开。此时,for 循环可以继续进行一次迭代。正是在这一点上(可能在 1028 次迭代左右),您开始看到“速度变慢”。此后,for 循环继续进行大约GPU 内核执行和从处理队列中删除的速率。

这里没有什么需要修复的;这是预期的行为。

如果您希望 for 循环仅按照 GPU 内核实际执行的速率进行,那么您应该在 for 循环中插入一个同步函数。

例如,numba 提供numba.cuda.synchronize() https://numba.pydata.org/numba-doc/dev/cuda-reference/host.html因此,如果您按如下方式修改 for 循环:

for i in range(2000):
  matmul[(256,256),(16,16)](a1,b1,c1)
  cuda.synchronize()
  count +=1
  print(count)

您将看到 for 循环以 GPU 工作完成的实际速率进行,而不是“队列填充”速率。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么numba cuda调用几次后运行速度变慢? 的相关文章

  • 如何在 MacBook Pro 上的 Docker 容器内运行 tkinter?

    我正在尝试运行一个使用以下命令的 python GUI 应用程序tkinter我的 MacBook Pro 上的 docker 容器内的模块 所以我安装了XQuartz https www xquartz org 并跟随本教程 https
  • Pandas 中的 Groupby、转置和追加?

    我有一个数据框 如下所示 每个用户有10条记录 现在 我想创建一个如下所示的数据框 userid name1 name2 name10 这意味着我需要反转该列的每 10 条记录name并附加到新的数据框 那么 它是如何做到的呢 有什么办法可
  • 最小化 MC 模拟期间存储的 cuRAND 状态数量

    我目前正在 CUDA 中编写蒙特卡罗模拟 因此 我需要生成lots使用随机数cuRAND图书馆 每个线程处理一个巨大的元素floatarray 示例中省略 并在每次内核调用时生成 1 或 2 个随机数 通常的方法 参见下面的示例 似乎是为每
  • 无法在 virtualenv 中安装 libxml2

    我有一个问题libxml2蟒蛇模块 我正在尝试将其安装在python3 虚拟环境使用以下命令 pip install libxml2 python3 但它显示以下错误 Collecting libxml2 python3 Using cac
  • 无法让gunicorn使用Python 3

    我有 Ubuntu NGINX Gunicorn 以及可与 Python 3 设置配合使用的虚拟环境 但我的 Flask 应用程序仍然以 2 7 6 运行 我已系统地按照说明进行操作 但找不到解决方案 Gunicorn 配置文件 progr
  • 如何将字符串转换为浮点数? [复制]

    这个问题在这里已经有答案了 我需要转换变量 pi string 3 1415926 变成一个浮子 这是我正在处理的事情 你的线路应该是pi float float pi string float pi string 是一个浮点值 你不能给它
  • 使用 os.write 打印字体图标

    在 Windows 10 上使用 Python 3 8 3 我的终端 使用nerdfont https github com ryanoasis nerd fonts tree master patched fonts Agave有图标的
  • gitlab-ci 的缓存虚拟环境

    我使用 Gitlab CI 脚本缓存了 Pip 包 所以这不是问题 现在我还想赶上Conda虚拟环境 因为它减少了设置环境的时间 我缓存了一个虚拟环境 不幸的是 最后需要很长时间才能缓存所有 venv 文件 我尝试仅缓存 CI PROJEC
  • 如何优化分割重叠范围?

    我编写的这个 Python 脚本用于将重叠范围拆分为唯一范围 最后一次迭代 https codereview stackexchange com questions 285932 python script to split overlap
  • 如何在 Python 中将 pdf 文件附加到 MIME 电子邮件?

    我正在制作一个自动邮件发送程序 Python 3 6 1 用于电子邮件营销 我在附加 PDF 文件时遇到问题 邮件中的 PDF 文件的文件名和页数是正确的 但 PDF 文件始终为空白 并且其大小增加 我尝试了三种不同的方法 其他两种方法不起
  • 没有名为 StringIO 的模块

    我有Python 3 6 我想从另一个名为 run py 的 python 文件执行名为 operation py 的 python 文件 In operation py I do from cStringIO import StringI
  • Python pip install pyarrow错误,无法执行'cmake'

    我尝试在 EMR 集群的主实例上安装 pyarrow 但总是收到此错误 hadoop ip XXX XXX XXX XXX sudo usr bin pip 3 4 install pyarrow Collecting pyarrow Do
  • SocketIO + Flask 检测断开连接

    我在这里有一个不同的问题 但意识到它可以简化为 如何检测客户端何时从页面断开连接 关闭其页面或单击链接 换句话说 套接字连接关闭 我想制作一个带有更新用户列表的聊天应用程序 并且我在 Python 上使用 Flask 当用户连接时 浏览器发
  • Python SSL X509:KEY_VALUES_MISMATCH

    Python HTTPS server from http server import HTTPServer SimpleHTTPRequestHandler import ssl https stackoverflow com a 408
  • 创建 matplotlib 注释后如何移动它们?

    我有以下代码来使用生成箭头ax annotate import numpy as np import matplotlib pyplot as plt fig ax plt subplots t np arange 0 0 5 0 0 01
  • 使用 Python37 运行时通过 Cloud Functions 生成缩略图

    我有一个由 Firebase 存储触发的 Google Cloud 函数 我想生成缩略图 虽然 Node js 文档有一个使用 ImageMagick 的示例 https cloud google com functions docs tu
  • lxml/python 使用 CDATA 部分读取 xml

    在我的 xml 中我有一个CDATA部分 我想保留 CDATA 部分 然后剥离它 有人可以帮忙解决以下问题吗 默认不起作用 from io import StringIO from lxml import etree xml
  • 如何修复下载 spacy 模型的“无效语法”

    我尝试在 Jupyter 笔记本上下载 spacy 模型 但它打印出 无效语法 python m spacy download en core web sm 有什么解决方案可以帮助我成功下载模型吗 为了将来帮助某人 对我来说 这个问题是因为
  • 使用 matplotlib 在 python3 中对多个形状进行动画处理

    尝试在 python3 中使用 matplotlib 动画函数同时对多个对象进行动画处理 下面写的代码是我到目前为止的位置 我能够创建多个对象并将它们显示在图中 我通过使用包含矩形补丁函数的 for 循环来完成此操作 从这里开始 我希望通过
  • 从由空格分隔的单个输入整数列表创建二维数组

    我正在解决一些问题geeksforgeeks我遇到了一个特定的问题 其中在测试用例中提供了输入 如下所示 2 2 denotes row column of the matrix 1 0 0 0 all the elements of th

随机推荐