Nvidia CUDA初级教程6 CUDA编程一

Nvidia CUDA初级教程6 CUDA编程一

视频:https://www.bilibili.com/video/BV1kx411m7Fk?p=7
讲师:周斌

GPU架构概览

  • GPU特别使用于:
    • 密集计算,高度可并行计算
    • 图形学
  • 晶体管主要被用于:
    • 执行计算
    • 而不是
      • 缓存数据
      • 控制指令流

在这里插入图片描述

图中分别是CPU、GPU各个部件所占的芯片面积。可以看到,CPU芯片中大量部分是缓存和控制逻辑,而GPU中则绝大部分都是计算单元。

CUDA编程相关简介

CUDA的一些信息

  • 层次化线程集合
  • 共享存储
  • 同步

CUDA术语

主机端和设备端

  • HOST - 主机端,通常指CPU
    • 采用ANSI标准C语言编程
  • Device - 设备端,通常指GPU(数据可并行)
    • 采用ANSI标准C的扩展语言编程 (CUDA C)
  • HOST 和 Device 拥有各自的存储器
  • CUDA编程
    • 包括主机端和设备端两部分代码

  • Kernel 数据并行处理函数
    • 通过调用 Kernel 函数在设备端创建轻量级的线程,线程由硬件负责创建并调度

类似于 OpenCL 的 shader?

  • 核函数会在 N 个不同的 CUDA 线程上并行执行

    // 定义核函数
    __global__ void VecAdd(float* a, float* B, float* C) {int i = threadIdx.x;C[i] = A[i] + B[i];
    }int main() {// ...// 在N个线程上调用核函数VecAdd<<<1, N>>>(A, B, C);
    }
    

CUDA程序的执行

CUDA程序执行的流程大体上是这样的:当我们在CPU端的代码是串行执行的(这里简单地认为指令在CPU上串行执行),当遇到需要并行大量处理数据时,会调用核函数在GPU上进行计算,计算完成后将结果返回给CPU。

在这里插入图片描述

线程层次

  • Grid - 一维或多维线程块(block)
    • 一维或二维
  • Block - 一维线程
    • 一维,二维或三维
    • 一个 Grid 中的每个 Block 的线程数是一样的
    • Block 内部的每个线程可以:
      • 同步 Synchronize
      • 访问共享存储器 shared memory

一个线程可以类比为一个员工,一个 block 是一个科室,grid 是整个公司。

在这里插入图片描述

在这里插入图片描述

线程ID

每一个线程都有一个索引:threadIdx

  • 一维 Block Thread ID == Thread Index
  • 二维 Block (Dx, Dy)
    • 索引为 (x, y) 的 Thread ID == x + yDy
  • 三维 Block (Dx, Dy, Dz)
    • 索引为 (x, y) 的 Thread ID == x + yDy + zDxDy

代码实例

__global__ void MatAdd(float A[N][N], float B[N][N], float C[N][N]) {int i = threadIdx.x;int j = threadIdx.y;C[i][j] = A[i][j] + B[i][j];
}int main() {int numBlocks = 1;dim3 threadsPerBlock(N, N);MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);
}

每个 Block 中的线程的索引是二维的,这在我们处理二维数据(矩阵)时可以很方便地进行对应。

线程数

Thread Block 线程块

  • 线程的的集合
    • G80 和 GT200:多达512个线程
    • Fermi:多达1024个线程
  • 位于相同的处理器核(相同的SM)
  • 共享所在核的存储器

在这里插入图片描述

块索引

  • 块索引:blockIdx
  • 维度:blockDim
    • 一维,二维或三维
__global__ void MatAdd(float A[N][N], float B[N][N], float C[N][N]) {int i = blockIdx.x * blockDim.x + threadIdx.x;int j = blockIdx.y * blockDim.y + threadIdx.y;if (i < N && j < N)C[i][j] = A[i][j] + B[i][j];
}int main() {// ...dim3 threadsPerBlock(16, 16);dim3 numBlocks(N / threadsPerBlock.x, N / threadsPerBlock.y);MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);
}

