CUDA学习笔记04:向量之和

参考资料

CUDA编程模型系列二(向量操作)_哔哩哔哩_bilibili (非常好的学习资料!)

vs2019

随意新建一个空项目,按照之前的环境配置配好项目依赖:

CUDA学习笔记02:测试程序hello world-CSDN博客

代码结构如下:

代码片段,demo_gpu.cu:

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

__global__ void vecAdd(const double* x, const double* y, double* z, int count)
{
    const int index = blockDim.x * blockIdx.x + threadIdx.x;
    // t00 t01 t02 t10 t11 t12 t20 t21 t22
    if (index < count)
    {
        z[index] = x[index] + y[index];
    }
}

void vecAdd_cpu(const double* x, const double* y, double* z, int count)
{
    for (int i = 0; i < count; ++i)
    {
        z[i] = x[i] + y[i];
    }
}

void test()
{
    const int N = 1000;
    const int M = sizeof(double) * N;

    //cpu mem alloc
    double* h_x = (double*)malloc(M);
    double* h_y = (double*)malloc(M);
    double* h_z = (double*)malloc(M);
    double* result_cpu = (double*)malloc(M);

    for (int i = 0; i < N; ++i)
    {
        h_x[i] = 1;
        h_y[i] = 2;
    }

    double* d_x, * d_y, * d_z;
    cudaMalloc((void**)&d_x, M);
    cudaMalloc((void**)&d_y, M);
    cudaMalloc((void**)&d_z, M);

    cudaMemcpy(d_x, h_x, M, cudaMemcpyHostToDevice);
    cudaMemcpy(d_y, h_y, M, cudaMemcpyHostToDevice);

    const int block_size = 128;
    const int grid_size = (N + block_size - 1) / block_size;

    vecAdd << <grid_size, block_size >> > (d_x, d_y, d_z, N);

    cudaMemcpy(h_z, d_z, M, cudaMemcpyDeviceToHost);

    vecAdd_cpu(h_x, h_y, result_cpu, N);

    bool error = false;

    for (int i = 0; i < N; ++i)
    {
        if (fabs(result_cpu[i] - h_z[i]) > (1.0e-10))
        {
            error = true;
        }
    }

    printf("Result: %s\n", error ? "Errors" : "Pass");

    free(h_x);
    free(h_y);
    free(h_z);
    free(result_cpu);
    cudaFree(d_x);
    cudaFree(d_y);
    cudaFree(d_z);
}

主函数:

#include <iostream>

void test();

int main()
{
    test();
    std::cout << "Finished! \n";
}

运行结果:

ok,结果通过。

Linux(CMake)

如果是使用CMake配置环境就更简单了,CMakeLists.txt这样写即可:

cmake_minimum_required(VERSION 3.10)

project(vector_add LANGUAGES CXX CUDA)

add_definitions(-std=c++11)
option(CUDA_USE_STATIC_CUDA_RUNTIME OFF)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CUDA_STANDARD 11)
set(CMAKE_BUILD_TYPE Debug)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/build)
set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -O0 -Wfatal-errors -pthread -w -g")

find_package(CUDA REQUIRED)

cuda_add_executable(vector_add add.cu)

代码结构:

add.cu和前边的代码没有区别:

#include <stdio.h>
#include <math.h>

__global__ void vecAdd(const double *x, const double *y, double *z, int count)
{
    const int index = blockDim.x * blockIdx.x + threadIdx.x;
    // t00 t01 t02 t10 t11 t12 t20 t21 t22
    if( index < count)
    {
        z[index] = x[index] + y[index];
    }
}

void vecAdd_cpu(const double *x, const double *y, double *z, int count)
{
    for(int i = 0; i<count; ++i)
    {
        z[i] = x[i] + y[i];
    }
}


