C++学习|CUDA内存管理代码实例

news2024/12/24 0:22:51

前言:之前介绍了CUDA入门知识,对CUDA编程有了一个基本了解,但是实际写起来还是遇到很多问题,例如cpp文件该怎么调用cuda文件、cpu和gpu之间内存数据怎么交换、如何编写.cu和.cuh文件之类的。本篇文章将会以一个实现向量相加的代码实例,来搞懂前面的这些问题。

CUDA实例:向量相加

  • 项目创建和配置
  • 新建.cu和.cuh文件
  • 编写.cu文件
  • 编写.cuh文件
  • 编写cpp文件

项目创建和配置

如果cuda还没有安装,可以参考我之前的博客“CUDA安装和配置”。

我安装的是CUDA 11.4版本,配置中所有给出的地址是CUDA安装的默认地址。如果你安装的不是默认地址,或者版本不同,请根据自己的需要去更改。

  1. 创建了一个C++控制台程序,也可以根据自己需求创建不同的C++项目。
  2. 配置CUDA的lib。
    项目-属性-连接器-常规-附加库目录,补上cuda.lib所在的地址“C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4\lib\x64”。
    项目-属性-连接器-输入,补上cuda.lib。
  3. 配置CUDA的include。
    项目-属性-VC++目录-包含目录,补上CUDA的include文件地址“C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.4\include”。
  4. 配置项目依赖项。
    项目-生成依赖项-生成自定义-勾选CUDA选项。

新建.cu和.cuh文件

添加->新建项,选择新建cuh和cu文件。在这里插入图片描述
头文件中新建cuda.cuh,源文件中新建cuda.cu。
在这里插入图片描述

编写.cu文件

先理解一下GPU内存管理的流程。
首先,CPU和GPU之间的数据是不共享的,所以要让GPU处理数据,除了要在GPU中分配内存,还需要把CPU的数据先传递到GPU。GPU数据处理完之后,需要把处理完的数据先传递回CPU,最后释放GPU分配的内存。
所以GPU内存管理的重要的功能就有四个:cudaMalloc(内存分配)、cudaMemcpy(数据传递)、cudaMemset(数据初始化)以及cudaFree(内存释放)。

目标是写一个GPU多线程运行的向量加法,一个线程负责一个向量维度的数相加。

#include"cuda.cuh"

#include <cuda_runtime.h>
#include<device_launch_parameters.h>
#include <stdio.h>

// 核函数:单独计算向量某一维的加法
__global__ void vecAdd(int *A,int *B,int *C) {
    int tid=threadIdx.x;// 获取线程所在一维block的id,作为向量维度的索引
    C[tid]=A[tid] + B[tid];
}
// 供CPP调用函数:GPU内存管理,调用核函数实现向量相加
void vecAddFun(int n,int* inA, int* inB,int *outC){
    // n是向量维度
    // A和B是两个输入向量,C是向量相加的结果
    int* A, *B,*C;
    // GPU开辟空间
    cudaMalloc((void**)&A,n*sizeof(int));
    cudaMalloc((void**)&B, n * sizeof(int));
    cudaMalloc((void**)&C, n * sizeof(int));
    // 把CPU数据拷贝到GPU
    cudaMemcpy(A,inA, n * sizeof(int),cudaMemcpyHostToDevice);
    cudaMemcpy(B, inB, n * sizeof(int), cudaMemcpyHostToDevice);
    cudaMemcpy(C, outC, n * sizeof(int), cudaMemcpyHostToDevice);
    // GPU运行核函数
    vecAdd<<< 1, n >>>(A, B, C);// n维向量,所以开1个block和n个线程
    // 让CPU等GPU运行完
    cudaDeviceSynchronize();
    // 把GPU数据拷贝回CPU
    cudaMemcpy(outC, C, n * sizeof(int), cudaMemcpyDeviceToHost);
    // 释放GPU内存
    cudaFree(A);
    cudaFree(B);
    cudaFree(C);
    return;
}

编写.cuh文件

这个文件主要目的是为了方便cpp文件调用.cu文件的功能。

// ifndef的作用是为了防止头文件的重复包含和编译
#ifndef CUDA_H
#define CUDA_H

void vecAddFun(int n, int* inA, int* inB, int* outC);

#endif

编写cpp文件

cpp文件里面写了主函数,调用cuda文件。
效果,输入向量维度n,然后输入两个向量,最后会输出两个向量相加的结果。

