cuda 并行计算

article/2025/9/13 16:37:55

1 简介

 2006年,NVIDIA公司发布了CUDA,CUDA是建立在NVIDIA的GPU上的一个通用并行计算平台和编程模型,基于CUDA编程可以利用GPU的并行计算引擎来更加高效地解决比较复杂的计算难题。CUDA是NVIDIA公司所开发的GPU编程模型,它提供了GPU编程的简易接口,基于CUDA编程可以构建基于GPU计算的应用程序。CUDA提供了对其它编程语言的支持,如C/C++,Python,Fortran等语言。

       GPU并不是一个独立运行的计算平台,而需要与CPU协同工作,可以看成是CPU的协处理器,因此当我们在说GPU并行计算时,其实是指的基于CPU+GPU的异构计算架构。在异构计算架构中,GPU与CPU通过PCIe总线连接在一起来协同工作,CPU所在位置称为为主机端(host),而GPU所在位置称为设备端(device),如下图所示。

        可以看到GPU包括更多的运算核心,其特别适合数据并行的计算密集型任务,如大型矩阵运算,而CPU的运算核心较少,但是其可以实现复杂的逻辑运算,因此其适合控制密集型任务。另外,CPU上的线程是重量级的,上下文切换开销大,但是GPU由于存在很多核心,其线程是轻量级的。因此,基于CPU+GPU的异构计算平台可以优势互补,CPU负责处理逻辑复杂的串行程序,而GPU重点处理数据密集型的并行计算程序,从而发挥最大功效。

2 cuda编程模型基础

CUDA编程模型是一个异构模型,需要CPU和GPU协同工作。在CUDA中,hostdevice是两个重要的概念,我们用host指代CPU及其内存,而用device指代GPU及其内存。CUDA程序中既包含host程序,又包含device程序,它们分别在CPU和GPU上运行。同时,host与device之间可以进行通信,这样它们之间可以进行数据拷贝。典型的CUDA程序的执行流程如下:

  1. 分配host内存,并进行数据初始化;
  2. 分配device内存,并从host将数据拷贝到device上;
  3. 调用CUDA的核函数在device上完成指定的运算;
  4. 将device上的运算结果拷贝到host上;
  5. 释放device和host上分配的内存。

上面流程中最重要的一个过程是调用CUDA的核函数来执行并行计算,kernel是CUDA中一个重要的概念,kernel是在device上线程中并行执行的函数,核函数用__global__符号声明,在调用时需要用<<<grid, block>>>来指定kernel要执行的线程数量,在CUDA中,每一个线程都要执行核函数,并且每个线程会分配一个唯一的线程号thread ID,这个ID值可以通过核函数的内置变量threadIdx来获得。

      由于GPU实际上是异构模型,所以需要区分host和device上的代码,在CUDA中是通过函数类型限定词开区别host和device上的函数,主要的三个函数类型限定词如下:

  • __global__:在device上执行,从host中调用(一些特定的GPU也可以从device上调用),返回类型必须是void,不支持可变参数参数,不能成为类成员函数。注意用__global__定义的kernel是异步的,这意味着host不会等待kernel执行完就执行下一步。
  • __device__:在device上执行,单仅可以从device中调用,不可以和__global__同时用。
  • __host__:在host上执行,仅可以从host上调用,一般省略不写,不可以和__global__同时用,但可和__device__,此时函数会在device和host都编译。

       kernel在device上执行时实际上是启动很多线程,一个kernel所启动的所有线程称为一个网格(grid),同一个网格上的线程共享相同的全局内存空间,grid是线程结构的第一层次,而网格又可以分为很多线程块(block),一个线程块里面包含很多线程,这是第二个层次。

cuda内存模型

一般CPU一个核只支持一到两个硬件线程,而GPU往往在硬件层面上就支持同时成百上千个并发线程。不过这也要求我们在GPU编程中更加高效地管理这些线程,以达到更高的运行效率。在CUDA编程中,线程是通过线程网格(Grid)、线程块(Block)、线程束(Warp)、线程(Thread)这几个层次进行管理的.

  第二点,为了达到更高的效率,在CUDA编程中我们需要格外关注内存的使用。与CPU编程不同,GPU中的各级缓存以及各种内存是可以软件控制的,在编程时我们可以手动指定变量存储的位置。具体而言,这些内存包括寄存器、共享内存、常量内存、全局内存等。这就造成了CUDA编程中有很多内存使用的小技巧,比如我们要尽量使用寄存器,尽量将数据声明为局部变量。而当存在着数据的重复利用时,可以把数据存放在共享内存里。而对于全局内存,我们需要注意用一种合理的方式来进行数据的合并访问,以尽量减少设备对内存子系统再次发出访问操作的次数。

3 cuda编程实例

