CUDA编程笔记(5)
创始人
2024-05-16 16:56:28
0

文章目录

  • 前言
  • CUDA的内存组织
    • 全局内存
    • 常量内存
    • 纹理内存和表面内存
    • 寄存器
    • 局部内存
    • 共享内存
    • L1和L2缓存
    • SM的构成
  • API函数查询设备
  • 总结


前言

cuda的内存组织,在使用GPU时尽可能提高性能,合理的使用设备的内存也是十分重要的。

CUDA的内存组织

如表所示:

内存类型物理位置访问权限可见范围生命周期
全局内存在芯片外可读可写所有线程和主机端由主机分配和释放
常量内存在芯片外仅可读所有线程和主机端由主机分配和释放
纹理和表面内存在芯片外一般仅可读所有线程和主机端由主机分配和释放
寄存器内存在芯片内可读可写单个线程所在线程
局部内存在芯片外可读可写单个线程所在线程
共享内存在芯片内可读可写单个线程块所在线程块

全局内存

定义:这里的全局内存,指的是核函数中所有线程都能访问到数据的内存。
作用:保存核函数提供数据,并在主机与设备及设备与设备之间传递数据。
不在GPU芯片上,所以为核函数提供数据时具有较高的延迟和较低的访问速度。
内存容量基本和GPU的显存差不多。
是可读可写的。
动态全局内存变量:前面cuda数组相加的程序中定义的d_x,d_y,d_z就是动态分配的,要先通过cudaMalloc()为其分配设备内存和cudaMemcpy()将主机上的数据传递到设备上,然后在核函数中访问分配的内存和改变其中的数值。
静态全局内存变量:使用cudaMemcpyToSymbol()进行主机与设备之间的数据传输和cudaMemcpyFromSymbol()进行设备与主机之间的数据传输。在核函数中,可直接对静态全局内存变量进行访问,并不需要将它们以参数的形式传给核函数。
由以下方式在函数外部定义

__device__ T x;  // 单个变量
__device__ T y[N];	// 固定长度的数组

例子:
在这里插入图片描述

常量内存

定义:是有常量缓存的全局内存,数量有限,仅有64kb。
作用:和全局内存一样。
仅可读不可写,而且由于有缓存,常量内存的访问速度比全局内存要高。
使用:cuda数组相加的程序里的const int N,就是使用了常量内存的变量。

纹理内存和表面内存

定义:类似于常量内存
一般仅可读,表面内存也可写。对于计算能力不小于3.5的GPU来说,将某些只读全局内存数据用__ldg()函数通过只读数据缓存读取,既可以达到使用纹理内存的加速效果,又可使代码简洁。

寄存器

定义:在核函数中不加任何限定符的变量一般来说就存放于寄存器中(可能在局部内存中)。
寄存器可读可写。寄存器内存在芯片内,是所有内存中访问速度最高的,但其数量有限。
使用:cuda数组相加的程序里的 int n = blockDim.x * blockIdx.x + threadIdx.x;
其中n就是一个寄存器变量。在核函数中使用z[n] = x[n] + y[n],寄存器变量n并将赋值号右边计算出来的赋值给它。
生命周期与所属线程的生命周期一致,从定义它开始到线程结束。寄存器变量仅仅被一个线程可见,不同的线程中该寄存器变量名一样,但是变量的值是不同的,相当于另外创建了副本。

局部内存

定义:和寄存器几乎一样。
寄存器里放不下的变量可能放在局部内存里,这种判断是由编译器自动做。

共享内存

定义:与寄存器类似,但共享内存对整个线程块可见。
作用:减少对全局内存的访问,或者改善对全局内存的访问模式。
其生命周期与整个线程块一致。
使用:在核函数中要将一个变量定义为共享内存变量,就要在定义语句中加上一个限定符__shared__

__shared__ real s_y[128];

L1和L2缓存

从费米架构开始,有了SM层次的L1缓存(一级缓存)和设备层次的L2缓存(二级缓存)。
主要用来缓存全局内存和局部内存的访问,减少延迟。L1和L2缓存是不可编程的缓存(用户最多能引导编译器做一些选择)。

SM的构成

(1)一定数量的寄存器
(2)一定数量的共享内存
(3)常量内存的缓存
(4)纹理和表面内存的缓存
(5)L1缓存
(6)两个线程束调度器,用于在不同线程的上下文之间迅速切换及为准备就绪的线程束发出执行指令。
(7)执行核心:若干整型数运算的核心,若干单精度浮点数运算的核心,若干双精度浮点数运算的核心,若干单精度浮点数超越函数的特殊函数单元,若干混合精度的张量核心。

API函数查询设备

用一些cuda的api程序来查询设备的一些规格。

