CUDA学习笔记7——CUDA内存组织

CUDA内存组织

CUDA设备内存的分类与特征
内存类型物理位置访问权限可见范围生命周期
1全局内存芯片外可读写所有线程和主机端由主机分配与释放
2常量内存芯片外只读所有线程和主机端由主机分配与释放
3纹理和表面内存芯片外一般只读所有线程和主机端由主机分配与释放
4寄存器内存芯片内可读写单个线程所在线程
5局部内存芯片外可读性单个线程所在线程
6共享内存芯片内可读性单个线程块所在线程块
  1. 全局内存:核函数中所有线程都能访问其中的数据。
    用cudaMalloc()为全局内存变量分配设备内存;
    用cudaMemcpy()将主机数据复制到全局内存;

  2. 常量内存:一共64KB,只读,可见范围与生命周期与全局内存一样,访问速度比全局内存快;在核函数未满用 _constant_ 定义变量;并使用cudaMemcpyToSymbol()将数据从主机端复制到设备的常量内存。

  3. 纹理内存与表面内存:类似于常量内存(可见范围与生命周期相同);

  4. 寄存器:在核函数中定义的不加任何限定符的变量一般来说放在寄存器中,核函数定义不加任何限定符的数组可能放于寄存器,也可能放于局部内存中;

  5. 局部内存:寄存器放不下的变量,索引值不能在编译时确定的数组;

  6. 共享内存:与寄存器类似,存在于芯片上,仅次于寄存器的读写速度;

CUDA中的内存组织示意图

在这里插入图片描述

GPU设备规格查询
#include <stdio.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"int main()
{int device_id = 0;cudaDeviceProp prop;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);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("----------------------------- \n");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.0);printf("Maximum number of registers per SM:					%d K\n", prop.regsPerMultiprocessor / 1024.0);printf("Maximum number of threads per block:					%d \n", prop.maxThreadsPerBlock);printf("Maximum number of threads per SM:					%d \n", prop.maxThreadsPerMultiProcessor);return 0;
}

在这里插入图片描述

全局内存的合并与非合并访问

合并访问:一个线程束对全局内存的一次访问(读/写)导致最少数量的数据传输;否则为非合并访问。

利用共享内存和统一内存优化矩阵乘

在这里插入图片描述

#include <stdio.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include<math.h>
#include <malloc.h> 
#include <opencv2/opencv.hpp>
#include <stdlib.h>//利用share memory 和统一内存优化矩阵乘#define M 1000
#define N 500
#define K 1000__managed__ int a[M*N];
__managed__ int b[N*K];
__managed__ int c_gpu[M*K];
__managed__ int c_cpu[M*N];#define BLOCK_SIZE 16__global__ void gpu_matrix(int* a, int* b, int* c, int m, int n, int k)
{__shared__ int sub_a[BLOCK_SIZE][BLOCK_SIZE];__shared__ int sub_b[BLOCK_SIZE][BLOCK_SIZE];int x = blockIdx.x*blockDim.x + threadIdx.x;int y = blockIdx.y*blockDim.y + threadIdx.y;int tmp = 0;int idx;for (int step = 0; step < N/BLOCK_SIZE; step++){int step_x = step*BLOCK_SIZE + threadIdx.x;int step_y = y;idx = step_y*n + step_x;if (step_x>n || step_y>m){sub_a[threadIdx.y][threadIdx.x] = 0;}else{sub_a[threadIdx.x][threadIdx.x] = a[idx];}step_x = x;step_y = step*BLOCK_SIZE + threadIdx.y;idx = step * k + step_x;if (step_x >= k || step_y>=n){sub_b[threadIdx.y][threadIdx.x] = 0;}else{sub_b[threadIdx.y][threadIdx.x] = b[idx];}__syncthreads();for (int i = 0; i < BLOCK_SIZE; i++){tmp += sub_a[threadIdx.y][i] * sub_b[i][threadIdx.x];}__syncthreads();}if (x<k && y<m){c[y*k + x] = tmp;}}void cpu_matrix(int* a, int* b, int* c, int m, int n, int k)
{for (int y = 0; y < m; y++){for (int x = 0; x < k; x++){int tmp = 0;for (int step = 0; step < n; step++){tmp += a[y*n + step] * b[step*n + x];}c[y*k + x] = tmp;}}}int main()
{for (int y = 0; y < M; y++){for (int x = 0; x < N; x++){a[y * N + x] = rand() % 1024;}}for (int y = 0; y < N; y++){for (int x = 0; x < K; x++){b[y*K + x] = rand() % 1024;}}unsigned int grid_x = (K + BLOCK_SIZE - 1) / BLOCK_SIZE;unsigned int grid_y = (M + BLOCK_SIZE - 1) / BLOCK_SIZE;dim3 dimGrid(grid_x, grid_y);dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);gpu_matrix<<<dimGrid, dimBlock>>>(a, b, c_gpu, M, N, K);cpu_matrix(a, b, c_cpu, M, N, K);bool errors = false;for (int y = 0; y < M; y++){for (int x = 0; x < K; x++){if (fabs(c_cpu[y*K + x] - c_gpu[y*K + x]) > (1.0e-10)){errors = true;}}}printf("Result: %s\n", errors ? "Error" : "Pass");return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