在进行CUDA编程前,可以先检查一下自己的GPU的硬件配置,通过下面的程序获得GPU的配置属性:

  int dev = 0;cudaDeviceProp devProp;CHECK(cudaGetDeviceProperties(&devProp, dev));std::cout << "使用GPU device " << dev << ": " << devProp.name << std::endl;std::cout << "SM的数量:" << devProp.multiProcessorCount << std::endl;std::cout << "每个线程块的共享内存大小:" << devProp.sharedMemPerBlock / 1024.0 << " KB" << std::endl;std::cout << "每个线程块的最大线程数:" << devProp.maxThreadsPerBlock << std::endl;std::cout << "每个EM的最大线程数:" << devProp.maxThreadsPerMultiProcessor << std::endl;std::cout << "每个SM的最大线程束数:" << devProp.maxThreadsPerMultiProcessor / 32 << std::endl;// 输出如下使用GPU device 0: GeForce GT 730SM的数量:2每个线程块的共享内存大小:48 KB每个线程块的最大线程数:1024每个EM的最大线程数:2048每个EM的最大线程束数:64

        kernel的这种线程组织结构天然适合vector,matrix等运算,如我们实现两个矩阵的加法,每个线程负责处理每个位置的两个元素相加,代码如下所示。线程块大小为(16, 16),然后将N*N大小的矩阵均分为不同的线程块来执行加法运算

// Kernel定义
__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() 
{ ...// Kernel 线程配置dim3 threadsPerBlock(16, 16); dim3 numBlocks(N / threadsPerBlock.x, N / threadsPerBlock.y);// kernel调用MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C); ...
}


http://chatgpt.dhexx.cn/article/AyPBnTQX.shtml

相关文章

数据 并行

first 含义是计算机内包含一组处理单元&#xff08;PE&#xff09;&#xff0c;每一个处理单元存储一个&#xff08;或多个&#xff09;数据元素。当机器执行顺序程序时&#xff0c;可对应于全部或部分的内部处理单元所存的数据同时操作。 将并行处理技术引入信息检索领域 把数…

并行的常见问题和注意事项

关于Oracle中的并行&#xff0c;可以说是一把双刃剑&#xff0c;用得好&#xff0c;可以充分利用系统资源&#xff0c;提升数据库的处理能力&#xff0c;用得不好&#xff0c;可能会适得其反。 并行的基本使用方法&#xff0c;对于大部分SQL开发者和DBA来说&#xff0c;并行的一…

并发和串行、并行的概念

先抛开语言不管&#xff0c;只聊概念&#xff0c;说起并发&#xff0c;就很容易想到它和串行、并行的区别。 串行&#xff1a;一次只能取得一个任务并执行这个任务&#xff0c;这个任务执行完后面的任务才能继续&#xff1b; 并发&#xff1a;指的是在同一个时间段内&#xf…

牛腩新闻发布--过程或函数 'news_selectByCaId' 需要参数 '@caid',但未提供该参数(二)

发现问题 之前有一篇博客是因为存储过程中没有添加相应的函数&#xff0c;导致出现了“过程或函数 ‘news_selectByCaId’ 需要参数 ‘caid’&#xff0c;但未提供该参数”&#xff0c;这次继续出现了这样一个问题&#xff0c;但是出现的错误就不再过程函数中了&#xff0c;而…

牛腩新闻发布--过程或函数 'news_selectByCaId' 需要参数 '@caid',但未提供该参数(三)

发现问题 这篇博客是建立在“牛腩新闻发布–过程或函数 ‘news_selectByCaId’ 需要参数 ‘caid’&#xff0c;但未提供该参数&#xff08;二&#xff09;”&#xff0c;因为在那篇博客中说出了我当时遇到的“过程或函数 ‘news_selectByCaId’ 需要参数 ‘caid’&#xff0c;…

【牛腩】-'T_news_selectByCaId' 需要参数 '@caid',但未提供该参数。”

问题截图 解决方案&#xff1a; 改动存储过程 BEGINselect n.id,n.title,n.createTime,c.[name],n.caId from T_news ninner join T_category c on n.caIdc.id and n.caIdcaidorder by n.createTime desc END检查传参是或否正确如果以上都没有错误&#xff0c;那就看一下是否…

【重要补充】关于第三方潜在SDK导致的5.1.2Data use sharing

接上一篇《关于IDFA、CAID和「5. 1.2 - Data use & sharing」》后&#xff0c;我们发现&#xff0c;苹果在14.5出来前&#xff0c;对于IDFA替代方案之数据收集的审核打击力度越来越大。 因5.1.2条款被拒&#xff0c;目前可以确认的原因有以下两大&#xff1a; 一、如果你…

spring笔记⑬——spring事务

事务的四个特征 CAID是事务的四个特征&#xff0c;所有事务都必须满足以下特性。 原子性&#xff08;Atomicity&#xff09;&#xff1a;一个事务要么全部执行&#xff0c;要么不执行一致性(Consistency)&#xff1a;事务的运行并不改变数据库中数据的一致性隔离性&#xff0…

SQL查询语句(内联,as,in,通配符)

