专栏首页Dechin的专栏用CUDA写出比Numpy更快的规约求和函数

用CUDA写出比Numpy更快的规约求和函数

技术背景

在前面的几篇博客中我们介绍了在Python中使用Numba来写CUDA程序的一些基本操作和方法,并且展示了GPU加速的实际效果。在可并行化的算法中,比如计算两个矢量的加和,或者是在分子动力学模拟领域中的查找近邻表等等,都是可以直接并行的算法,而且实现起来难度不大。而有一种情况是,如果我们要计算的内容的线程之间互相存在依赖,比方说最常见的,计算一个矩阵所有元素的和。

CUDA的atomic运算

正如前面所提到的问题,如何去计算一个矩阵所有元素之和呢?具体问题可以表述为:

\[S=\sum_{i,j}A_{i,j} \]

对于此类的问题,如果我们像普通的CUDA并行操作一样,直接创建一个S变量,然后直接在线程和分块上直接把每一个矩阵元素加到这个S变量中,那么会出现一种情况:在线程同步时,存在冲突的线程是无法同时加和成功的,也就是说,这种情况下虽然程序不会报错,但是得到的结果是完全错误的。对于此类情况,CUDA官方给出了atomic运算这样的方案,可以保障线程之间不被干扰:

import numpy as np
from numba import cuda
from numba import vectorize
cuda.select_device(1)

@cuda.jit
def ReducedSum(arr, result):
    i, j = cuda.grid(2)
    cuda.atomic.add(result, 0, arr[i][j])

if __name__ == '__main__':
    import time
    np.random.seed(2)
    data_length = 2**10
    arr = np.random.random((data_length,data_length)).astype(np.float32)
    print (arr)
    arr_cuda = cuda.to_device(arr)
    np_time = 0.0
    nb_time = 0.0
    for i in range(100):
        res = np.array([0],dtype=np.float32)
        res_cuda = cuda.to_device(res)
        time0 = time.time()
        ReducedSum[(data_length,data_length),(1,1)](arr_cuda,res_cuda)
        time1 = time.time()
        res = res_cuda.copy_to_host()[0]
        time2 = time.time()
        np_res = np.sum(arr)
        time3 = time.time()
        if i == 0:
            print ('The error rate is: ', abs(np_res-res)/res)
            continue
        np_time += time3 - time2
        nb_time += time1 - time0
    print ('The time cost of numpy is: {}s'.format(np_time))
    print ('The time cost of numba is: {}s'.format(nb_time))

这里需要重点关注的就是用CUDA实现的简单函数ReducedSum,这个函数中调用了CUDA的atomic.add方法,用这个方法直接替代系统内置的加法,就完成了所有的操作。我们将这个函数的运行时间去跟np.sum函数做一个对比,结果如下:

$ python3 cuda_reduced_sum.py 
[[0.4359949  0.02592623 0.5496625  ... 0.3810055  0.6834749  0.5225032 ]
 [0.62763107 0.3184925  0.5822277  ... 0.89322233 0.7845663  0.4595605 ]
 [0.9666947  0.16615923 0.6931703  ... 0.29497907 0.63724256 0.06265242]
 ...
 [0.96224505 0.36741972 0.6673239  ... 0.3115176  0.7561843  0.9396167 ]
 [0.781736   0.28829736 0.38047555 ... 0.15837361 0.00392629 0.6236886 ]
 [0.03247315 0.3664344  0.00369871 ... 0.0205253  0.15924706 0.8655231 ]]
The error rate is:  4.177044e-06
The time cost of numpy is: 0.027491092681884766s
The time cost of numba is: 0.01042938232421875s

在GPU的计算中,会有一定的精度损失,比如这里的误差率就在1e-06级别,但是运行的速度要比numpy的实现快上2倍!

总结概要

