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;
}



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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenSSL生成自签名证书

生成之前首先需要明白以下内容&#xff1a; 第三点的验证数字签名解释下&#xff1a;客户端将使用颁发机构的公钥解密得到的原始数据&#xff0c;再将原始数据通过哈希算法计算得到的哈希值&#xff08;此处应该是使用CA证书提供的哈希算法&#xff09;进行比对。如果两者一致&…

2022最新版-李宏毅机器学习深度学习课程-P46 自监督学习Self-supervised Learning(BERT)

一、概述&#xff1a;自监督学习模型与芝麻街 参数量 ELMO&#xff1a;94MBERT&#xff1a;340MGPT-2&#xff1a;1542MMegatron&#xff1a;8BT5&#xff1a;11BTuring NLG&#xff1a;17BGPT-3&#xff1a;175BSwitch Transformer&#xff1a;1.6T 二、Self-supervised Lear…

云计算:无所不能的超级英雄

引言 在这个奇妙的时代&#xff0c;云计算如同一位无所不能的超级英雄&#xff0c;无处不在。从智能家居到无人驾驶&#xff0c;从虚拟现实到人工智能&#xff0c;云计算为我们的生活带来了智能、便捷和有趣。它以其强大的能力和灵活性&#xff0c;令我们的生活变得更加智能化…

库存预占架构升级方案设计-交易库存中心

背景介绍 &#xfeff; 伴随物流行业的迅猛发展&#xff0c;一体化供应链模式的落地&#xff0c;对系统吞吐、系统稳定发出巨大挑战&#xff0c;库存作为供应链的重中之重表现更为明显。近三年数据可以看出&#xff1a; &#xfeff;&#xfeff; 接入商家同比增长37.64%、货…

rviz添加qt插件

一、增加rviz plugin插件 资料&#xff1a;http://admin.guyuehome.com/42336 https://blog.51cto.com/u_13625033/6126970 这部分代码只是将上面两个链接中的代码整合在了一起&#xff0c;整合在一起后可以更好的理解其中的关系 1、创建软件包 catkin_create_pkg rviz_tel…

css呼吸效果实现

实现一个图片有规律的大小变化&#xff0c;呈现呼吸效果&#xff0c;怎么用CSS实现这个呼吸效果呢 一.实现 CSS实现动态效果可以使用动画( animation)来属性实现&#xff0c;放大缩小效果可以用transform: scale来实现&#xff0c;在这基础上有了动画&#xff0c;就可以设置一个…

每日汇评:黄金将测试1935美元的200日移动均线

金价在美联储主席鲍威尔发表讲话之前仍然脆弱&#xff1b; 在市场情绪喜忧参半的情况下&#xff0c;美元与美债收益率走势艰难&#xff1b; 在上升的三角形破裂和看跌的相对强弱指数中&#xff0c;黄金价格看向200日移动均线&#xff1b; 黄金周四早时在略低于1950美元的三周…

访问者模式

详情可参考&#xff1a;https://zhuanlan.zhihu.com/p/380161731 意图&#xff1a;主要将数据结构与数据操作分离。 适用于&#xff1a;系统中有稳定的数据结构&#xff0c;且数据结构的功能经常发生变化。 双分派&#xff1a;我的理解是两次多态操作&#xff0c;动态获取对象…

mysql的备份和恢复

备份&#xff1a;完全备份 增量备份 完全备份&#xff1a;将整个数据库完整的进行备份 增量备份&#xff1a;在完全备份的基础之上&#xff0c;对后续新增的内容进行备份 备份的需求 1、在生产环境中&#xff0c;数据的安全至关重要&#xff0c;任何数据的都可能产生非常严重…

PHP保存时自动删除末尾的空格,phpstorm自动删除空白字符串