最近在学习牛腩新闻发布系统&#xff0c;正如牛老师所说&#xff0c;作为一个优秀的.NET开发人员&#xff0c;对SQL语句不熟怎么能行呢&#xff0c;接下来就总结下牛老师写的存储过程中SQL语句&#xff0c;挺经典&#xff0c;举一反三 首先先展示出来适用于系统的三张表 新闻类…

【微信小程序 | 实战开发】配置微信小程序APPID并快速接入

写在前面: 你是否想要掌握人工智能的最新技术和应用?你是否想要成为未来社会的创新者和领导者?你是否想要和全球的优秀导师和同学一起学习和交流?如果你的答案是肯定的,那么欢迎来到床长人工智能教程网站,这里是你实现梦想的起点! 个人名片: 🐼作者简介:一名大一在校…

获取苹果收集设备ID的方法

目录 问题 解决 问题 如果我们想要通过工具获取苹果手机 iPhone 或者 iPad 的设备 ID&#xff0c;也就是 UDID。这个时候&#xff0c;很多人可能会问 UDID 是什么&#xff0c;UDID 是 iOS 设备的一个唯一识别码&#xff0c;每台 iOS 设备都有一个独一无二的编码&#xff0c;…

浅谈大数据广告下个人隐私保护,开发者视角的广告原理

本文已收录于 Github CodeClass 和 Gitee CodeClass 致力于打造高质量编程学习课堂&#xff0c;内含百篇原创技术文章&#xff0c;千本计算机开源电子书&#xff0c;谷歌、阿里大神开源 LeetCode 题解&#xff0c;各类编程学习资源&#xff0c;欢迎 star &#xff0c;一起学习&…

简单理解MySQL的存储引擎

1、什么是存储引擎&#xff1f; 在说明存储引擎之前&#xff0c;首先你需要简单了解MqSQL的整体架构。 从上图可知&#xff0c;存储引擎位于整体架构的最底层。 存储引擎真正负责了MySQL中数据的存储和提取。 可以这样理解&#xff1a; 其实我们平时写的各种SQL语句相当于指…

iOS隐私新规如何破局?盗版SKAdnetwork可行吗?

背景&#xff1a;   在2020年的开发者大会上&#xff0c;苹果宣布iOS14设备将会在App首次打开时主动弹窗请求是否选择允许广告追踪&#xff0c;即被获取设备的IDFA。这也就意味着新系统需要用户手动选择允许&#xff0c;而旧系统是手动选择关闭&#xff0c;这一关键改变无异…

牛腩新闻发布--过程或函数 'news_selectByCaId' 需要参数 '@caid',但未提供该参数(一)

发现问题 今天敲击牛腩,在敲击Web页面的List.aspx之后,点击Ctrl+F5运行,发现运行不了,首先是数据库中调取数据有问题,因为这个数据是用存储过程调取的,所以需要修改存储过程,这时候只需要改成如下代码就行: 将这个更改完之后就可以在数据库中调取到应需要的数据了,但是…

【牛腩】DELETE 语句与 REFERENCE 约束“FK_news_category“冲突。该冲突发生于数据库“newssystem“,表“dbo.news“, column ‘caId‘

【前言】 牛腩中删除类别的时候会提示受到主外键的约束&#xff0c;导致无法删除这个类别。 【问题描述】 DELETE 语句与 REFERENCE 约束"FK_news_category"冲突。该冲突发生于数据库"newssystem"&#xff0c;表"dbo.news", column ‘caId’。…

【牛腩】过程或函数 ‘news_selectByCaId‘ 需要参数 ‘@caid‘,但未提供该参数

【前言】 在运行牛腩的时候会有提示过程或者函数缺少参数。这个是因为存储过程中写的缺少参数&#xff0c;添加相应的参数就可以了。 【问题描述】 过程或函数 ‘news_selectByCaId’ 需要参数 ‘caid’&#xff0c;但未提供该参数 过程或函数 ‘news_selectByContent’ 需要…

关于IDFA、CAID和「5. 1.2 - Data use sharing」

今天&#xff0c;2021年3月18日&#xff0c;突然收到了之前从未遇到过的拒审邮件&#xff0c;邮件原文如下&#xff1a; 发件人 Apple 5. 1.2 - Data use & sharing Please review this information carefully as it impacts your app’s availability on the App Store a…

中国广告协会的CAID方案

前些时间看到一个消息&#xff0c;腾讯、百度和字节跳动测试工具绕开苹果的ATT&#xff08;AppTrackingTransparency&#xff0c;简称 ATT&#xff0c;旨在保护用户隐私的应用追踪透明度框架&#xff09;&#xff0c;估计这个应该是在测试CAID。 过一两天又出现一个消息&#x…

微信H5链接包装

最近看到好多人问一个问题&#xff0c;就是在微信中发游戏链接给好友&#xff0c;让链接显示成一个抖音的样式&#xff0c;如下&#xff1a; 这种链接包装&#xff0c;做起来说难不难&#xff0c;说简单也不简单。网上很多服务商都可以做&#xff0c;不过靠谱程度就参差不齐了…