CUDA各种内存和使用方法

news2024/12/27 11:11:51

文章目录

      • 1、全局内存
      • 2、局部内存
      • 3、共享内存
        • 3.1 静态共享内存
        • 3.2 动态共享内存
      • 4、纹理内存
      • 5、常量内存
      • 6、寄存器内存
      • 7、用CUDA运行时API函数查询设备
      • CUDA 错误检测

在这里插入图片描述在这里插入图片描述

1、全局内存

特点:容量最大,访问延时最大,所有线程都可以访问。 线性内存。
cudaMalloc() 动态分配内存
cudaFree() 释放内存
_device_ int buff[N] 使用固定长度的静态全局内存
动态内存使用cudaMemcpy 在host 和 device之间传输
静态内存 host 和 device 之间传输数据:
cudaMemcpyToSymbol() host 传到device
cudaMemcpyFromSymbol() device传到host

在这里插入图片描述

#include <cuda.h>
#include <cuda_runtime.h>
__device__ int d_x = 1;
__device__ int d_y[2];
__global__ void cudaOut(void) {
	d_y[0]+= d_x;
	d_y[1]+= d_x;
}
int main(void) {
	int h_y[2] = { 10,20 };
	CHECK(cudaMemcpyToSymbol(d_y, h_y, sizeof(int) * 2));
	cudaOut<<<1,1>>>();
	CHECK(cudaDeviceSynchronize());
	CHECK(cudaMemcpyFromSymbol(h_y, d_y, sizeof(int) * 2));
	return 0;
}

2、局部内存

特点:存储线程私有的局部变量,在寄存器内存不足时使用。

3、共享内存

特点:片上内存,访问速度快,线程块内共享
使用:存储线程块中的共享数据,加速线程间的数据处理
每个SM的共享内存数量是一定的,也就是说,如果在单个线程块中分配过度的共享内存,将会限制活跃线程束的数量;合适分配单个线程块的共享内存,使得SM的使用率最大化,起到加速的作用。

例如:blockSize = 128,一个SM有2048个线程,那么一个SM能同时处理16个block。如果SM有96K的共享内存,每个block则分配96 / 16 = 6K,太大其他block无法获得使用。

__syncthreads 通常用于协调同一块中线程间的通信。

__global__ void kernel_function(parameters) {
     // 假设算法的特殊设计导致对变量 data 的访问不得不是非合并的
     // 1. 定义共享内存
     __shared__ float s_data [data_size];
     // 2. 将 data 复制到共享内存
     s_data[copy_index] = data[copy_index];
     // 3. 等待线程块中所有线程完成复制操作
     __syncthreads();
     // 4. 进行操作(包含非合并内存访问)
     operations(data);
}

3.1 静态共享内存
// 静态共享内存
__global__ void staticReverse(int* d, int n){
   	__shared__ int s[64];
    int t = threadIdx.x;
    s[t] = d[t];
    __syncthreads();
}
int main(void){
staticReverse << <1, n >> > (d_d, n);
}
3.2 动态共享内存

调用时指定共享内存大小
如果一个共享内存的大小在编译时是未知的, 则需要添加 extern修饰,在内核调用时动态分配。

__global__ void dynamicReverse(int* d, int n){
    extern __shared__ int s[];
    int t = threadIdx.x;
    s[t] = d[t];
}
int main(void){
dynamicReverse << <1, n, n * sizeof(int) >> > (d_d, n);
}

4、纹理内存

特点:优化二维数据的访问,具有缓存加速
使用:适用图像处理和大规模数据访问

5、常量内存

特点:存储只读数据,访问速度快,广播式访问。数量有限,最多64KB
使用:频繁访问的常量数据,所有线程块都能访问,全局可见。
使用_constant_修饰
只能通过cudaMemcpyToSymbol() 或**cudaMemcpyToSymbolAsync()**进行数据传输

const int N = 4;
// 定义结构体
struct ConstStruct {
    float array[N];
    float singleValue;
};
// 常量内存变量声明
__constant__ float d_constArray[N];    // 数组
__constant__ float d_singleValue;      // 单个变量
__constant__ ConstStruct d_constStruct; // 结构体
// 定义核函数
__global__ void kernelFunction(float* d_result, float* d_result_s) {
    int idx = threadIdx.x;
    if (idx < N) {
        // 从常量内存中读取常量数组和单个值,将结果存入 d_result
        d_result[idx] = d_constArray[idx] + d_singleValue;
        // 从常量内存中的结构体读取数据,将数组中的值和单个值相加,并存入 d_result_s
        d_result_s[idx] = d_constStruct.array[idx] + d_constStruct.singleValue;
    }
}
int main() {
    // 将数据从主机复制到常量内存
    CHECK(cudaMemcpyToSymbol(d_constArray, h_array, N * sizeof(float)));
    CHECK(cudaMemcpyToSymbol(d_singleValue, &h_singleValue, sizeof(float)));
    CHECK(cudaMemcpyToSymbol(d_constStruct, &h_constStruct, sizeof(ConstStruct)));
	kernelFunction << <1, N >> > (d_result, d_result_s);
}

