首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在python中,GPU能加速一个简单的数学方程,例如:y= 1/x吗?

在python中,GPU能加速一个简单的数学方程,例如:y= 1/x吗?
EN

Stack Overflow用户
提问于 2022-06-23 15:02:33
回答 2查看 213关注 0票数 1

我可以使用我的GPU的核心来加速这个问题并加快速度吗?如果是的话,我该如何做?在我的CPU中,大约有10万亿个线程做不到,这就是为什么我想用GPU加速它。我也有兴趣看到任何多线程CPU的答案,但我真的很想看到它在GPU上完成。理想情况下,我希望答案尽可能简单。

我的代码:

代码语言:javascript
运行
复制
y=0

for x in range(1, 10000000000):
    y += 1/x

print(y)
EN

回答 2

Stack Overflow用户

发布于 2022-06-23 16:46:59

是的,这个操作可以使用基本的并行还原完成一个GPU。事实上,它非常适合于GPU,因为它主要是令人尴尬的并行和大量使用浮点/整数操作。

请注意,这类基本序列的收敛性是众所周知的解析(如@jfaccioni所指出的),因此您应该更喜欢计算成本低得多的解析解。还要注意的是,客户端GPU对于高效计算64位浮点(FP)数字并不是很好,所以通常应该使用32位浮点(FP),这样就可以看到速度的提高,而牺牲了较低的精度。也就是说,服务器端GPU可以高效地计算64位FP数,所以最好的解决方案取决于您实际拥有的硬件。

Nvidia GPU通常是用CUDA编程的,与基本的纯Python代码相比,这是相当低的水平。有Python包装器和更高级别的库,但在本例中,大多数都不是有效的,因为它们会导致不必要的内存负载/存储或其他开销。AFAIK、PyCUDA和Numba可能是实现这一目标的最佳工具。如果您的GPU不是Nvidia GPU,那么您可以使用基于OpenCL的库(因为非Nvidia GPU还没有很好地支持CUDA )。

Numba支持高级别的裁减,因此它可以非常容易地完成(注意,Numba在内部使用CUDA,因此您需要一个Nvidia GPU):

代码语言:javascript
运行
复制
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内核,而不是整个代码。有关如何运行它的更多信息,请阅读文档。通常,需要关注数据传输、分配内核依赖关系、流等。请记住,GPU很难(高效)编程。这个内核很简单,但显然不是最优的,特别是在没有硬件原子加速单元的旧GPU上。要编写更快的内核,需要使用内部循环执行局部缩减。还要注意的是,C++编写高效的内核代码要好得多,特别是使用库(基于CUDA),它支持迭代器和高级灵活有效的原语。

请注意,Numba也可以用于实现快速并行CPU代码。下面是一个示例:

代码语言:javascript
运行
复制
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核机器上,这只需要0.6秒的时间.CPU代码具有更简单、更易于维护、更可移植和更灵活的优点,尽管速度可能较慢。

票数 2
EN

Stack Overflow用户

发布于 2022-06-23 16:42:53

(Nvidia CUDA) GPU可以与适当的模块安装在一起。然而,一个标准的多处理解决方案(这不是多线程,因为这是一个只计算的任务)很容易实现,而且相当有效:

代码语言:javascript
运行
复制
import multiprocessing as mp

def inv_sum(start):
  return sum(1/x for x in range(start,start+1000000))

def main():
  pool = mp.Pool(mp.cpu_count())
  result = sum(pool.map(inv_sum, range(1,1000000000,1000000)))
  print(result)

if __name__ == "__main__":
  main()

我不敢在一万亿台电脑上测试它,但是我的8核i-5笔记本电脑上的10亿台笔记本电脑只需20秒就能运行。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72732401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档