例如 N = 32

  • 每个块有16x16个线程(跟N无关)
    • threadIdx([0, 15], [0, 15])
  • Grid 里面有 2x2 个线程块 block
    • blockIdx([0, 1], [0, 1])
    • blockDim = 16
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;

i = [0, 1] * 16 + [0, 15]

线程块之间

线程块彼此之间独立执行

  • 任意顺序:并行或串行
  • 被任意数量的处理器以任意顺序调度
    • 处理器的数量具有可扩展性

一个块内部的线程

一个块内部的线程有一些重要的特性:

  • 共享容量有限的低延迟存储器 (shared memory)
  • 同步执行
    • 合并访存
    • __syncThreads()
      • barrier - 块内线程一起等待所有的线程都
      • 轻量级线程

CUDA内存传输

主机端与设备端

CUDA内存传输

在这里插入图片描述

  • device 端代码可以:

    • 读写该线程的 registers
    • 读写该线程的local memory
    • 读写该线程所属的块的 shared memory
    • 读写grid的 global memory
    • 只读grid的 constant memory
  • host 端代码可以:

    • 读写grid的 global memory 和 constant memory
  • host 可以从 device 往返传输数据

    • global memory 全局存储器
    • constant memory 常量存储器

CUDA内存传输函数

  • 在设备端分配 global memory:cudaMalloc()
  • 释放存储空间 cudaFree()
float* Md;
int size = Width * Width * sizof(float);
cudaMalloc((void**)&Md, size);
//...
cudaFree(Md);

注意这里的指针 Md 是指向 device(GPU)上的存储空间。

  • 内存传输:cudaMemcpy()
    • host to host
    • host to device
    • device to host
    • device to device
cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice);
cudaMemcpy(P, Pd, size, cudaMemcpyDeviceToHost);

示例:矩阵相乘 Matrix Multiply

矩阵相乘简介

  • 向量
  • 点乘
  • 行优先或列优先
  • 每次点乘结果输出一个元素

在这里插入图片描述

矩阵相乘CPU实现

void MatrixMulOnHost(float* M, float* N, float* P, int width) {for (int i=0; i<width; ++i) {for (int j=0; j<width; ++j) {float sum = 0;for (int k=0; k<width; ++k) {float a = M[i * width + k];float b = N[k * width + j]:sum += a  * b;}P[i * width + j] = sum;}}
}

CUDA算法框架

三步走:

int main(void) {// 1 分配device空间// 2 在GPU上,并行计算MatrixMulOnDevice(M, N, P, width);// 3 将结果拷贝回CPU,并释放device空间return 0;
}

伪代码如下:

void MatrixMulOnDevice(float* M, float* N, float* P, int Width) {int size = Width * Width * sizeof(float);// 1cudaMalloc(Md, size);cudaMemcpy(Md, M, size, cudaMemcpyHostToDevice);cudaMalloc(Nd, size);cudaMemcpy(Nd, N, size, cudaMemcpyHostToDevice);cudaMalloc(Pd, size);// 2 调用cuda核函数,并行计算// 3cudaMemcpy(P. Pd, size, cudaMemcpyDeivceToHost)cudaFree(Md); cudaFree(Nd); cudaFree(Pd);
}

CUDA C 实现

矩阵相乘样例

在这里插入图片描述

目前版本矩阵相乘的问题

  • 在上述算法实现中最主要的性能问题是什么?
    • 访存
  • 主要的限制是什么?
    • 访存带宽

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/532529.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

由前中后遍历序列构建二叉树

由前/中/后遍历序列构建二叉树 基础 首先&#xff0c;我们需要知道前中后序三种深度优先遍历二叉树的方式的具体顺序&#xff1a; 前序&#xff1a;中左右中序&#xff1a;左中右后序&#xff1a;左右中 另外&#xff0c;要知道只有中序前/后序可以唯一确定一棵二叉树&…