#include <iostream>
#include "cuda.cuh"// 调用cuda头文件
using namespace std;

int main()
{
	// n是向量的维度
	// A和B是两个输入向量,C是向量相加的结果
	int* A, * B, * C;
	int n;
	cin >> n;
	A = (int*)malloc(n * sizeof(int));
	B = (int*)malloc(n * sizeof(int));
	C = (int*)malloc(n * sizeof(int));
	for (int i = 0; i < n; i++) {
		cin >> A[i];
	}
	for (int i = 0; i < n; i++) {
		cin >> B[i];
	}
	vecAddFun(n, A, B, C);//调用cuda函数,进行向量相加
	for (int i = 0; i < n; i++) {
		cout << C[i] << " ";
	}
	cout << endl;
	return 0;
}

结果:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】二叉数的存储与基本操作的实现

文章目录 &#x1f340;二叉树的存储&#x1f333;二叉树的基本操作&#x1f431;‍&#x1f464;二叉树的创建&#x1f431;‍&#x1f453;二叉树的遍历&#x1f3a1;前中后序遍历&#x1f4cc;前序遍历&#x1f4cc;中序遍历&#x1f4cc;后续遍历 &#x1f6eb;层序遍历&am…

什么是Python爬虫分布式架构,可能遇到哪些问题,如何解决

目录 什么是Python爬虫分布式架构 1. 调度中心&#xff08;Scheduler&#xff09;&#xff1a; 2. 爬虫节点&#xff08;Crawler Node&#xff09;&#xff1a; 3. 数据存储&#xff08;Data Storage&#xff09;&#xff1a; 4. 反爬虫处理&#xff08;Anti-Scraping&…

2023-08-30力扣每日一题

链接&#xff1a; 1654. 到家的最少跳跃次数 题意&#xff1a; 从0出发&#xff0c;到X的最少步数 它可以 往前 跳恰好 a 个位置&#xff08;即往右跳&#xff09;。它可以 往后 跳恰好 b 个位置&#xff08;即往左跳&#xff09;。它不能 连续 往后跳 2 次。它不能跳到任何…

2023新版医保目录明细(药品查询)

查询医保目录的主要目的是为了了解医保政策对于特定医疗服务、药品和医疗器械的覆盖范围和支付标准。大众可以通过查看医保目录可以确定哪些药品可以被医保支付以及报销的比例和限额&#xff1b;医药从业者可通过查看医保目录可以即使了解医保政策的变化&#xff0c;便于做出相…

Window10 安装 Lua

1、下载地址&#xff1a;https://luabinaries.sourceforge.net/download.html 2、下载 3、解压后共有4个文件&#xff0c;这里我把这几个文件放到如下目录 D:\Program Files\lua-5.4.2\bin 4、定义环境变量 5、打开 powershell&#xff0c;运行 lua54 -v PS C:\Windows\syste…

qt设计界面

widget.h #ifndef WIDGET_H #define WIDGET_H //防止文件重复包含#include <QWidget> //QWidget类所在的头文件&#xff0c;父类头文件 #include<QIcon> #include<QPushButton> …

Facebook Shops免费面世 Facebook与Instagram携手并肩

图片来源&#xff1a;SaleSmartly官网 近年来网上购物剧增&#xff0c;电子商务越趋重要&#xff0c;Facebook 和Instragram乘势推出Facebook Shops&#xff0c;免费让零售商户在全球最多使用者的两个社交平台创建线上商户&#xff0c;展示产品和进行交易&#xff0c;助零售业走…

DataTable扩展 列转行方法(2*2矩阵转换)

源数据 如图所示 // <summary>/// DataTable扩展 列转行方法&#xff08;2*2矩阵转换&#xff09;/// </summary>/// <param name"dtSource">数据源</param>/// <param name"columnFilter">逗号分隔 如SDateTime,PM25,PM10…

SmokePing网络延迟和丢包监测工具

SmokePing是一种网络延迟和丢包监测工具&#xff0c;其监控原理如下&#xff1a; 监测目标选择&#xff1a;SmokePing通过配置文件&#xff08;Targets&#xff09;定义了要监测的目标&#xff0c;可以是主机、路由器、服务器或其他网络设备。每个目标都有一个唯一的名称和IP地…

9个实用的交互设计软件,Get更简单的原型制作方式!

