[spring 并行5]GPU

GPU篇 1

准备

  1. 需要有支持CUDA的Nvidia显卡
    linux查看显卡信息:lspci | grep -i vga
    使用nvidia显卡可以这样查看:lspci | grep -i nvidia
    上一个命令可以得到类似"03.00.0"的显卡代号,查看详细信息:lspic -v -s 03.00.0
    查看显卡使用情况(nvidia专用):nvidia-smi
    持续周期性输出使用情况(1秒1次):watch -n 1 nvidia-smi
  2. 需要安装pycuda(linux安装:apt install python3-pycuda)

基本使用

1.底层操作

  1. 准备工作: sudo apt install python3-pycuda
  2. 在cpu使用的内存中创建矩阵
  3. 将矩阵从cpu使用的内存移动到gpu的显存中
  4. 编辑c语言代码,让gpu计算
  5. 将矩阵从gpu显存移动到cpu使用的内存中

内核与线程层级
CUDA程序的一个最重要元素就是内核(kernel),它代表可以并行执行的代码
每个内核的执行均有叫做线程(thread)的计算单元完成,与cpu的线程不同,gpu线程更加轻量,上下文切换不会影响性能
为了确定运行一个内核所需的线程数机器逻辑组织形式,CUDA定义了一个二层结构。在最高一层,定义了所谓的区块网格(grid of blocks),这个网格代表了线程区块所在的二维结构,而这些线程区块则是三维的(简单来说,一个cuda结构包含多个blocks,每个blocks包含多个thread)(在下面还会对每个线程区块细分操作)

一个线程区块会被指派给一个流式多处理器(SM),然后这些线程被进一步划分为被称为warp的线程组,其大小有GPU的架构决定
为了充分发挥SM本身的并发性,同一组内的线程必须执行相同的指令,否则会出现线程分歧(divergence of thread)

示例:
用gpu将矩阵每个元素x2

import pycuda.driver as cuda
import pycuda.autoinit  # init GPU
from pycuda.compiler import SourceModule

import numpy as np

# 1.cpu create matrix
a = np.random.randn(5, 5)   # matrix:m*n
a = a.astype(np.float32)    # nvidia only support float calculate

# 2.move to gpu from cpu
a_gpu = cuda.mem_alloc(a.nbytes)    # alloc memory of gpu, this is 1 dim
cuda.memcpy_htod(a_gpu, a)      # copy cpu memory to gpu memory

# 3.gpu calculate
# create module of gpu calculate by c
mod = SourceModule('''
    __global__ void doubleMatrix(float *a)
    {
        int idx = threadIdx.x + threadIdx.y * 5;    // (x,y,z), gpu -> sm -> warp
        a[idx] *= 2;
    }
''')

func = mod.get_function('doubleMatrix') # get function from module
func(a_gpu, block = (5, 5, 1))      # set var and thread number from (x,y,z) orient to function

# 4.move to cpu from gpu
a_doubled = np.empty_like(a)        # create memory of cpu
cuda.memcpy_dtoh(a_doubled, a_gpu)  # copy gpu memory to cpu memory

print('original matrix')
print(a)
print('double matrix')
print(a_doubled)

注1import pycuda.autoinit 语句自动根据GPU可用性和数量选择要使用的GPU,这将创建一个接下来的代码运行中所需的GPU上下文(只需导入即可完成)

: astype(numpy.float32):将矩阵中的项转换为单精度模式,因为许多Nvidia显卡只支持单精度

注3:在调用gpu的c函数时,通过block参数设定,分配线程的方式,(5, 5, 1)是对应这gpu的(x, y, x)的分配
在c函数中,threadIdx是一个结构体,它有三个字段xyz,每个线程中的这个变量都不同(结合线程层级理解),故用此索引数组,由于动态分配的gpu内存是一维数组,所以需要在c函数内,使用threadIdx.y乘以矩阵每行的元素个数转换
更多详情:自行搜索cuda的线程区块划分

注4:gpu执行的c函数中 __global__ 关键字表示该函数是一个内核函数,必须从主机上调用才能在gpu设备上生成线程层级
涉及到pycuda内存,为了最大限度地利用可用资源,在支持CUDA的GPU显卡中,有4类内存:
寄存器(registers):每个线程将被分配一个寄存器,每个线程只能访问自身的寄存器,即使同属于一个线程区块
共享存储器(shared memory):在共享存储器中,每个线程区块都有一个其内部线程共享的内存,这部分内存速度极快
常数存储器(constant memory):一个网格中的所有线程一直都可以访问这部分内存,但只能在读取时访问。常数存储器中的数据在应用持续期间一直存在
全局存储器(global memory),:所有网格中的线程(也包含所有内核)都可访问全局存储器

更多详情:自行搜索PyCUDA内存模型

2.python封装控制

用gpuarray调用内核,它可以直接将数据保存在计算设备(gpu)中,并在该设备中进行计算

示例:
用gpu将矩阵每个元素x2

import pycuda.autoinit
import pycuda.gpuarray as gpuarray

import numpy as np

x = np.random.randn(5, 5)
x_gpu = gpuarray.to_gpu(x)

x_doubled = (2 * x_gpu).get()

print('x:')
print(x)
print('x_doubled:')
print(x_doubled)

其它

还有其它的库可以方便对cuda编程,如NumbaPro是一个Python编译器,提供了基于CUDA的API编程接口,可以编写CUDA持续,它专门设计用来执行与数组相关的计算任务,和广泛使用的numpy库类似
NumbaPro: 对GPU编程的库,提供许多的数值计算库,GPU加速库



1.参考书籍:《Python并行编程手册》

原文地址:https://www.cnblogs.com/maplesnow/p/12044372.html

时间: 2024-10-15 02:25:21

