IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> CUDA C编程7: 内存管理之固定内存 -> 正文阅读

[C++知识库]CUDA C编程7: 内存管理之固定内存

系列文章目录



前言

这里开始介绍CUDA C编程内存管理中的固定内存相关知识。


一、固定内存相关知识点

系统分配的主机内存默认是可分页的,GPU不能在可分页主机内存上安全地访问数据,这是因为主机操作系统在物理位置上移动数据时,GPU无法控制。

当从可分页主机内存传输数据到设备内存时,CUDA驱动程序首先分配临时页面锁定的或固定的主机内存,将主机源数据复制到固定内存中,然后从固定内存传输数据给设备内存。

使用如下函数可直接分配固定主机内存:
c u d a E r r o r _ t c u d a M a l l o c H o s t ( v o i d ? ? ? d e v P t r , s i z e _ t ? c o u n t ) ; cudaError\_t cudaMallocHost(void\ **devPtr, size\_t\ count); cudaError_tcudaMallocHost(void???devPtr,size_t?count);

固定内存是页面锁定的并且对设备来说是可访问的,由于固定内存能被设备直接访问,所以允许更好的带宽进行读写。

需要注意的是,分配过多的固定内存可能会降低主机系统的性能,这是因为它减少了用于存储虚拟内存数据的可分页内存的数量。

使用如下函数释放固定主机内存:
c u d a E r r o r _ t ? c u d a F r e e H o s t ( v o i d ? ? p t r ) ; cudaError\_t\ cudaFreeHost(void\ *ptr); cudaError_t?cudaFreeHost(void??ptr);

CPU与GPU通过固定内存传输数据流程如下图所示(引用自参考资料):
在这里插入图片描述

二、固定内存示例

#include <iostream>
#include <cuda.h>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
#include <device_functions.h>

int main()
{
	//set up device
	int dev = 0;
	cudaSetDevice(dev);

	//memory size
	unsigned int isize = 1 << 22;
	unsigned int nbytes = isize * sizeof(float);

	//get device information
	cudaDeviceProp stDeviceProp;
	cudaGetDeviceProperties(&stDeviceProp, dev);
	printf("starting at ");
	printf("device %d: %s memory size %d nbyte %5.2fMB\n", dev,
		stDeviceProp.name, isize, nbytes / (1024.0f * 1024.0f));

	//allocate the host memory
	//float* h_a = (float*)malloc(nbytes);
	float* h_a = nullptr;
	cudaError_t err = cudaMallocHost(&h_a, nbytes);//fixed page global memory
	if (err != cudaSuccess)
	{
		printf("cudaMallocHost failed!\n");
		goto EXIT;
	}

	//allocate the device memory
	float* d_a;
	cudaMalloc(&d_a, nbytes);//pageable global memory

	//initialize the host memory
	for (unsigned int i = 0; i < isize; i++)
		h_a[i] = 0.5f;

	//transfer data from the host to the device
	cudaMemcpy(d_a, h_a, nbytes, cudaMemcpyHostToDevice);
	//cudaMemcpy(d_a, h_a, nbytes, cudaMemcpyHostToHost);

	//tansfer data from the device to the host
	cudaMemcpy(h_a, d_a, nbytes, cudaMemcpyDeviceToHost);
	//cudaMemcpy(h_a, d_a, nbytes, cudaMemcpyHostToHost);

	EXIT:
	//free memory
	
	if (d_a != nullptr)
	{
		cudaFree(d_a);
	}

	if (h_a != nullptr)
	{
		cudaFreeHost(h_a);
		//free(h_a);
	}
		

	//reset device
	cudaDeviceReset();

	system("pause");
	return 0;
}

可分页的全局内存程序nvprof分析结果:
在这里插入图片描述固定内存程序nvprof分析结果:
在这里插入图片描述

对比固定内存与可分页内存运行时间可知,固定内存访问速度(Duration)更快,吞吐量(Throughput)更大。


总结

使用固定内存在CPU与GPU间传输数据有更高的性能,但是要慎用。本人也是现学现卖,如果有任何失误之处,欢迎大神们指正。

参考资料

《CUDA C编程权威指南》

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-10 22:13:22  更:2022-03-10 22:13:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:16:01-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码