【CUDA 】第1章 基于CUDA的异构并行计算

更全面的资料参考:第1章 基于CUDA的异构并行计算
2024.09.11 第一章剩余内容:1.3代码实践以及课后习题,由于目前还无法调用gpu遗留
2024.09.18 已解决,分配了账号,远程ssh连接上了实验室的显卡;第一章课后第5题,访问不了cuda网站

第一章 基于CUDA的异构并行计算

1.1 并行计算

计算原则:一个大的问题同时划分为多个同时解决的小问题
并行计算:多个计算资源,多个同时解决的小问题安排在不同的计算资源上
并行程序:只要包含并发执行
任务相关性:一个的输出是另一个的输入
CUDA编程解决数据并行步骤:数据划分①块划分②周期划分

块划分周期划分
数据块内为连续数据块内数据更少
块与线程块安排给任意线程,一个线程同一时间只能处理一个块相邻线程处理相邻块,每个线程可处理多个块
备注为待处理线程选择新块,意味着要跳过和现有线程一样多的块

程序性能对块大小敏感,划分方式与计算机架构密切相关。

GPU核心与CPU核心:

GPU核心CPU核心
核心轻核心重
处理简单逻辑数据并行处理复杂逻辑控制
优化并行吞吐量优化串行程序

eg:这里的核心是指上下文切换以及开销

1.2 异构计算

异构架构:GPU是CPU的协处理器(设备端)
异构应用:主机代码(CPU)+设备代码(GPU)
应用由CPU初始化,CPU代码管理设备端的环境、代码和数据
GPU容量特征:

GPU容量特征CUDA核心数内存大小
性能指标峰值计算性能内存带宽

CUDA API:驱动API 和 运行时API(不能混合使用,只能二选一用,这本书用运行时API

驱动API运行时API
层级低,难编程(类似汇编语言)层级高,在驱动API上层(类似高级语言),运行时API分解并传给下级驱动API运算

CUDA程序=主机代码(CPU)+设备代码【核代码】(GPU)

主机代码设备代码
运行位置CPUGPU
编程语言C扩展的CUDA C
编译器C编译器nvcc编译器

CUDA C是C语言的拓展,可以直接将C语言移植到CUDA C程序

1.3 用GPU输出Hello World

CUDA编程结构:

  1. 分配GPU内存
  2. 从CPU内存拷贝数据到——>GPU内存
  3. 调用CUDA核函数
  4. 将结果从GPU内存拷回——>CPU内存
  5. 释放GPU内存

##出现的问题1:各种报错
怀疑的解决方法:
1、修改编码,用vim创建的编码是ascii——>用iconv命令改成uft-8
2、修改后缀名——>后缀名为cu会报错,后缀名为c会警告,后缀名为cpp无警告
最后解决方式:不是nvidia的显卡,所以文件名.cu不能用,改成.cpp就可以;还有一台nvidia显卡,在那个上面可以用.cu

##出现的问题2:nvcc编译后,生成可执行文件hello,查看可执行文件
解决:执行可执行文件linux命令./hello

$ ./hello
Hello World from CPU!

##出现的问题3:使用nvcc -arch sm_20编译时,提示如下

$ nvcc -arch sm_20 helloGpu.cu -o hello
nvcc fatal   : Value 'sm_20' is not defined for option 'gpu-architecture'

原因:这本书比较老,里面的内容是当年的英伟达显卡架构,但实验室的显卡是较新的版本,查询当前显卡架构,修改sm后面对应的值
解决:换成sm_86
参考文章: 问题全流程解释
查看显卡版本的linux命令
查找对应架构版本的代号

$ nvcc -arch sm_86 helloGpu.cu -o hello
$ ./hello
Hello World From cpu!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!

1.4 编程难吗

GPU编程主要在于对GPU架构的熟悉程度
CUDA中的概念:内存层次+线程层次
实际上编写程序,是单个线程调用的一小段串行代码GPU启动成千上万个线程并行化,所有线程执行相同计算
CUDA核的3个关键抽象(最小的一组语言拓展):①线程组层次②内存层次③障碍同步(在执行某个任务前,必须完成N个线程各自的任务,才能往下执行)

课后习题

2.移除cudaDeviceReset函数

$ ./hello
Hello World From cpu!

结果:核函数输出的gpu消失。【该函数作用:显示释放和清空当前进程与当前设备有关的所有资源】
???为什么这里消失

3.用cudaDeviceSynchronize函数代替cudaDeviceReset函数

$ ./hello
Hello World From cpu!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!

结果:核函数输出的gpu又出现了(疑似是因为同步)
【同步函数作用:由于主机和设备的执行具有异步性,该函数会阻塞调用它的主机线程,直至之前启动的核函数和数据传输都操作完成】
参考文章: CUDA:常用函数2

4.编译时移除设备架构标志

$ nvcc helloGpu.cu -o hello
$ ./hello
Hello World From cpu!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!
Hello World From GPU!

结果:看不出什么差别????
参考文章:nvcc的code、arch、gencode选项

5.阅读CUDA在线文档,谈谈CUDA支持哪些后缀文件编译?【网站登不上】

2024.09.18 网站登不上

6.编译时移除设备架构标志
修改代码为:

__global__ void helloFromGPU(void){
    int x = threadIdx.x;
    if(x==5){
        printf("Hello World From GPU thread %d!\n",x);
    }
    //printf("Hello World From GPU!\n");
}

shell结果:

./hello
Hello World From cpu!
Hello World From GPU thread 5!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值