最近有个活儿&#xff0c;修改一个财务软件。 修改后给客户验收的过程中&#xff0c;客户反应有一个txt表格导出功能不能用了。之前是好的。 这次是新增&#xff0c;老的这个功能碰都没碰过&#xff0c;怎么能有问题呢&#xff1f;我心里OS 下班后我立马用系统导出TXT&#…

如何实现Debian工控电脑USB接口安全管控

Debian 作为工控电脑操作系统具有稳定性、安全性、自定义性和丰富的软件包等优势&#xff0c;适用于要求高度可靠性和安全性的工控应用。 Debian 作为工控电脑操作系统在工业控制领域有很大优势&#xff0c;包括&#xff1a; 稳定性&#xff1a;Debian 的发布版以其稳定性而闻…

ThinkPHP框架 开源 虚拟资源分享付费下载PHP网站源码

源码测评&#xff1a;非常不错的资源分享网站&#xff0c;仿的是之前的码农网&#xff0c;这个网站也是在码农网的源码基础上修改而来&#xff0c;这个是用ThinkPHP仿的&#xff0c;还不错&#xff0c;测试的时候发现后台上传图片报错&#xff0c;其他暂时没有发现。 转载自…

Leetcode刷题【hot100】盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜容器。 示例…

OpenAI 工程师平均薪酬 92.5 万美元;SpaceX 明年将每两天发射一次丨 RTE 开发者日报 Vol.81

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

【爬虫与反爬虫】从技术手段与原理深度分析

文章目录 1. 爬虫的基本概念1.1. 什么是爬虫1.2. 爬虫的价值1.3. 爬虫的分类 3. 爬虫技术原理与实现4. 反爬虫基本概念4.1. 什么是反爬虫4.2. 反爬虫的目的4.3. 反什么样的爬虫 5. 由浅到深的反爬虫技术手段5.1. 主动常见型反爬虫5.1.1. 基于爬虫行为5.1.2. 基于身份识别 6. 被…

Banana Pi BPI-M6(Raspberry Pi 5 替代品)初始设置及固件烧录

Banana Pi BPI-M6&#xff1a;初始设置和镜像烧录 Banana Pi BPI-M6 的首次测试 在上一篇文章中&#xff0c;我比较了Banana Pi BPI-M6和Raspberry Pi 5的硬件特性。两者都拥有出色的硬件技术&#xff0c;在性能方面应该不会有太大的问题。 今天我想测试一下 Banana Pi。作为…

Zabbix“专家坐诊”第210期问答汇总

问题一 Q&#xff1a;zabbix触发器条件基于历史趋势的函数有示例吗&#xff1f;还有这些基于历史趋势的函数&#xff0c;具体是读取历史表还是趋势表&#xff1f; A&#xff1a;读历史表&#xff0c;示例可以看看官网的。 https://www.bookstack.cn/read/zabbix-5.0-zh/37cf0…

Qt实现自定义多选下拉列表

目录 前言1、 功能描述2、代码实现总结 前言 本文记录了一种通过继承 QComboBox 实现下拉列表多选功能的方法。效果如下图所示&#xff1a; 1、 功能描述 普通的下拉列表只支持选择一个选项&#xff0c;在软件开发过程中&#xff0c;经常会遇到下拉列表支持选择多个选项的需…

网络原理---拿捏网络层:IP协议

文章目录 IP协议4位版本4位首部长度、选项8位服务类型&#xff08;TOS&#xff09;16位总长度16位标识、3位标志、13位片偏移8位生存时间&#xff08;TTL&#xff09;8位协议16位首部校验和32位源IP地址、32位目的IP地址解决IP地址不够用的问题动态分配IP地址NAT机制&#xff0…

RPA处理重复工作,助力高效资金管理

在瞬息万变的市场竞争中&#xff0c;众多企业开展多元化经营以获取最大的经济效益。然而&#xff0c;企业的多元化经营程度越高&#xff0c;协调活动可能造成的决策延误也越多&#xff0c;其资金管理往往将面临更大的考验。随着新技术的发展&#xff0c;更多具备多元产业的企业…