我可以使用我的GPU的核心来加速这个问题并加快速度吗?如果是的话,我该如何做?在我的CPU中,大约有10万亿个线程做不到,这就是为什么我想用GPU加速它。我也有兴趣看到任何多线程CPU的答案,但我真的很想看到它在GPU上完成。理想情况下,我希望答案尽可能简单。
我的代码:
y=0
for x in range(1, 10000000000):
y += 1/x
print(y)发布于 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):
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代码。下面是一个示例:
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代码具有更简单、更易于维护、更可移植和更灵活的优点,尽管速度可能较慢。
发布于 2022-06-23 16:42:53
(Nvidia CUDA) GPU可以与适当的模块安装在一起。然而,一个标准的多处理解决方案(这不是多线程,因为这是一个只计算的任务)很容易实现,而且相当有效:
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秒就能运行。
https://stackoverflow.com/questions/72732401
复制相似问题