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;
}
这段参数是一个Python命名空间(Namespace),其中包含了用于训练机器学习模型的一系列参数。具体解释如下: - aa: 随机种子相关参数,用于数据增强。 - batch_size: 每个批次的样本数量。 - clip_grad: 梯度裁剪的阈值。 - color_jitter: 颜色抖动增强的强度。 - cooldown_epochs: 学习率衰减后,在进行下一次衰减之前等待的 epochs 数量。 - cutmix: CutMix 数据增强的系数。 - cutmix_minmax: CutMix 增强中随机裁剪的最小和最大比例。 - data_path: 存储数据集的路径。 - data_set: 数据集名称。 - decay_epochs: 学习率衰减的 epochs 数量。 - decay_rate: 学习率衰减的比例。 - device: 训练设备,例如 CPU 或 GPU。 - dist_url: 分布式训练的 URL。 - distributed: 是否进行分布式训练。 - drop: Dropout 正则化的比例。 - drop_block: DropBlock 正则化的比例。 - drop_path: DropPath 正则化的比例。 - epochs: 训练 epochs 数量。 - eval: 是否在验证集上进行评估。 - inat_category: iNaturalist 数据集的分类方式。 - input_size: 输入图像的大小。 - load_pretrain: 是否加载预训练模型。 - lr: 初始学习率。 - lr_noise: 学习率噪声的系数。 - lr_noise_pct: 学习率噪声的占比。 - lr_noise_std: 学习率噪声的标准差。 - min_lr: 最小学习率。 - mixup: Mixup 数据增强的系数。 - mixup_mode: Mixup 增强的方式。 - mixup_prob: Mixup 增强的概率。 - mixup_switch: 是否在 Mixup 增强中打开随机开关。 - mixup_switch_prob: 随机开关打开的概率。 - model: 选择的模型名称。 - model_ema: 是否使用模型指数滑动平均(EMA)。 - model_ema_decay: 模型 EMA 的衰减率。 - model_ema_force_cpu: 是否强制在 CPU 上使用模型 EMA。 - momentum: SGD 优化器的动量。 - no_aug: 是否禁用数据增强。 - num_workers: 数据加载器的工作线程数量。 - opt: 优化器名称。 - opt_betas: Adam 优化器的 beta 参数。 - opt_eps: Adam 优化器的 epsilon 参数。 - output_dir: 模型检查点的输出路径。 - patience_epochs: 在验证集上等待的 epochs 数量,用于提高验证集性能。 - pin_mem: 是否使用 pinned memory 进行数据加载。 - pretrain_address: 预训练模型的地址。 - print_epoch: 每多少个 epochs 打印一次训练信息。 - recount: 数据增强的重复次数。 - remode: 随机增强的方式。 - repeated_aug: 是否对同一图像进行多次数据增强。 - reprob: 随机擦除的比例。 - resplit: 是否对数据集进行重新划分。 - resume: 恢复训练的检查点路径。 - scale: 随机缩放的比例范围。 - sched: 学习率调度器名称。 - seed: 随机数种子。 - smoothing: Label Smoothing 正则化的比例。 - start_epoch: 起始 epoch 数量。 - train_interpolation: 训练集插值方式。 - use_prefetcher: 是否使用数据预加载。 - warmup_epochs: 学习率预热的 epochs 数量。 - warmup_lr: 预热学习率。 - weight_decay: 权重衰减的比例。 - world_size: 分布式训练的进程数量。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值