技术分享 | app自动化测试(Android)-- 特殊控件 Toast 识别

Toast 是 Android 系统中的一种消息框类型&#xff0c;它属于一种轻量级的消息提示&#xff0c;常常以小弹框的形式出现&#xff0c;一般出现 1 到 2 秒会自动消失&#xff0c;可以出现在屏幕上中下任意位置。它不同于 Dialog&#xff0c;它没有焦点。Toast 的设计思想是尽可能…

Java进击框架:Spring-数据存取(七)

Java进击框架&#xff1a;Spring-数据存取&#xff08;七&#xff09; 前言事务管理声明式事务管理 DAO支持JDBC的数据访问使用JdbcTemplate控制数据库连接JDBC批处理操作封装 SQL 语句中的参数 使用R2DBC进行数据访问对象关系映射(ORM)数据访问HibernateJPA XML模式 前言 参考…

渗透测试学习day2

文章目录 连接靶机靶机&#xff1a;Fawn 解题过程Task 1Task 2Task 3Task 4Task 5Task 6Task 7Task 8Task 9Task 10Task 11Task 12 总结 连接靶机 详细过程可参考day1 靶机&#xff1a;Fawn 难度&#xff1a;very easy &#xff08;ftp服务的靶机&#xff09; 解题过程 T…

23个优秀开源免费BI仪表盘

BI也称为商业智能&#xff0c;是收集、分析和展示数据以支持决策者做出明智的业务决策的过程。BI帮助组织将其原始的生产数据转化为有意义的见解或者知识&#xff0c;以推动其业务战略。BI能够为组织改善决策、提高效率和提升资源利用率。 BI仪表盘是BI系统的重要组成部分&…

工程(十二)Ubuntu20.04LSD_SLAM运行

博主创建了一个科研互助群Q&#xff1a;772356582&#xff0c;欢迎大家加入讨论。这是一个科研互助群&#xff0c;主要围绕机器人&#xff0c;无人驾驶&#xff0c;无人机方面的感知定位&#xff0c;决策规划&#xff0c;以及论文发表经验&#xff0c;以方便大家很好很快的科研…

(待完善)python学习参考手册

这里写目录标题 观前浅谈:学习路线 :学习心得笔记:Step1:简单但一问不知怎么的组织语言去回答的小问题:什么是提示符?python解释器是什么?请正在阅读本文的朋友,安装一下PyCharm以及如何进行科学的省钱:Python中的命令行模式和交互模式的区别是什么?请正在阅读本文的朋友安装…

支持存档的书签服务LinkWarden

什么是 LinkWarden &#xff1f; Linkwarden 是一个自托管、开源协作书签管理器&#xff0c;用于收集、组织和存档网页。目标是将您在网络上找到的有用网页和文章组织到一个地方&#xff0c;并且由于有用的网页可能会消失&#xff08;参见链接失效的必然性&#xff09;&#xf…

基于单片机的甲醛检测器设计

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 技术交流认准下方 CSDN 官方提供的联系方式 文章目录 概要 一、设计的主要内容二、系统硬件设计三、软件设计4.1 程序结构流程图原理图 四、结论五、 文章目录 概要 本文将要提…

把wpf的窗体保存为png图片

昨晚在stack overflow刷问题时看到有这个问题&#xff0c;今天早上刚好来尝试学习一下 stack overflow的链接如下&#xff1a; c# - How to render a WPF UserControl to a bitmap without creating a window - Stack Overflow 测试步骤如下&#xff1a; 1 新建.net frame…

【达梦数据库】学习笔记

【达梦数据库】学习笔记 【一】如何使用idea连接达梦数据库【二】idea项目导入本地的达梦数据库驱动jar包&#xff08;方法一&#xff09;【三】idea项目把本地的达梦数据库驱动jar包安装到本地仓库&#xff08;方法二&#xff09; 【一】如何使用idea连接达梦数据库 &#xf…

深入理解强化学习——多臂赌博机:乐观初始值

分类目录&#xff1a;《深入理解强化学习》总目录 目前为止我们讨论的所有方法都在一定程度上依赖于初始动作值 Q 1 ( a ) Q_1(a) Q1​(a)的选择。从统计学角度来说&#xff0c;这些方法&#xff08;由于初始估计值&#xff09;是有偏的。对于采样平均法来说&#xff0c;当所有…

蓝桥杯双周赛算法心得——串门(双链表数组+双dfs)

大家好&#xff0c;我是晴天学长&#xff0c;树和dfs的结合&#xff0c;其邻接表的存图方法也很重要。需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .串门 2) .算法思路 串门&#xff08;怎么存图很关键&#xf…