[spring 并行5]GPU的相关文章

[spring 并行6]分布式

分布式篇 1 简述 分布式计算的基本理念是将工作划分为一个一个小任务,分发给多台设备处理,再汇总结果.在分布式计算中,网络中的机器必须要保持可用(延迟误差.意外宕机等等),需要一个持续监控架构 分布式多进程 2 multiprocessing的子模块managers还支持把多进程分布在多台机器上,managers模块已经封装好了网络通信的细节 实现方法:我们可以使用managers模块将queue队列通过网络暴露出去,让其它机器访问到这个队列,然后就可以通过它实现数据交换 示例: 服务器通过暴露

[spring 并行4]异步

异步篇 1 介绍 2 除了线性.并行执行模式外,还有异步模式,它与事件编程一样,十分重要 在并发的异步模式中,不同的任务在时间线上是相互交错的,而且一切都是在单一控制流(单线程)下进行的 1.asyncio (过时) 基本使用 1.1 使用asyncio实现事件循环管理 什么是事件循环? 在计算系统中,能够产生事件的实体被称为事件源(event source),而负责协商管理事件的实体被称为事件处理器(event handler) 它实现了管理计算代码中所有事件的功能:在程序执行期间事件循环不断

GPU编程之: GPUvsCPU

由于GPU具有高并行结构,所以GPU在处理图像数据和复杂算法方面拥有比CPU更高的效率.GPU与CPU在结构上存在着差异,CPU大部分面积为控制器和寄存器,与之相比,GPU拥有更多的ALU(逻辑运算单元)用于数据处理,而非数据高速缓存和流控制,这样的结构适合对密集型数据进行并行处理.CPU执行计算任务时,一个时刻只处理一个数据,不存在真正意义的并行,而GPU具有多个处理器核,在一个时刻可以并行处理多个数据. GPU采用流式并行计算模式,可对每个数据进行独立的并行计算,所谓"对数据进行独立计算&q

深入浅出计算机组成原理:GPU(下)-为什么深度学习需要使用GPU?(第31讲)

一.引子 上一讲,我带你一起看了三维图形在计算机里的渲染过程.这个渲染过程,分成了顶点处理.图元处理.栅格化.片段处理,以及最后的像素操作.这一连串的过程, 也被称之为图形流水线或者渲染管线. 因为要实时计算渲染的像素特别地多,图形加速卡登上了历史的舞台.通过3dFx的Voodoo或者NVidia的TNT这样的图形加速卡,CPU就不需要再去处理一个个像素点的图元处理.栅格化和片段处理这些操作.而3D游戏也是从这个时代发展起来的. 你可以看这张图,这是“古墓丽影”游戏的多边形建模的变化.这个变化,

深度学习成长的烦恼

深度学习成长的烦恼 [编者按]深度学习尽管对当前人工智能的发展作用很大,然而深度学习工作者并非一帆风顺.Chris Edwards发表于Communications of the ACM的这篇文章,通过不同的深度学习研究人员的现身说法,列举了深度学习在不同场景下面临的一些挑战以及目前的解决方案.CSDN翻译此文,希望对国内深度学习从业者有借鉴意义. 理论和计算机硬件的进步促使神经网络成为在线服务的核心部分,如微软的Bing,采用神经网络驱动图像搜索和语音识别系统.这些公司提供这样的能力是希望在未

快速开发CUDA程序的方法

根据几年的CUDA开发经验,简单的介绍下CUDA程序的大概开发步骤,按照先修改CPU串行程序后移植到GPU平台的原理,把需要在GPU上做的工作尽量先在CPU平台上修改,降低了程序的开发难度,同时有利用bug的调试.通过实现一种快速.有效地CUDA并行程序开发的方法,提高CUDA并行程序开发效率,降低CUDA并行程序开发周期和难度. (1)    CPU串行程序分析 对于CPU串行程序,首先需要测试串行程序中的热点函数,以及分析热点函数的并行性: a)       热点测试 根据时间的测试结果确定

一天造出10亿个淘宝首页,阿里工程师如何实现?

阿里妹导读:双十一手淘首页个性化场景是推荐生态链路中最大的场景之一,在手淘APP承载了整体页面的流量第一入口,对用户流量的整体承接.分发.调控,以及用户兴趣的深度探索与发现上起着至关重要的作用. 原文:http://mp.weixin.qq.com/s/vpxLTcwenvlIvj5D-8uolg 双11手淘首页的几个重要推荐场景截图如下: 如上图所示,左一场景为AIO综合会场,包括AIO日常场景(淘抢购.有好货.清单等).双11人群会场及行业会场:中间为AIOplus场景卡片综合会场,包括5张

Keras官方中文文档:工具

utils 工具 本模块提供了一系列有用工具 CustomObjectScope keras.utils.generic_utils.CustomObjectScope() 提供定制类的作用域,在该作用域内全局定制类能够被更改,但在作用域结束后将回到初始状态.以with声明开头的代码将能够通过名字访问定制类的实例,在with的作用范围,这些定制类的变动将一直持续,在with作用域结束后,全局定制类的实例将回归其在with作用域前的状态. with CustomObjectScope({"MyOb

神经网络+增强学习

该文章转至: https://www.cnblogs.com/xlturing/p/5844555.html 马里奥AI实现方式探索 --神经网络+增强学习 儿时我们都曾有过一个经典游戏的体验,就是马里奥(顶蘑菇^v^),这次里约奥运会闭幕式,日本作为2020年东京奥运会的东道主,安倍最后也已经典的马里奥形象出现.平时我们都是人来玩马里奥游戏,能否可以让马里奥智能的自己闯关个呢?OK,利用人工智能的相关算法来进行自动化通关一直是一个热门的话题,最近最火的相关东东就是传说中的alphaGo啦.而在