CUDA编程学习笔记 之 页锁定内存(固定内存Pinned Memory)

主机内存分为 可分页内存(Pagable)页锁定内存(固定内存Pinned Memory)

CPU向GPU传输数据时是通过直接内存访问(DMA,Direct Memory Access)传输的。
但是主机虚拟内存中分配的数据在物理内存中是随时可能被移动的,所以当数据在可分页内存时,系统随时可能会移动数据,此时将该数据传输给GPU时,需要将可分页内存复制到一块“临时的”页锁定内存,然后再从这块“临时的页锁定内存“复制到GPU
因此使用页锁定内存会一定程度上加快数据在GPU与CPU之间的传输速度,虽然可能会涉及CPU内存之间的copy,但是CPU内存之间的拷贝速度是大于CPU–>GPU的速度的。

但是,页锁定内存是占用系统的物理内存的,并不能交换到磁盘上,当机器的物理内存比较少时程序运行会受到影响

因此页锁定内存在不再使用时需要立刻释放

分配页锁定内存:
①由cudaHostAlloc( )来进行分配
②在opencv的GPU模块中,申请固定内存存储图片时,可以使用下面的函数来申请

CudaMem img_host(cols,rows, CV_8UC1, CudaMem::ALLOC_PAGE_LOCKED)

释放页锁定内存:

cudaFreeHost ( )

下面是一个将图片传到页锁定内存的应用示例,其中还有相应的CUDA测试运行时间的代码

float feature_match_pl()
{
	//数据导入
	Mat img1 = imread("D:/Images/14.jpg", CV_LOAD_IMAGE_GRAYSCALE);
	CV_Assert(!img1.empty());//CV_Assert()若括号中的表达式值为false,则返回一个错误信息。
	Mat img2 = imread("D:/Images/15.jpg", CV_LOAD_IMAGE_GRAYSCALE);
	CV_Assert(!img2.empty());

	//耗时统计
	cudaEvent_t start, stop;
	float elapsedTime;
	cudaEventCreate(&start);
	cudaEventCreate(&stop);

	//计时开始
	cudaEventRecord(start, 0);

	//申请页锁定内存
	CudaMem img1_host(img1.cols, img1.rows, CV_8UC1, CudaMem::ALLOC_PAGE_LOCKED);
	CudaMem img2_host(img2.cols, img2.rows, CV_8UC1, CudaMem::ALLOC_PAGE_LOCKED);

	memcpy(img1_host.datastart, img1.datastart, img1_host.cols * img1_host.rows);
	memcpy(img2_host.datastart, img2.datastart, img2_host.cols * img2_host.rows);

	GpuMat img1_gpu, img2_gpu;

	//图像传输到设备
	img1_gpu.upload(img1_host);
	CV_Assert(!img1_gpu.empty());
	img2_gpu.upload(img2_host);
	CV_Assert(!img2_gpu.empty());

    //释放
	cudaFreeHost(&img1_host);
	cudaFreeHost(&img2_host);

	//计时结束
	cudaEventRecord(stop, 0);
	cudaEventSynchronize(stop);
	cudaEventElapsedTime(&elapsedTime, start, stop);

	cudaEventDestroy(start);
	cudaEventDestroy(stop);

	return (float)elapsedTime / 1000;
}


int main(int argc, char* argv[])
{
	//检查CUDA能否正常使用
	if (getCudaEnabledDeviceCount() == 0) {
		cerr << "此OpenCV编译的时候没有启用CUDA模块" << endl;
		return -1;
	}
	//输出所使用的GPU信息
	//cv::gpu::printShortCudaDeviceInfo(cv::gpu::getDevice());
	//for (int i = 0; i < 3; i++)
	//{
		float time2 = feature_match_pl();
		printf("使用页锁定内存耗时: %.6f s\n", time2);
	//}
	waitKey(0);
	return 0;
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值