首页 > 系统相关 >cuda 内存模型

cuda 内存模型

时间:2024-03-21 20:34:52浏览次数:22  
标签:__ int 模型 global cuda shared array include 内存

cuda内存模型其实概括来说就是下面两张图

双箭头代表可读可写,单箭头代表只读

1. local memory

#include<iostream>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

# define BLOCK_SIZE 256


__global__ void test_kernal()
{
	int  array[3];
	float value = 5;
	__shared__ int shared_value;
	printf("array is local = %s\n", __isLocal(array) ? "true" : "false");  //数组是local memory
	printf("value is local = %s\n", __isLocal(&value) ? "true" : "false");  //自定义的一个变量是...
	printf("shared_value is local = %s\n", __isLocal(&shared_value) ? "true" : "false"); //shared memory里的变量不是...
}



int main()
{
	test_kernal << <1, 1 >> >() ;
	cudaDeviceSynchronize(); //前面的任务失败后会返回一个error

	return 0;
}

输出

2. shared memory

#include<iostream>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

# define BLOCK_SIZE 256

//声明共享的变量,不能给初始值,需要由线程来初始化
__shared__ int shared_value2;

static __global__ void test_kernal()
{
	__shared__ int  shared_array[3]; //shared类型的变量,同一block的所有线程共用
	__shared__ int shared_value1; //声明共享的变量,不能给初始值,需要由线程来初始化

	if (threadIdx.x == 0) 
	{
		shared_value1 = 5;
		shared_value2 = 8;
		shared_array[0] = 33;
	}

	__syncthreads();

	printf("%d, shared_value1 = %d, shared_value2 = %d\n",threadIdx.x , shared_value1 , shared_value2);
	printf("%d, shared_array[0] = %d\n",shared_array[0]); 
}



int main()
{
	test_kernal << <1, 2 >> >() ;
	cudaDeviceSynchronize(); //前面的任务失败后会返回一个error

	return 0;
}

输出

#include<iostream>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

# define BLOCK_SIZE 256


static __global__ void test_kernal()
{
	//使用extern声明外部的动态大小共享内存,由启动核函数的第三个参数指定
	extern __shared__ int  shared_array[]; 

	if (threadIdx.x == 0) 
	{
		shared_array[0] = blockIdx.x;
	}

	__syncthreads();

	printf("%d, %d , %d\n",blockIdx.x , threadIdx.x , shared_array[0]); 
}



int main()
{ 
	test_kernal << <2, 2 ,sizeof(int)*5 >> >() ; //核函数里的数组大小为5
	cudaDeviceSynchronize(); //前面的任务失败后会返回一个error

	return 0;
}

输出:

3. global memory

1. 定义

#include<iostream>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

# define BLOCK_SIZE 256
__device__ float global_array[100];  //方式2 : __device__定义

static __global__ void test_kernal(float* device_ptr)
{
	printf("device_ptr is global = %s\n",__isGlobal(device_ptr) ? "true" : "false");
	printf("global_array is global = %s\n", __isGlobal(global_array) ? "true" : "false");
}



int main()
{ 
	float* device_ptr = nullptr;
	cudaMalloc(&device_ptr, sizeof(float) * 100); //方式1 : cudamalloc主机分配

	test_kernal << <1, 1>> >(device_ptr) ; //核函数里的数组大小为5
	cudaDeviceSynchronize(); //前面的任务失败后会返回一个error

	return 0;
}

输出:

2. memory transfer


cpu和gpu之间传输用PCle 速度慢:8GB/s
GPU和GPU Memory之间用GDDR5 速度快:144GB/s

尽量避免cpu和gpu之间的数据传输

3. Pinned memory(页锁定内存)

默认下,通过new,malloc函数分配的pageable data transfer(可置换页上的内存)可能会被os置换到虚拟内存上导致gpu无法安全获取

因此在pageable data transfer传送到device时,cuda驱动会分配一个Pinned Memory。
Pinned Memory常驻物理内存,不会被交换。可以使用DMA技术直接在cpu/gpu使用该内存

通过cudaMallocHost可以显示的分配Pinned Data Transfer

#include<iostream>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"


static __global__ void test_kernal(float* array)
{
	array[threadIdx.x] = threadIdx.x;
}

void global_memory2_pinned_memory()
{
	int num = 5;
	float* array = nullptr;
	cudaMallocHost(&array, sizeof(float) * num); //给array分配页锁定内存,是dma的,不需要cpu参与

	test_kernal << <1, num >> > (array);
	cudaDeviceSynchronize();

	for (int i = 0; i < num; i++) printf("array[%d] = %f\n", i, array[i]);
	cudaFreeHost(array); //释放
}

int main()
{
	global_memory2_pinned_memory();
	cudaDeviceSynchronize(); //前面的任务失败后会返回一个error

	return 0;
}

4. Unified Memory(统一内存)

将cpu和gpu看做一个整体进行管理和使用。分配的内存可以cpu/gpu直接访问

左图是将cpu和gpu的内存割裂开来看的,右图则是统一内存

static __global__ void test_kernal(float* array)
{
	array[threadIdx.x] = threadIdx.x;
}