int main()
{
    const int N = 1000;
    const int M = sizeof(double) * N;

    //cpu mem alloc
    double *h_x = (double*) malloc(M);
    double *h_y = (double*) malloc(M);
    double *h_z = (double*) malloc(M);
    double *result_cpu = (double*) malloc(M);

    for( int i = 0; i<N; ++i)
    {
        h_x[i] = 1;
        h_y[i] = 2;
    }

    double *d_x, *d_y, *d_z;
    cudaMalloc((void**) &d_x, M );
    cudaMalloc((void**) &d_y, M );
    cudaMalloc((void**) &d_z, M );

    cudaMemcpy(d_x ,h_x ,M , cudaMemcpyHostToDevice);
    cudaMemcpy(d_y ,h_y ,M , cudaMemcpyHostToDevice);

    const int block_size = 128;
    const int grid_size  = (N + block_size -1)/block_size;

    vecAdd<<<grid_size, block_size>>>(d_x, d_y, d_z, N);

    cudaMemcpy( h_z, d_z, M, cudaMemcpyDeviceToHost);

    vecAdd_cpu(h_x, h_y, result_cpu, N);

    bool error = false;

    for(int i=0; i<N; ++i)
    {
        if(fabs(result_cpu[i] - h_z[i]) > (1.0e-10))
        {
            error = true;
        }
    }
    
    printf("Result: %s\n", error?"Errors" : "Pass");

    free(h_x);
    free(h_y);
    free(h_z);
    free(result_cpu);
    cudaFree(d_x);
    cudaFree(d_y);
    cudaFree(d_z);

}

当前目录下建立build路径并且进入,用cmake构建:

cmake ..

构建好后编译:

最后查看编译结果,并运行:

OK,结果通过!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

jitpack上传aar异常: ERROR: No build artifacts found

问题 如图所示&#xff0c;提示 ERROR: No build artifacts found 解决 无法找到artifacts的情况下&#xff0c;我们就需要手动添加artifacts 。 //maven-publish 插件的配置 // publishing 用于定义项目的发布相关配置 publishing {// 配置maven 仓库repositories { Repo…

5201B数据网络测试仪

|5201B数据网络测试仪| | 产品综述 | 电科思仪5201B便携式数据网络测试仪&#xff0c;集成高性能IP基础测试硬件平台&#xff0c;提供L2-L3流量测试及协议仿真解决方案&#xff0c;支持以太网报文线速生成与分析、统计、报文捕获&#xff0c;以及路由、接入、组播、数据中心等协…

item_fee-获得淘宝商品快递费用 API调用说明获取测试key

item_fee-获得淘宝商品快递费用 .通过传入商品id、区域id&#xff0c;来获取该商品的快递费用。 公共参数 点此获取API请求地址 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&a…

Linux系统的服务/进程

系统守护进程&#xff08;服务&#xff09; •服务就是运行在网络服务器上监听用户请求的进程 •服务是通过端口号来区分的 常见的服务及其对应的端口 1.ftp&#xff1a;21 FTP指的是文件传输协议&#xff0c;它是用于在计算机网络上进行文件传输的标准网络协议。通过FTP&am…

数字化转型导师坚鹏:成为数字化转型顾问 引领数字化美好未来

成为数字化转型顾问 引领数字化美好未来 ——数字化人才与企业的共赢之路 数字经济新时代&#xff0c;中国企业向数字化转型要效益&#xff1b; 转型顾问创未来&#xff0c;职场精英借数字化转型成良师。 我们中国政府特别重视数字经济发展及数字化人才培养。早在2020年8月2…

通过XML调用CAPL脚本进行测试(新手向)

目录 0 引言 1 XML简介 2 通过XML调用CAPL脚本 0 引言 纪念一下今天这个特殊日子&#xff0c;四年出现一次的29号。 在CANoe中做自动化测试常用的编程方法有CAPL和XML两种&#xff0c;二者各有各的特色&#xff0c;对于CAPL来说新手肯定是更熟悉一些&#xff0c;因为说到在C…

C#高级:Winform桌面开发中DataGridView的详解

一、每条数据增加一个按钮&#xff0c;点击输出对应实体 请先确保正确添加实体的名称和文本&#xff1a; private void button6_Click(object sender, EventArgs e) {//SQL查询到数据&#xff0c;存于list中List<InforMessage> list bll.QueryInforMessage();//含有字段…

动静态库-动态库加载

动静态库 前言引入 一、静态库1. 创建静态库①原理②创建 2. 使用静态库①借助编译选项②只需要带库名 3. 小结 二、动态库1. 创建动态库2. 使用动态库 三、 动态库加载原理——进程地址空间1. 地址①程序没有被加载前的地址②程序加载后的地址 2. 原理①动态库的地址②原理 前…

Redis中的单线程高性能原因和其他高级命令

单线程 Redis是单线程吗&#xff1f; Redis的单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的&#xff0c;这也是 Redis对外提供键值存储的主要流程。但Redis的其他功能&#xff0c;比如持久化、异步删除、 集群数据同步等&#xff0c;其实是由额外的线程执行的…

Spring Cloud 面试题及答案整理,最新面试题

