CUDA存储器详解
来源:互联网 发布:山东网络作家协会 编辑:程序博客网 时间:2024/06/06 06:34
为了更好的在kernel函数中提高数据访问效率,我们需要理解CUDA各个存储器模型的特点,合理的分配存储空间。
-------------------华丽的分割线-------------------
一、存储器比较
每个线程拥有自己的register and loacal memory;(可读可写)
每个线程块拥有一块shared memory;(可读可写)
所有线程都可以访问global memory;(可读可写)
还有,可以被所有线程访问的只读存储器:constant memory and texture memory (只读)
通过上述图,我们理解为什么shared和register拥有同样的访问速度,shared memory 和 register 位于 GPU 片内。全局存储三个:global memory,constant memory,texture memory.
存储器关系图,如图所示:
二、各类存储器细讲
1、 寄存器Register
寄存器是GPU上的高速缓存器,其基本单元是寄存器文件,每个寄存器文件大小为32bit. Kernel中的局部(简单类型)变量第一选择是被分配到Register中。
特点:每个线程私有,速度快。
2、 局部存储器 local memory
当register耗尽时,数据将被存储到local memory。如果每个线程中使用了过多的寄存器,或声明了大型结构体或数组,或编译器无法确定数组大小,线程的私有数据就会被分配到local memory中。但是local memory 的数据是被保存在显存中的,速度很慢。
特点:每个线程私有;没有缓存,慢。
注:在声明局部变量时,尽量使变量可以分配到register。如:
unsigned int mt[3]; 改为: unsigned int mt0, mt1, mt2;
使用常量内存性能提升的原因:
I:对常量内存的单次读操作可以广播到其他的“邻近”线程。这将节约15次读取操作。(为什么是15,因为“邻近”指半个线程束,一个线程束包含32个线程的集合。)
II: 常量内存的数据将缓存起来,因此对相同地址的连续读操作将不会产生额外的内存通信量。
注:定义常数存储器时,需要将其定义在所有函数之外,作用于整个文件
1 __constant__ int devVar;2 cudaMemcpyToSymbol(devVar, hostVar, sizeof(int), 0, cudaMemcpyHostToDevice)3 cudaMemcpyFromSymbol(hostVar, devVar, sizeof(int), 0, cudaMemcpyDeviceToHost)
#include "cuda_runtime.h"#include "device_launch_parameters.h"#include <stdio.h>#define SIZE 124//***declare the constant value***//两种方法赋值:1-定义直接初始化 2-定义后调用函数初始化cudaMemcpyToSymbol__constant__ int constArray[SIZE];__constant__ int cosntArray_Result[SIZE];__constant__ int constNumber = 10;//********************************__global__ void addKernel(){int idx = threadIdx.x + blockDim.x * blockIdx.x;cosntArray_Result[idx] = constNumber + constArray[idx];}int main(){int inArray[SIZE] = {0};size_t size = SIZE * sizeof(int);int *result = NULL;result = (int*)malloc(size);//初始化数据for (int i = 0; i < SIZE; i++) {inArray[i] = i+1;}//copy host data to constant memory 如果不初始化常量内存,将默认数组各元素为0cudaMemcpyToSymbol(constArray, inArray, size);//call kernel fundim3 threadPerBlock(16);dim3 blockNum((SIZE + threadPerBlock.x - 1) / threadPerBlock.x);//计算输入数据和输出数据均采用常量内存addKernel << <blockNum , threadPerBlock >> > ();//copy constant data to host datacudaMemcpyFromSymbol(result, cosntArray_Result, size);//show datafor (int i = 0; i < SIZE; i++) {printf("%5d", result[i]);} return 0;}结果:
形式:分为一维纹理内存:texture<float> texconst 和 二维纹理内存 texture<float> texconst 。
- CUDA存储器详解
- CUDA存储器
- CUDA存储器模型
- CUDA存储器模型
- cuda存储器类型
- CUDA学习: 共享存储器
- cuda存储器模型
- CUDA中的存储器类型
- CUDA 存储器模型
- CUDA存储器模型
- CUDA存储器模型
- CUDA存储器模型概述
- CUDA纹理存储器
- CUDA存储器模型
- CUDA存储器模型
- CUDA学习笔记之 CUDA存储器模型
- CUDA学习笔记之 CUDA存储器模型
- CUDA学习笔记之CUDA存储器模型
- Spring不能直接@autowired注入Static变量
- svn的merge使用例子
- 安霸(ambarella) s2lm视频处理流程
- java多态
- easy 1 : 461. Hamming Distance
- CUDA存储器详解
- 缓存、缓存算法和缓存框架比较
- 聪明的老板才不招工资低的程序员
- Codeforces 808C Tea Party 题解
- kafka
- eclipse主题
- 数据库索引
- 记录一次kernel内存泄漏的查找定位过程
- Python 安装redis