6、寄存器内存

特点:片上内存,访问速度最快
使用:局部变量

7、用CUDA运行时API函数查询设备

该段介绍用 CUDA 运行时 API 函数查询所用 GPU 的规格 ,可以通过以下代码查看显卡的信息:

#include <iostream>
#include <cuda_runtime.h>
#include "error_check.cuh"
int main(int argc, char* argv[]) {
	int device_id = 0;//如果你不止一个显卡,可以切换ID,输出不同显卡的信息
	if (argc > 1) device_id = atoi(argv[1]);
	CHECK(cudaSetDevice(device_id));
	cudaDeviceProp prop;
	CHECK(cudaGetDeviceProperties(&prop, device_id));
	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);//个SM可以分配的最大共享内存总量
	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);//每个SM可以分配的最大寄存器总量
	printf("Maximum number of threads per block: %d\n", prop.maxThreadsPerBlock);
	printf("Maximum number of threads per SM: %d\n", prop.maxThreadsPerMultiProcessor);//每个SM可以同时运行的最大线程数量
	return 0;
}


CUDA 错误检测

#define CHECK(call)                 \    
do                                  \
{                                   \
    const cudaError_t error_code = call;                \
    if (error_code != cudaSuccess)                  \
    {                                   \
    printf("CUDA ERROR:\n");                    \
        printf("    FILE:   %s\n", __FILE__);           \
        printf("    LINE:   %d\n", __LINE__);           \
        printf("    ERROR CODE: %d\n", error_code);         \
        printf("    ERROR TEXT: %s\n", cudaGetErrorString(error_code)); \
    exit(1);                            \
    }                                   \
} while(0)

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

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

相关文章

青少年科普教学系统平台的设计与实现springboot

摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对高校教师成果信息管理混乱&#xff0c;出错率高&#xff0c;信息安…

Vue2:v-for创建echart图表时不能使用动态ref,要使用动态id

项目中需要创建一组图表+表格的组合,一共15组,为了便于维护,希望使用v-for来创建,而不是写出15组<div>,但是动态指定echart的ref时,频繁遭遇init失败,提示“TypeError: this.dom.getContext is not a function”。过程记录如下。 实现效果 要实现的效果如下图,…

Ch9 形态学图像处理

Ch9 形态学图像处理 blog点此处&#xff01;<--------- 四大算子相应性质。 腐蚀、膨胀、开闭之间的含义、关系 文章目录 Ch9 形态学图像处理预备知识(Preliminaries)膨胀和腐蚀(Dilation and Erosion)腐蚀膨胀膨胀与腐蚀的对偶关系 开闭操作(Opening and Closing)开运算闭…