好用的原型图软件不仅可以快速可视化产品经理的想法&#xff0c;提高沟通效率&#xff0c;还可以加快测试进度&#xff0c;打造更真实的用户体验。今天本文为大家整理了9个好用的原型图工具&#xff0c;一起来看看吧&#xff01; 1、即时设计 在设计场景中&#xff0c;即时设…

基于MyBatis注解的学生管理程序--mybatis注解开发的练手项目

基于MyBatis注解的学生管理程序 需求&#xff1a;完成基于MyBatis注解的学生管理程序&#xff0c;能够用MyBatis注解实现查询操作、实现修改操作、实现一对多查询 &#xff08;1&#xff09;MyBatis注解开发实现查询操作。根据表1和表2在数据库分别创建一个学生表tb_student和…

【CicadaPlayer】getPlayerBufferDuration分析

https://github.com/alibaba/CicadaPlayer/blob/release/0.4.4/mediaPlayer/SuperMediaPlayer.cpp核心关键函数int64_t SuperMediaPlayer::getPlayerBufferDuration(bool gotMax, bool internal)17个地方出现: getPlayerBufferDuration的durations 数组 分别 对音频、视频、字…

登录页面设计的7个小细节,帮你提升用户体验

移动 APP 登录页面的设计直接影响到用户体验&#xff0c;从而决定 APP 的成败。我们应该设计出令用户兴奋而不是沮丧的登录界面。下面就让我和你分享几个提升登录页面 UX 设计的技巧: 如果用户必须登录才能使用服务&#xff0c;那么需要仔细考虑登录表单。 在构建登录页面设计…

简单数学题:找出最大的可达成数字

来看一道简单的数学题&#xff1a;力扣2769. 找出最大的可达成数字 题目描述的花里胡哨&#xff0c;天花乱坠&#xff0c;但这道题目非常简单。我们最多执行t次操作&#xff0c;只需每次操作都让x-1&#xff0c;让num1&#xff0c;执行t次操作后&#xff0c;x就变为xt&#xff…

YAML基本介绍和使用语法

YAML详解及使用方法 一、基本介绍二、数据类型2.1 纯量(scalars)/标量2.1.1 字符串2.1.2 保留换行(Newlines preserved)2.1.3 布尔值&#xff08;Boolean)2.1.4 整数&#xff08;Integer&#xff09;2.1.5 浮点数&#xff08;Floating Point&#xff09;2.1.6 空&#xff08;Nu…

找到9个可以编辑的线框图模板资源,自取

大家好&#xff0c;我是设计师l1m0&#xff0c;最近找到了的9个还比较不错的线框图模板&#xff0c;想要分享给大家。顺便提一下这个免费的资源下载网站&#xff1a;Pixso资源社区。 相比成熟的设计师都知道线框图对产品设计来说扮演着什么角色&#xff0c;在这里不做过多赘述…

搬家小程序开发攻略

随着互联网的快速发展&#xff0c;小程序已成为各行各业实现线上服务的重要工具。特别是在搬家行业&#xff0c;小程序的应用能够让用户更加便捷地获取服务。本文将为您详细介绍如何使用第三方制作平台&#xff0c;如乔拓云网&#xff0c;轻松开发一款搬家小程序&#xff0c;实…

echarts环形图,饼图 自定义title居中显示

需求 方法一 使用 div 定位 将数字放在饼图中间 <div style"position: relative;"><pieChart :chartObj"usageMap" /><div class"pieNum" :style"{ left: drawer ? 40px : 65px }"><div class"pieTitle&q…

Mysql-索引查询相关

一、单表查询 1.1 二级索引为null 不论是普通的二级索引&#xff0c;还是唯一二级索引&#xff0c;它们的索引列对包含 NULL 值的数量并不限制&#xff0c;所以我们采用key IS NULL 这种形式的搜索条件最多只能使用 ref 的访问方法&#xff0c;而不是 const 的访问方法 1.2 c…

零知识证明(zk-SNARK)(二)

From Computational Problem to zk-SNARK 本部分就是将计算难题转换为多项式&#xff0c;然后使用zk-SNARK。 &#xff08;注&#xff1a;以下用 P&#xff0c;V 替代 Prover&#xff0c;Verifier&#xff09; 计算难题->R1CS R1CS(Rank-1 Constraint System)是一种能够…