我可以使用我的 GPU 中的核心来加速这个问题并加快速度吗?如果是这样,我该怎么做?在 10 万亿左右,我的 CPU 中的单个线程根本无法做到这一点,这就是为什么我想用我的 GPU 来加速它。我也有兴趣查看任何多线程 CPU 答案,但我真的希望看到它在 GPU 上完成。理想情况下,我希望答案尽可能简单。
我的代码:
y=0
for x in range(1, 10000000000):
y += 1/x
print(y)
最佳答案
是的,可以使用基本的并行缩减在一个 GPU 上完成此操作。事实上,它非常适合 GPU,因为它主要并行并且大量使用浮点/整数运算。
请注意,这种基本序列的收敛性是众所周知的分析(正如@jfaccioni 所指出的),因此您应该更喜欢通常计算成本低得多的分析解决方案。另请注意,客户端 GPU 不太适合高效计算 64 位浮点 (FP) 数字,因此您通常应该使用 32 位 GPU,这样才能以较低的精度为代价实现加速/em>.话虽这么说,服务器端 GPU 可以有效地计算 64 位 FP 数,因此最佳解决方案取决于您实际拥有的硬件。
Nvidia GPU 通常使用 CUDA 进行编程,与基本的纯 Python 代码相比,这是相当低级的。有Python包装器和更高级别的库,但在这种情况下大多数效率不高,因为它们会导致不必要的内存加载/存储或其他开销。 AFAIK、PyCUDA 和 Numba 可能是迄今为止最好的工具。如果您的 GPU 不是 Nvidia GPU,那么您可以使用基于 OpenCL 的库(因为非 Nvidia GPU 尚未很好地支持 CUDA)。
Numba 支持高级缩减,因此可以非常轻松地完成(请注意,Numba 在内部使用 CUDA,因此您需要 Nvidia GPU):
from numba import cuda
# "out" is an array with 1 FP item that must be initialized to 0.0
@cuda.jit
def vec_add(out):
x = cuda.threadIdx.x
bx = cuda.blockIdx.x
bdx = cuda.blockDim.x
i = bx * bdx + x
if i < 10_000_000_000-1:
numba.cuda.atomic.add(out, 0, i+1)
这只是 GPU 内核,而不是全部代码。有关如何运行它的更多信息,请阅读 documentation 。一般来说,需要关心数据传输、分配内核依赖性、流等。请记住,GPU 很难(高效)编程。这个内核很简单,但显然不是最优的,特别是在没有硬件原子加速单元的旧GPU上。要编写更快的内核,您需要使用内部循环执行局部缩减。另请注意,C++ 更适合编写高效的内核代码,尤其是使用 CUB(基于 CUDA)等支持迭代器和高级灵活高效原语的库。
请注意,Numba 还可用于实现快速并行 CPU 代码。这是一个例子:
import numba as nb
@nb.njit('float64(int64)', fastmath=True, parallel=True)
def compute(limit):
y = 0.0
for x in nb.prange(1, limit):
y += 1 / x
return y
print(compute(10000000000))
这在我的 10 核 CPU 机器上只需要 0.6 秒。尽管速度可能较慢,但 CPU 代码的优点是更简单、更易于维护、更可移植且更灵活。
关于python - 你能用 GPU 加速 python 中的简单数学方程吗,例如 : y = 1/x and how do you do it?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72732401/