likeAdmin架构部署(踩坑后的部署流程

1、gitee下载 https://gitee.com/likeadmin/likeadmin_java.git 自己克隆 2、项目注意 Maven&#xff1a;>3.8 ❤️.9 (最好不要3.9已经试过失败 node &#xff1a;node14 (不能是18 已经测试过包打不上去使用14的换源即可 JDK&#xff1a;JDK8 node 需要换源 npm c…

如何解决 ‘adb‘ 不是内部或外部命令,也不是可运行的程序或批处理文件的问题

在cmd中输入 adb &#xff0c;显示 ‘adc‘ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件的问题 解决办法&#xff1a;在环境变量中添加adb所在的路径 1、找到 adb.exe 的所在的文件路径&#xff0c;一般在 Android 安装目录下 \sdk\platform-tools\adb.exe…

使用 OpenCV 在图像中添加文字

在图像处理任务中&#xff0c;我们经常需要将文本添加到图像中。OpenCV 提供了 cv2.putText() 函数&#xff0c;可以很方便地在图像上绘制文本&#xff0c;支持多种字体、颜色、大小和位置等参数。 本文将详细介绍如何使用 OpenCV 在图像中添加文字&#xff0c;介绍 cv2.putTe…

解线性方程组

直接三角分解&#xff08;LU分解&#xff0c;Doolittle分解&#xff09; ATM分解&#xff08;追赶法&#xff0c;Crout分解&#xff0c;克劳特分解&#xff09; 平方根法&#xff08;Cholesky分解&#xff0c;乔列斯基分解&#xff09; 矩阵的范数

17.2、应急事件场景与处理流程

目录 常见网络安全应急事件场景网络安全应急处理流程应急演练类型 常见网络安全应急事件场景 应急事件的处理场景&#xff0c;分成四类场景&#xff0c;恶意程序事件&#xff0c;网络攻击事件&#xff0c;还有网站相关的一些安全事件&#xff0c;最后是拒绝服务事件 恶意程序…

并发编程 - 死锁的产生、排查与解决方案

在多线程编程中&#xff0c;死锁是一种非常常见的问题&#xff0c;稍不留神可能就会产生死锁&#xff0c;今天就和大家分享死锁产生的原因&#xff0c;如何排查&#xff0c;以及解决办法。 线程死锁通常是因为两个或两个以上线程在资源争夺中&#xff0c;形成循环等待&#xf…

关于埃斯顿机器人文件导出或者系统日志导出

关于埃斯顿机器人文件导出或者日志导出&#xff0c;登录模式&#xff0c;选择高级设置&#xff0c;控制器备份恢复 选择U盘导入地址&#xff0c;点击导出&#xff0c;等待时间30秒就可以查看文件格式和系统日志

5G CPE接口扩展之轻量型多口千兆路由器小板选型

多口千兆路由器小板选型 方案一: 集成式5口千兆WIFI路由器小板方案二:交换板 + USBwifiUSB WIFI选型一USBwifi选型二:四口千兆选型一四口千兆选型二:四口千兆选型三:部分5G CPE主板不支持Wifi,并且网口数量较少,可采用堆叠方式进行网口和wifi功能 扩展,本文推荐一些路由…

PromptGIP:Unifying lmage Processing as Visual Prompting Question Answering

“Unifying Image Processing as Visual Prompting Question Answering” 文章提出了一种名为 PromptGIP 的通用模型&#xff0c;将图像处理任务统一为视觉提示问答范式&#xff0c;在多个图像处理任务上展现出良好性能&#xff0c;为通用图像处理提供了新的思路和方法。 confe…

【MySQL】索引 面试题

文章目录 适合创建索引的情况创建索引的注意事项MySQL中不适合创建索引的情况索引失效的常见情况 索引定义与作用 索引是帮助MySQL高效获取数据的有序数据结构&#xff0c;通过维护特定查找算法的数据结构&#xff08;如B树&#xff09;&#xff0c;以某种方式引用数据&#xf…

Doxygen 使用指南

Doxygen 是一个文档生成工具&#xff0c;可以从源代码中的注释生成高质量的文档&#xff0c;支持多种编程语言&#xff08;如 C/C、Python、Java 等&#xff09;。以下是 Doxygen 的基本使用方法。 1. 安装 Doxygen 1.1 下载 Doxygen 访问 Doxygen 官网。根据操作系统选择合适…

Jensen-Shannon Divergence:定义、性质与应用

一、定义 Jensen-Shannon Divergence&#xff08;JS散度&#xff09;是一种衡量两个概率分布之间差异的方法&#xff0c;它是Kullback-Leibler Divergence&#xff08;KL散度&#xff09;的一种对称形式。JS散度在信息论、机器学习和统计学等领域中具有广泛的应用。 给定两个概…

一个特别的串口通讯

背景 设备是EPICS流式细胞仪&#xff0c;这个设备的控制系统是在DOS系统上的。数据存储在硬盘上&#xff0c;不带串口通讯功能。我们遇到了这个设备后&#xff0c;就开发了一个DOS下的执行程序通过串口&#xff0c;将最新的数据自动上传到服务器上。 编译工具 Turbo C 数据…

4.系统学习-集成学习

集成学习 前言Bias and Variance过拟合&#xff08;overfitting&#xff09;与欠拟合&#xff08;underfitting&#xff09;集成学习为什么有效&#xff1f;Blending 模型集成Stakcing 模型集成Bagging模型集成Bagging 模型集成算法流程&#xff1a;Boosting模型集成作业 前言 …

电商项目高级篇07-redisson分布式锁

redisson分布式锁 1、引入maven依赖2、config类3、可重入锁设计 1、引入maven依赖 <!--引入redisson--><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.12.0</version></depend…

Nginx的性能分析与调优简介

Nginx的性能分析与调优简介 一、Nginx的用途二、Nginx负载均衡策略介绍与调优三、其他调优方式简介四、Nginx的性能监控 一、Nginx的用途 ‌Nginx是一种高性能的HTTP和反向代理服务器&#xff0c;最初作为HTTP服务器开发&#xff0c;主要用于服务静态内容如HTML文件、图像、视…

递归算法常见问题(Java)

问题&#xff1a;斐波那契数列,第1项和第2项都为1&#xff0c;后面每一项都为相邻的前俩项的和,求第n个数 解法&#xff1a;每一个数都为前俩个数之和&#xff0c;第1项和第2项都为1&#xff0c;所以写 方法f1(n)即为求第n个数&#xff0c;那么f1(n-1)为求第n-1个数&#xff0…