#include "error.cuh"
#include int main(int argc, char *argv[])
{// 设置查询的设备编号.int device_id = 0; if (argc > 1) device_id = atoi(argv[1]);// cudaSetDevice()函数将对所指定的设备进行初始化CHECK(cudaSetDevice(device_id));// 定义设备输出规格的一些结构体变量cudaDeviceProp prop;CHECK(cudaGetDeviceProperties(&prop, device_id));  // 得到了device_id设备的性质,存放在结构体变量中的prop中.printf("Device id:                                 %d\n", device_id);printf("Device name:                               %s\n",prop.name);printf("Compute capability:                        %d.%d\n",prop.major, prop.minor);printf("Amount of global memory:                   %g GB\n",prop.totalGlobalMem / (1024.0 * 1024 * 1024));printf("Amount of constant memory:                 %g KB\n",prop.totalConstMem  / 1024.0);printf("Maximum grid size:                         %d %d %d\n",prop.maxGridSize[0], prop.maxGridSize[1], prop.maxGridSize[2]);printf("Maximum block size:                        %d %d %d\n",prop.maxThreadsDim[0], prop.maxThreadsDim[1], prop.maxThreadsDim[2]);printf("Number of SMs:                             %d\n",prop.multiProcessorCount);printf("Maximum amount of shared memory per block: %g KB\n",prop.sharedMemPerBlock / 1024.0);printf("Maximum amount of shared memory per SM:    %g KB\n",prop.sharedMemPerMultiprocessor / 1024.0);printf("Maximum number of registers per block:     %d K\n",prop.regsPerBlock / 1024);printf("Maximum number of registers per SM:        %d K\n",prop.regsPerMultiprocessor / 1024);printf("Maximum number of threads per block:       %d\n",prop.maxThreadsPerBlock);printf("Maximum number of threads per SM:          %d\n",prop.maxThreadsPerMultiProcessor);return 0;
}

查询的一些设备设置:
在这里插入图片描述
从这些输出可以看出GPU的内存组织,和所占各内存的最大容量大小。

总结

cuda程序执行的计时方式和GPU性能加速的分析
参考:
如博客内容有侵权行为,可及时联系删除!
CUDA 编程:基础与实践
https://docs.nvidia.com/cuda/
https://docs.nvidia.com/cuda/cuda-runtime-api
https://github.com/brucefan1983/CUDA-Programming

相关内容

热门资讯

安卓子系统windows11,... 你知道吗?最近科技圈可是炸开了锅,因为安卓子系统在Windows 11上的兼容性成了大家热议的话题。...
电脑里怎么下载安卓系统,电脑端... 你有没有想过,你的电脑里也能装上安卓系统呢?没错,就是那个让你手机不离手的安卓!今天,就让我来带你一...
索尼相机魔改安卓系统,魔改系统... 你知道吗?最近在摄影圈里掀起了一股热潮,那就是索尼相机魔改安卓系统。这可不是一般的改装,而是让这些专...
安卓系统哪家的最流畅,安卓系统... 你有没有想过,为什么你的手机有时候像蜗牛一样慢吞吞的,而别人的手机却能像风一样快?这背后,其实就是安...
安卓最新系统4.42,深度解析... 你有没有发现,你的安卓手机最近是不是有点儿不一样了?没错,就是那个一直在默默更新的安卓最新系统4.4...
android和安卓什么系统最... 你有没有想过,你的安卓手机到底是用的是什么系统呢?是不是有时候觉得手机卡顿,运行缓慢,其实跟这个系统...
平板装安卓xp系统好,探索复古... 你有没有想过,把安卓系统装到平板上,再配上XP系统,这会是怎样一番景象呢?想象一边享受着安卓的便捷,...
投影仪装安卓系统,开启智能投影... 你有没有想过,家里的老式投影仪也能焕发第二春呢?没错,就是那个曾经陪你熬夜看电影的“老伙计”,现在它...
安卓系统无线车载carplay... 你有没有想过,开车的时候也能享受到苹果设备的便利呢?没错,就是那个让你在日常生活中离不开的iOS系统...
谷歌安卓8系统包,系统包解析与... 你有没有发现,手机更新换代的速度简直就像坐上了火箭呢?这不,最近谷歌又发布了安卓8系统包,听说这个新...
微软平板下软件安卓系统,开启全... 你有没有想过,在微软平板上也能畅享安卓系统的乐趣呢?没错,这就是今天我要跟你分享的神奇故事。想象你手...
coloros是基于安卓系统吗... 你有没有想过,手机里的那个色彩斑斓的界面,背后其实有着一个有趣的故事呢?没错,我要说的就是Color...
安卓神盾系统应用市场,一站式智... 你有没有发现,手机里的安卓神盾系统应用市场最近可是火得一塌糊涂啊!这不,我就来给你好好扒一扒,看看这...
黑莓平板安卓系统升级,解锁无限... 亲爱的读者们,你是否还记得那个曾经风靡一时的黑莓手机?那个标志性的全键盘,那个独特的黑莓体验,如今它...
安卓文件系统采用华为,探索高效... 你知道吗?最近安卓系统在文件管理上可是有了大动作呢!华为这个科技巨头,竟然悄悄地给安卓文件系统来了个...
深度系统能用安卓app,探索智... 你知道吗?现在科技的发展真是让人惊叹不已!今天,我要给你揭秘一个超级酷炫的话题——深度系统能用安卓a...
安卓系统的分区类型,深度解析存... 你有没有发现,你的安卓手机里藏着不少秘密?没错,就是那些神秘的分区类型。今天,就让我带你一探究竟,揭...
安卓系统铠无法兑换,揭秘无法兑... 最近是不是有很多小伙伴在玩安卓系统的游戏,突然发现了一个让人头疼的问题——铠无法兑换!别急,今天就来...
汽车安卓系统崩溃怎么刷,一键刷... 亲爱的车主朋友们,你是否曾遇到过汽车安卓系统崩溃的尴尬时刻?手机系统崩溃还能重启,但汽车系统崩溃了,...
miui系统可以刷安卓p系统吗... 亲爱的手机控们,你是否对MIUI系统情有独钟,同时又对安卓P系统的新鲜功能垂涎欲滴?今天,就让我带你...