手写nms

手写nms 计算宽高的时候加1是为什么&#xff1f; 本文总结自互联网的多种nms实现&#xff0c;供参考&#xff0c;非博主原创&#xff0c;各原文链接如下&#xff0c;也建议大家动手写一写。 Ref&#xff1a; 浅谈NMS的多种实现 目标窗口检测算法-NMS非极大值抑制 一、fas…

目标检测综述

目标检测综述 转自&#xff1a;https://zhuanlan.zhihu.com/p/383616728 论文参考&#xff1a;[Object Detection in 20 Years: A Survey][https://arxiv.org/abs/1905.05055] 引言 目标检测领域发展至今已有二十余载&#xff0c;从早期的传统方法到如今的深度学习方法&#x…

Nvidia CUDA初级教程7 CUDA编程二

Nvidia CUDA初级教程7 CUDA编程二 视频&#xff1a;https://www.bilibili.com/video/BV1kx411m7Fk?p8 讲师&#xff1a;周斌 本节内容&#xff1a; 内置类型和函数 Built-ins and functions线程同步 Synchronizing线程调度 Scheduling threads存储模型 Memory model重访 Matr…

详解优酷视频质量评价体系

万字长文 | 详解优酷视频质量评价体系 分享嘉宾&#xff5c;李静博士&#xff0c;阿里巴巴文娱集团资深算法专家&#xff0c;阿里巴巴大文娱摩酷实验室视频体验与质量团队负责人 整理出品&#xff5c;AICUG人工智能社区 本文地址&#xff1a;https://www.6aiq.com/article/1617…

视频质量评价:挑战与机遇

视频质量评价&#xff1a;挑战与机遇 转自&#xff1a;https://zhuanlan.zhihu.com/p/384603663 本文整理自鹏城实验室助理研究员王海强在LiveVideoStack线上分享上的演讲。他通过自身的实践经验&#xff0c;详细讲解了视频质量评价的挑战与机遇。 文 / 王海强 整理 / LiveVi…

关于二分法的边界问题及两种写法

关于二分法的边界问题及两种写法 二分查找法大家很熟悉了&#xff0c;对于一个有序序列&#xff0c;我们可以通过二分查找法在 O(logN)O(logN)O(logN) 的时间内找到想要的元素。但是&#xff0c;在代码实现的过程中&#xff0c;如果没有仔细理解清楚&#xff0c;二分法的边界条…

LeetCode上的各种股票最大收益

LeetCode上的各种股票最大收益 对于力扣平台上的股票类型的题目&#xff1a; 121 买卖股票的最佳时机 122 买卖股票的最佳时机 II 123 买卖股票的最佳时机 III 124 买卖股票的最佳时机 IV 309 最佳买卖股票时机含冷冻期 714 买卖股票的最佳时机含手续费 剑指 Offer 63. …

建设专业化运维服务团队必要性

信息系统的生命周期涵盖&#xff1a;设计、开发、测试、部署上线、运行维护。其中&#xff0c;运行维护阶段是信息系统生命周期中的关键环节&#xff0c;其执行效果直接影响系统是否能达到预期的运行目标。为了实现这个目标&#xff0c;我们必须建立一个以业务服务为导向的专业…

docker初探

docker初探 本文旨在介绍 docker 基本的安装、常用命令和常见概念的辨析&#xff0c;方便新手入门和笔者日后查阅&#xff0c;大部分内容整理自互联网&#xff0c;原出处在文中注明。 文章目录docker初探docker安装&#xff08;mac&#xff09;版本、信息相关命令version/info…

ubuntu安装zsh、oh-my-zsh及常用配置

