python - 我如何知道我的令人尴尬的并行任务是否适合 GPU?
问题描述
我们是说在大量行上每行需要相当轻量计算的任务从根本上不适合 GPU 吗?
我在行独立的表上要做一些数据处理。所以它是尴尬的平行。我有一个 GPU,所以....天作之合?它与此示例非常相似,它计算每行每个条目的移动平均值(行是独立的。)
import numpy as np
from numba import guvectorize
@guvectorize(['void(float64[:], intp[:], float64[:])'], '(n),()->(n)')
def move_mean(a, window_arr, out):
window_width = window_arr[0]
asum = 0.0
count = 0
for i in range(window_width):
asum += a[i]
count += 1
out[i] = asum / count
for i in range(window_width, len(a)):
asum += a[i] - a[i - window_width]
out[i] = asum / count
arr = np.arange(2000000, dtype=np.float64).reshape(200000, 10)
print(arr)
print(move_mean(arr, 3))
像这个例子一样,我对每一行的处理不是很数学。相反,它是在行中循环并进行一些求和、赋值和其他一些零碎的操作,并加入一些条件逻辑。
我尝试在 Numba 库中使用 guVectorize 将其分配给 Nvidia GPU。它工作正常,但我没有得到加速。
这种类型的任务原则上适合 GPU 吗?即,如果我更深入地研究 Numba 并开始调整线程、块和内存管理或算法实现,理论上我应该加快速度。或者,这种问题是否根本不适合架构。
下面的答案似乎表明它不适合,但我还不太相信。
解决方案
您的任务显然受内存限制,但这并不意味着您无法从 GPU 中获利,但它可能不如 CPU 限制任务那么直接。
让我们看看常见的配置并做一些数学运算:
- 约 CPU-RAM 内存带宽。24GB/秒
- CPU-GPU 传输带宽约为 8GB/秒
- 大约 GPU-RAM 内存带宽。180GB/秒
假设我们需要传输 24 GB 的数据来完成任务,那么我们将有以下最佳时间(是否以及如何达到这些时间是另一个问题!):
- 场景:只有 CPU 时间 = 24GB/24GB/s = 1 秒。
- 场景:数据必须从 CPU 传输到 GPU(24GB/8GB/s = 3 秒)并在那里处理(24GB/180GB/s = 0.13 秒)导致 3.1 秒。
- 场景:数据已经在设备上,所以只需要 24GB/180GB/s = 0.13 秒。
正如人们所看到的,有加速的潜力,但仅限于 3. 场景 - 当您的数据已经在 GPU 设备上时。
然而,实现最大带宽是一项相当具有挑战性的事业。
例如,在 CPU 上逐行处理矩阵时,您希望数据处于行主要顺序(C 顺序)中,以便充分利用 L1 缓存:同时读取双精度实际上,您将 8 个双打加载到缓存中,并且您不希望在处理剩余的 7 个之前将它们从缓存中逐出。
另一方面,在 GPU 上,您希望内存访问被合并,例如线程0
应该访问地址0
、线程1
地址1
等。为此,数据必须按列优先顺序(Fortran 顺序)。
还有一件事需要考虑:测试性能的方式。您的测试阵列只有大约 2MB 大,因此对于 L3 缓存来说足够小。L3 缓存的带宽取决于用于计算的内核数量,但至少会在 100GB/s 左右——不比 GPU 慢多少,在 CPU 上并行化时可能快得多。
您需要一个更大的数据集,以免被缓存行为所迷惑。
有点离题的评论:从数值的角度来看,您的算法不是很健壮。
如果窗口宽度为 3,如您的示例所示,但10**4
一行中有大约元素。因此,对于最后一个元素,该值是大约10**4
加法和减法的结果,每个加法和减法都会给该值增加一个舍入误差 - 与“天真”地进行的只有三个三个加法相比,这是一个很大的差异。
当然,它可能并不重要(对于你的例子中的连续 10 个元素),但也可能有一天会咬你......
推荐阅读
- unity3d - 在 FPS 中应如何以及在何处实例化子弹。统一
- solr - Solr:对嵌套文档使用标记关系会引发未知字段错误
- vue.js - 加载到客户端后刷新静态生成的页面(数据)
- python - 是否可以编写 Python (iOS) 程序来允许/执行对 RaspberryPi 的命令?
- python - Python - 读取音频输入并实时同时播放
- python - 大量数字python的奇怪行为
- jekyll - Jekyll Liquid 标签没有被替换
- c# - 使用另一个类中的方法绘制图形
- html - 按钮 Chrome 周围的白框
- python - 为什么 pygame 显示不正确?