我们知道GPU加速在可并行化程度比较高的算法中,能够发挥出比较大的作用,展示出明显的加速效果,而对于一些线程之间存在依赖这样的场景就不一定能够起到很大的加速作用。CUDA官方针对此类问题,提供了atomic的内置函数解决方案,包含有求和、求最大值等常用函数。而这些函数的特点就在于,线程与线程之间需要有一个时序的依赖关系。就比如说求最大值的函数,它会涉及到不同线程之间的轮询。经过测试,CUDA的这种atomic的方案,实现起来非常方便,性能也很乐观,相比于自己动手实现一个不断切割、递归的规约函数,还是要容易快捷的多。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【阿星的学习笔记(1)】如何在windows安裝Theano +Keras +Tensorflow並使用GPU加速訓練神經網路

    今天开始,Lady向各位介绍一个朋友阿星(Ashing)以及他的机器学习读书笔记! ? 阿星也是我们手撕深度学习算法微信群的热心群友!接下来,Lady我也会陆续...

    GPUS Lady
  • PyTorch 的这些更新,你都知道吗?

    昱良
  • PyTorch 重磅更新,不只是支持 Windows

    这次版本的主要更新一些性能的优化,包括权衡内存计算,提供 Windows 支持,24个基础分布,变量及数据类型,零维张量,张量变量合并,支持 CuDNN 7.1...

    AI科技大本营
  • 用Numba加速Python代码

    说这句话的人也没有错。与许多其他编程语言相比,Python很慢。Benchmark game有一些比较不同编程语言在不同任务上的速度的可靠的基准。

    AiTechYun
  • 一文理解PyTorch:附代码实例

    最近在学习Pytorch,对于每个部分有大致了解,但没有整体的逻辑框架,这篇文章虽然是翻译的,但有条理的带大家认识了Pytorch构建模型并进行训练的一般步骤和...

    张小磊
  • GPU加速04:将CUDA应用于金融领域,使用Python Numba加速B-S期权估值模型

    本文为英伟达GPU计算加速系列的第四篇,主要基于前三篇文章的内容,以金融领域期权估值案例来进行实战练习。前三篇文章为:

    PP鲁
  • 快速入门Pytorch(1)--安装、张量以及梯度

    https://pytorch.org/tutorials/beginner/deep_learning_60min_blitz.html

    kbsc13
  • 用 Numba 加速 Python 代码,变得像 C++ 一样快

    注意: 这篇文章的 Jupyter Notebook 代码在我的 Github 上:SpeedUpYourAlgorithms-Numba

    昱良
  • 大白话5分钟带你走进人工智能-第36节神经网络之tensorflow的前世今生和DAG原理图解(4)

    Tensorflow由Google Brain谷歌大脑开源出来的,在2015年11月在GitHub上开源,2016年是正式版,2017年出了1.0版本,趋于稳定...

    LhWorld哥陪你聊算法
  • NeurIPS顶会接收,PyTorch官方论文首次曝光完整设计思路

    论文地址:https://papers.nips.cc/paper/9015-pytorch-an-imperative-style-high-performa...

    机器之心
  • 一文读懂PyTorch张量基础(附代码)

    本文介绍了PyTorch Tensor最基础的知识以及如何跟Numpy的ndarray互相转换。

    数据派THU
  • GPU编程(四): 并行规约优化

    如果之前没有用过gdb, 可以速学一下, 就几个指令. 想要用cuda-gdb对程序进行调试, 首先你要确保你的gpu没有在运行操作系统界面, 比方说, 我...

    sean_yang
  • Python高性能计算库——Numba

    摘要: 在计算能力为王的时代,具有高性能计算的库正在被广泛大家应用于处理大数据。例如:Numpy,本文介绍了一个新的Python库——Numba, 在计算性能方...

    IT派
  • 最新翻译的官方 PyTorch 简易入门教程

    https://github.com/fengdu78/machine_learning_beginner/tree/master/PyTorch_beginn...

    用户1737318
  • TensorFlow从1到2(一)续讲从锅炉工到AI专家

    原来引用过一个段子,这里还要再引用一次。是关于苹果的。大意是,苹果发布了新的开发语言Swift,有非常多优秀的特征,于是很多时髦的程序员入坑学习。不料,经过一段...

    俺踏月色而来
  • PyTorch 60-Minute Blitz

    Tensors(张量)与 Numpy 的 ndarrays 类似,但是其支持在 GPU 上使用来加速计算。

    口仆
  • GPU加速02:超详细Python Cuda零基础入门教程,没有显卡也能学!

    Python是当前最流行的编程语言,被广泛应用在深度学习、金融建模、科学和工程计算上。作为一门解释型语言,它运行速度慢也常常被用户诟病。著名Python发行商A...

    PP鲁
  • 如何将Numpy加速700倍?用 CuPy 呀

    就其自身来说,Numpy 的速度已经较 Python 有了很大的提升。当你发现 Python 代码运行较慢,尤其出现大量的 for-loops 循环时,通常可以...

    小草AI
  • 在CUDA的天下,OpenAI开源GPU编程语言Triton,将同时支持N卡和A卡

    过去十年中,深度神经网络 (DNN) 已成为最重要的机器学习模型之一,创造了从自然语言处理到计算机视觉、计算神经科学等许多领域的 SOTA 实现。DNN 模型的...

    代码医生工作室

扫码关注云+社区

领取腾讯云代金券