void global_memory2_pinned_memory()
{
	int num = 5;
	float* array = nullptr;
	cudaMallocManaged(&array, sizeof(float) * num); //给array分配页锁定内存

	test_kernal << <1, num >> > (array);
	cudaDeviceSynchronize();

	for (int i = 0; i < num; i++) printf("array[%d] = %f\n", i, array[i]);
	cudaFree(array);
}

4. constant Memory

#include<iostream>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

//直接定义和初始化
__constant__ float warp_matrix[6] = { 1,2,3,4,5,6 };

static __global__ void test_kernal(float* array)
{ 
	//核函数内,常量内存不能修改,否则报错
	printf("warp_matrix[%d] = %f\n", threadIdx.x, warp_matrix[threadIdx.x]); 
}

void constant_memory()
{
	//修改常量内存的方法:覆盖
	float host_warp_matrix[6] = { 6,5,4,3,2,1 };
	test_kernal << <1, 6 >> > (warp_matrix);
	cudaMemcpyToSymbol(warp_matrix, host_warp_matrix, sizeof(float) * 6); //cudaMemcpyToSymbol用来拷贝数据到常量内存

	test_kernal << <1, 6>> > (warp_matrix);
	cudaDeviceSynchronize();
}

int main()
{
	constant_memory();
	cudaDeviceSynchronize(); //前面的任务失败后会返回一个error

	return 0;
}

标签:__,int,模型,global,cuda,shared,array,include,内存
From: https://www.cnblogs.com/algoshimo/p/18088189

相关文章

  • 【Jan】部署本地AI大模型
    Jan是一款开源的的本地AI部署软件,利用开源AI模型和自己的硬件(CPU、显卡),让我们可以在本地运行大语言模型,实现100%完全离线、免费的ChatGPT。目前支持Windows、macOS、Linux三个平台安装运行各大开源的AI大模型。项目地址:janhq/jan:Jan是ChatGPT的开源替代品Jan可在任......
  • 新人学习笔记之(盒子模型)
    一、盒子模型属性    1.width属性        (1)宽度:width:长度值|百分比|auto,最大宽度:max-width最小宽度:min-width.box1{width:300px;}.box2{min-width:1200px;}        2.height属性......
  • 首位脑机患者直播用意念玩游戏;快手自研大模型有信心半年内达 GPT4 水平丨RTE 开发者日
       开发者朋友们大家好: 这里是「RTE开发者日报」,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享RTE(RealTimeEngagement)领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「有看点的会议」,但内容仅代表......
  • Vue3、typeit、vue3-markdown-it仿文心一言前端代码对接大模型
    相关依赖"typeit":"^8.8.3","vue3-markdown-it":"^1.0.10",示例效果核心代码<template> <a-modal class="modal-container" style="min-width:1400px;" :visible="modalState.visible"......
  • 计算机网络参考模型
    计算机网络参考模型目录计算机网络参考模型OSI参考模型TCP/IP协议簇、端口号的组成数据封装的过程数据解封的过程OSI参考模型层次模型作用(发送)作用(接收)数据单元主要设备第七层应用层出:输入高级语言指令将数据展示在应用里数据计算机第六层表示层将人......
  • 钢材厂探秘:内部可视化模型带你领略工业之美
    在浩瀚的工业海洋中,钢材厂如同一座座巍峨的钢铁城堡,它们不仅见证了国家建设的辉煌历程,更是现代工业文明的生动写照。 可视化的3D模型仿佛将整个钢材厂的生产流程浓缩在了这方寸之间。从原材料的筛选、加工到成品的出厂,每一个环节都清晰可见,让人仿佛置身于繁忙的生产现场。 ......
  • 大模型应用开发:手把手教你部署并使用清华智谱GLM大模型
    部署一个自己的大模型,没事的时候玩两下,这可能是很多技术同学想做但又迟迟没下手的事情,没下手的原因很可能是成本太高,近万元的RTX3090显卡,想想都肉疼,又或者官方的部署说明过于简单,安装的时候总是遇到各种奇奇怪怪的问题,难以解决。本文就来分享下我的安装部署经验,包括本地和租用......
  • C++的内存管理
    1.C/C++内存分布我们可以先来了解一下具体的内存区域分布图,通过一个代码 那么我们想为什么要划分这些区域?为了方便管理因为我们在程序中有不同类型的数据(静态,局部,全局等)比如生命周期的不同,放到不同的区域进行管理哪个是我们重点关注的?堆区。因为其他区域不用管释......
  • 本地搭建深度学习训练环境(配置conda环境 cuda pytorch...)
    目录简介Nvidia驱动和cudatoolKit简介首先我们要下载的东西包括:anaconda(虚拟环境管理)pycharm(代码项目编辑器)Nvidia驱动和cudatoolKitpytorch(最好使用wheel)其中,anaconda和pycharm的下载比较简单,这里不在赘述。主要讲解后两个:Nvidia驱动和cudatoolKitNvidia驱动是向......
  • 内存CPU监控
    #-*-coding:utf-8-*-"""--------------------------------Time:2024/3/2111:50Author:NingDescription:xitong_jiankong.py系统内存、cpu使用情况检测--------------------------------"""fromloguruimportlo......