ubuntu安装zsh、oh-my-zsh及常用配置 目前&#xff0c;ubuntu默认的shell是bash&#xff0c;但还有一种shell&#xff0c;叫做zsh它比bash更加强大&#xff0c;功能也更加完善&#xff0c;zsh虽说功能强大&#xff0c;但是配置比较复杂导致流行度不是很高 但是好东西终究是好…

Segmentaion标签的三种表示:poly、mask、rle

Segmentaion标签的三种表示&#xff1a;poly、mask、rle 不同于图像分类这样比较简单直接的计算机视觉任务&#xff0c;图像分割任务&#xff08;又分为语义分割、实例分割、全景分割&#xff09;的标签形式稍为复杂。在分割任务中&#xff0c;我们需要在像素级上表达的是一张…

tensorboard报错:ValueError Duplicate plugins for name projector 问题的出现及解决过程

tensorboard报错&#xff1a;ValueError: Duplicate plugins for name projector 问题的出现及解决过程 记录如题问题的出现及解决过程。 报错命令及信息 笔者在终端调用 tensorboard 时&#xff1a; tensorboard --logdirruns/ --bind_all报错&#xff1a; raise ValueEr…

发布自己的Python包(Pypi)

发布自己的Python包(Pypi) 我们经常使用 Pypi 来安装包&#xff0c;但是有时候我们也想要发布自己的 Pypi 包&#xff0c;有可能我们写了一个特别牛的包&#xff0c;也有可能我们只是想使用自己常用的一些轮子&#xff0c;可能这是我们日常编码中很常用的一些轮子&#xff0c;…

Ubuntu PPA 使用指南

Ubuntu PPA 使用指南 转自&#xff1a;https://zhuanlan.zhihu.com/p/55250294 一篇涵盖了在 Ubuntu 和其他 Linux 发行版中使用 PPA 的几乎所有问题的深入的文章。 如果你一直在使用 Ubuntu 或基于 Ubuntu 的其他 Linux 发行版&#xff0c;例如 Linux Mint、Linux Lite、Zorin…

如何在 Linux 中快速地通过 HTTP 提供文件访问服务

如何在 Linux 中快速地通过 HTTP 提供文件访问服务 转自&#xff1a;https://linux.cn/article-10205-1.html 如今&#xff0c;我有很多方法来通过 Web 浏览器为局域网中的其他系统提供单个文件或整个目录的访问。我在我的 Ubuntu 测试机上测试了这些方法&#xff0c;它们如下面…

Linux apt命令

Linux apt命令及其与apt-get的关系 转自&#xff1a;https://blog.csdn.net/taotongning/article/details/82320472、https://www.runoob.com/linux/linux-comm-apt.html apt&#xff08;Advanced Packaging Tool&#xff09;是一个在 Debian 和 Ubuntu 中的 Shell 前端软件包管…

杨宏宇:腾讯多模态内容理解技术及应用

杨宏宇&#xff1a;腾讯多模态内容理解技术及应用 分享嘉宾&#xff1a;杨宇鸿 腾讯 内容理解高级工程师 编辑整理&#xff1a;吴祺尧 出品平台&#xff1a;DataFunTalk 导读&#xff1a; 搜索内容的理解贯穿了整个搜索系统。我们需要从多个粒度理解搜索内容&#xff0c;包括语…

git登录相关操作梳理

git登录相关操作梳理 本文主要基于 Linux/Mac &#xff0c;Windows下未经测试&#xff0c;不过估计差不多&#xff0c;在 git bash 内操作即可。 创建ssh key并关联github等账号 因为本地Git仓库和GitHub仓库之间的传输是通过SSH加密传输的&#xff0c;GitHub需要识别是否是…

关于mmdetection上手的几点说明

关于mmdetection上手的几点说明 官方的文档很有参考价值&#xff0c;并且也有中文版&#xff0c;应当是大家上手 mmdetection 的第一参考&#xff0c;本文是记录一些笔者在小白阶段上手 mmdetection 时的一些心得&#xff0c;这些东西没有人提&#xff0c;可能是大佬们觉得这些…