Spring Cloud中断路器的原理及其作用是什么&#xff1f; Spring Cloud断路器的原理和作用基于以下几个关键点&#xff1a; 1、故障隔离机制&#xff1a; 在微服务架构中&#xff0c;断路器作为一种故障隔离机制&#xff0c;当某个服务实例出现问题时&#xff0c;断路器会“断…

紫光展锐携手中兴通讯成功完成业界首个5G N102芯网一体方案联调

近日&#xff0c;紫光展锐携手中兴通讯成功完成业界首个5G N102频段的芯网一体方案联调&#xff0c;包括5G NR数据呼叫、时延和峰值速率测试等用例。这是双方在5G产品和研发方面取得的重大创新成果&#xff0c;为推动N102频段在5G行业的应用奠定了坚实基础。 3GPP定义的N102频段…

软件测试 - 测试用例基本理论

1. 概念 为了特定的目的(该目的是检验代码是否满足用户需求)而设计的文档&#xff0c;文档包含测试输入、执行条件、预期结果等。文档的形式一般是excel表格。 比如说我们买了一台电脑&#xff0c;新买的笔记本检查完外观之后第一步需要查看电脑是否能够正常开机&#xff0c;…

用Python爬取古诗文网的各类古诗

fetch-gushiwen 用途 可以拿去用于个人知识库、知识图谱的创建等其他学习用途。 使用 输入古诗文网的链接&#xff0c;即可爬取该页面所有诗歌的诗名&#xff0c;作者&#xff0c;朝代&#xff0c;内容&#xff0c;译文&#xff0c;注释&#xff0c;赏析&#xff0c;创作背…

MySQL 缓存策略

MySQL 缓存方案用来干什么 ? 缓存用户定义的热点数据&#xff0c;用户直接从缓存中获取热点数据&#xff0c;降低数据的读写压力。场景分析 内存访问速度是磁盘访问速度的 10 万倍。读的需求远远大于写的需求MySQL 自身缓冲层跟业务无关。MySQL 作为项目主要数据库&#xff0…

P5076 【深基16.例7】普通二叉树(简化版)题解

题目 您需要写一种数据结构&#xff0c;来维护一些数&#xff08;都是绝对值以内的数&#xff09;的集合&#xff0c;最开始时集合是空的。其中需要提供以下操作&#xff0c;操作次数q不超过&#xff1a; 定义数x的排名为集合中小于x的数的个数1。查询数x的排名。注意x不一定…

【ICM】好奇心机制

文章目录 样本经验处理降低图片像素和通道构建连续状态捕捉动作经验回放类 各部分的模型编码器模型反向模型正向模型DQN模型ICM 的 反向传播 概念补充强化学习组成元素按照学习目标来分按照策略更新方式区分强化学习on-line 与 off-line经验回放 全部代码 样本经验处理 降低图…

什么是物联网?物联网如何工作?

物联网到底是什么&#xff1f; 物联网(Internet of Things&#xff0c;IoT)的概念最早于1999年被提出&#xff0c;官方解释为“万物相连的互联网”&#xff0c;是在互联网基础上延伸和扩展&#xff0c;将各种信息传感设备与网络结合起来而形成的一个巨大网络&#xff0c;可以实…

无法启动报,To install it, you can run: npm install --save @/components/iFrame/index

运行的过程中后台报错 npm install --save /components/iFrame/index&#xff0c;以为是安装三方依赖错误&#xff0c;经过多次重装node_modules依然没有用。 没办法&#xff0c;只能在项目中搜索 components/iFrame/index这个文件。。突然醒悟。。。 有时候&#xff0c;犯迷…

MySQL面试题【全面】2024

基础内容 1、MySQL的架构分层 &#xff08;1&#xff09;Serve层&#xff1a;负责建立连接、分析和执行 SQL。 MySQL 大多数的核心功能模块都在这实现&#xff0c;主要包括连接器&#xff0c;查询缓存、解析器、预处理器、优化器、执行器等。另外&#xff0c;所有的内置函数&…

详解C#之WinForm版利用RichTextBox 制作文本编辑器【附源码】

在Windows应用程序开发中&#xff0c;刚刚介绍了WPF版的利用RichTextBox实现文本编辑器&#xff0c;今天继续推出WinForm版的利用RichTextBox实现文本编辑器。本文利用一个简单的小例子&#xff0c;简述如何在WinForm开发中&#xff0c;利用RichTextBox开发文本编辑器&#xff…