【cuda学习日记】2.cuda编程模型

2.1 在CPU上执行sum array

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>void sumArraysOnHost(float *A, float *B, float *C, const int N)
{for (int idx = 0; idx< N; idx ++){C[idx] = A[idx] + B[idx];}
}void initialData(float *ip, int size)
{time_t t;srand((unsigned int) time(&t));for (int i = 0; i < size; i++) {ip[i] = (float) (rand() & 0xff) / 10.0f;}
}int main(int argc , char **argv)
{int nElem = 1024;size_t nBytes = nElem * sizeof(float);float *h_A, *h_B, *h_C;h_A = (float *) malloc (nBytes);h_B = (float *) malloc (nBytes);h_C = (float *) malloc (nBytes);initialData(h_A, nElem);initialData(h_B, nElem);sumArraysOnHost(h_A, h_B, h_C, nElem);free(h_A);free(h_B);free(h_C);return 0;
}

2.2 查看grid, block的索引维度

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <cuda_runtime.h>__global__ void checkIndex(void)
{printf("threadidx: (%d ,%d ,%d) blockidx:(%d ,%d ,%d) blockdim: (%d ,%d ,%d) gridDim: (%d ,%d ,%d)\n", threadIdx.x, threadIdx.y, threadIdx.z,blockIdx.x, blockIdx.y, blockIdx.z,blockDim.x,blockDim.y,blockDim.z,gridDim.x, gridDim.y, gridDim.z);
}int main(int argc , char **argv)
{int nElem = 6;dim3 block(3);dim3 grid ((nElem + block.x -1)/block.x);printf("grid.x %d grid.y %d grid.z %d\n", grid.x, grid.y, grid.z);printf("block.x %d block.y %d block.z %d\n", block.x, block.y, block.z);checkIndex<<<grid, block>>>();cudaDeviceReset();return 0;
}

输出
grid.x 2 grid.y 1 grid.z 1
block.x 3 block.y 1 block.z 1
threadidx: (0 ,0 ,0) blockidx:(1 ,0 ,0) blockdim: (3 ,1 ,1) gridDim: (2 ,1 ,1)
threadidx: (1 ,0 ,0) blockidx:(1 ,0 ,0) blockdim: (3 ,1 ,1) gridDim: (2 ,1 ,1)
threadidx: (2 ,0 ,0) blockidx:(1 ,0 ,0) blockdim: (3 ,1 ,1) gridDim: (2 ,1 ,1)
threadidx: (0 ,0 ,0) blockidx:(0 ,0 ,0) blockdim: (3 ,1 ,1) gridDim: (2 ,1 ,1)
threadidx: (1 ,0 ,0) blockidx:(0 ,0 ,0) blockdim: (3 ,1 ,1) gridDim: (2 ,1 ,1)
threadidx: (2 ,0 ,0) blockidx:(0 ,0 ,0) blockdim: (3 ,1 ,1) gridDim: (2 ,1 ,1)

2.4 cuda核函数
kernel_name<<<grid, block>>> (argument list);

2.5 核函数限定符
global 在设备端执行,主机端或计算能力>3的设备端调用,必须有void 返回类型
device 在设备端执行,设备端调用
host 在主机端执行,主机端调用

2.6 在GPU中sum,和HOST sum array做对比

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>#define CHECK(call) \{\const cudaError_t error = call; \if (error != cudaSuccess)\{\printf("Error: %s: %d\n", __FILE__, __LINE__);\printf("code :%d reason :%s\n", error , cudaGetErrorString(error));\exit(1);\}\
}void checkResult(float *hostRef, float *gpuRef, const int N)
{double epsilon = 1.0E-8;bool match = 1;for (int i = 0; i < N; i++){if (abs(hostRef[i] - gpuRef[i])> epsilon){match = 0;printf("Array do not match\n");printf("host %5.2f gpu % 5.2f at current %d\n", hostRef[i], gpuRef[i], i);break;}}if (match) printf("array matches\n");
}void sumArraysOnHost(float *A, float *B, float *C, const int N)
{for (int idx = 0; idx< N; idx ++){C[idx] = A[idx] + B[idx];}
}void initialData(float *ip, int size)
{time_t t;srand((unsigned int) time(&t));for (int i = 0; i < size; i++) {ip[i] = (float) (rand() & 0xff) / 10.0f;}
}__global__ void sumArraysOnGPU(float *A, float *B, float *C)
{int i  = blockIdx.x * blockDim.x + threadIdx.x;C[i] = A[i] + B[i];
}double cpusec()
{struct timeval tp;gettimeofday(&tp, NULL);return ((double) tp.tv_sec + (double)tp.tv_usec* 1.e-6);
}int main(int argc , char **argv)
{printf("%s starting\n", argv[0]);int dev = 0;cudaSetDevice(dev);//set up dataint nElem = 32;size_t nBytes = nElem * sizeof(float);float *h_A, *h_B, *hostRef, *gpuRef;h_A = (float *) malloc (nBytes);h_B = (float *) malloc (nBytes);hostRef = (float *) malloc (nBytes);gpuRef = (float *) malloc (nBytes);initialData(h_A, nElem);initialData(h_B, nElem);memset(hostRef,0, nBytes);memset(gpuRef,0, nBytes);// malloc device global memoryfloat *d_A, *d_B, *d_C;cudaMalloc((float**)&d_A, nBytes);cudaMalloc((float**)&d_B, nBytes);cudaMalloc((float**)&d_C, nBytes);//transfer data from host to devicecudaMemcpy(d_A, h_A, nBytes, cudaMemcpyHostToDevice);cudaMemcpy(d_B, h_B, nBytes, cudaMemcpyHostToDevice);dim3 block(nElem);dim3 grid(nElem/block.x);sumArraysOnGPU<<<grid,block>>>(d_A, d_B, d_C);printf("execution config <<<%d, %d>>>\n", grid.x, block.x);//copy kernel result back to hostcudaMemcpy(gpuRef, d_C, nBytes, cudaMemcpyDeviceToHost);sumArraysOnHost(h_A, h_B, hostRef, nElem);checkResult(hostRef, gpuRef, nElem);cudaFree(d_A);cudaFree(d_B);cudaFree(d_C);free(h_A);free(h_B);free(hostRef);free(gpuRef);return 0;
}

输出
execution config <<<1, 32>>>
array matches

2.8 尝试用nvprof 检查执行时间,报错找不到dll文件,可以参考
https://blog.csdn.net/qq_41607336/article/details/126741908
解决,
但最后还是报warning, 跟显卡相关
======= Warning: nvprof is not supported on devices with compute capability 8.0 and higher.

2.9 加上device信息打印,以及cudaevent 计时, 参考https://blog.csdn.net/qq_42681630/article/details/144895351

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <windows.h>typedef unsigned long DWORD;#define CHECK(call) \{\const cudaError_t error = call; \if (error != cudaSuccess)\{\printf("Error: %s: %d\n", __FILE__, __LINE__);\printf("code :%d reason :%s\n", error , cudaGetErrorString(error));\exit(1);\}\
}void checkResult(float *hostRef, float *gpuRef, const int N)
{double epsilon = 1.0E-8;bool match = 1;for (int i = 0; i < N; i++){if (abs(hostRef[i] - gpuRef[i])> epsilon){match = 0;printf("Array do not match\n");printf("host %5.2f gpu % 5.2f at current %d\n", hostRef[i], gpuRef[i], i);break;}}if (match) printf("array matches\n");
}void sumArraysOnHost(float *A, float *B, float *C, const int N)
{for (int idx = 0; idx< N; idx ++){C[idx] = A[idx] + B[idx];}
}void initialData(float *ip, int size)
{time_t t;srand((unsigned int) time(&t));for (int i = 0; i < size; i++) {ip[i] = (float) (rand() & 0xff) / 10.0f;}
}__global__ void sumArraysOnGPU(float *A, float *B, float *C)
{int i  = blockIdx.x * blockDim.x + threadIdx.x;C[i] = A[i] + B[i];
}int main(int argc , char **argv)
{printf("%s starting\n", argv[0]);int dev = 0;cudaDeviceProp deviceprop;CHECK(cudaGetDeviceProperties(&deviceprop,dev));printf("Using Device %d : %s\n", dev, deviceprop.name);CHECK(cudaSetDevice(dev));printf( "Compute capability:  %d.%d\n", deviceprop.major, deviceprop.minor );printf( "Clock rate:  %d\n", deviceprop.clockRate );printf( "Memory Clock rate:  %d\n", deviceprop.memoryClockRate );printf( "Memory busWidth:  %d\n", deviceprop.memoryBusWidth );printf( "   --- Memory Information for device  ---\n");// printf( "Total global mem:  %ld\n", prop.totalGlobalMem );printf( "Total global mem:  %zu\n", deviceprop.totalGlobalMem );printf( "Total constant Mem:  %ld\n", deviceprop.totalConstMem );printf( "Max mem pitch:  %ld\n", deviceprop.memPitch );printf( "Texture Alignment:  %ld\n", deviceprop.textureAlignment );printf( "   --- MP Information for device  ---\n" );printf( "Multiprocessor count:  %d\n",deviceprop.multiProcessorCount );printf( "Shared mem per mp:  %ld\n", deviceprop.sharedMemPerBlock );printf( "Registers per mp:  %d\n", deviceprop.regsPerBlock );printf( "Threads in warp:  %d\n", deviceprop.warpSize );printf( "Max threads per block:  %d\n",deviceprop.maxThreadsPerBlock );printf( "Max thread dimensions:  (%d, %d, %d)\n",deviceprop.maxThreadsDim[0], deviceprop.maxThreadsDim[1],deviceprop.maxThreadsDim[2] );printf( "Max grid dimensions:  (%d, %d, %d)\n",deviceprop.maxGridSize[0], deviceprop.maxGridSize[1],deviceprop.maxGridSize[2] );printf( "\n" );//set up dataint nElem = 1<<24;size_t nBytes = nElem * sizeof(float);float *h_A, *h_B, *hostRef, *gpuRef;h_A = (float *) malloc (nBytes);h_B = (float *) malloc (nBytes);hostRef = (float *) malloc (nBytes);gpuRef = (float *) malloc (nBytes);initialData(h_A, nElem);initialData(h_B, nElem);memset(hostRef,0, nBytes);memset(gpuRef,0, nBytes);// malloc device global memoryfloat *d_A, *d_B, *d_C;cudaMalloc((float**)&d_A, nBytes);cudaMalloc((float**)&d_B, nBytes);cudaMalloc((float**)&d_C, nBytes);//transfer data from host to devicecudaMemcpy(d_A, h_A, nBytes, cudaMemcpyHostToDevice);cudaMemcpy(d_B, h_B, nBytes, cudaMemcpyHostToDevice);int Ilen = 1024;dim3 block(Ilen);dim3 grid((nElem + block.x - 1)/block.x);cudaEvent_t start, stop;cudaEventCreate(&start);cudaEventCreate(&stop);cudaEventRecord(start);sumArraysOnGPU<<<grid,block>>>(d_A, d_B, d_C);printf("execution config <<<%d, %d>>>\n", grid.x, block.x);cudaEventRecord(stop);cudaEventSynchronize(stop);float milliseconds = 0;cudaEventElapsedTime(&milliseconds, start, stop);printf("Kernel execution time: %f ms\n", milliseconds);cudaEventDestroy(start);cudaEventDestroy(stop);//copy kernel result back to hostcudaMemcpy(gpuRef, d_C, nBytes, cudaMemcpyDeviceToHost);sumArraysOnHost(h_A, h_B, hostRef, nElem);checkResult(hostRef, gpuRef, nElem);cudaFree(d_A);cudaFree(d_B);cudaFree(d_C);free(h_A);free(h_B);free(hostRef);free(gpuRef);return 0;
}

输出:
Using Device 0 : NVIDIA GeForce RTX 4090
Compute capability: 8.9
Clock rate: 2520000
Memory Clock rate: 10501000
Memory busWidth: 384
— Memory Information for device —
Total global mem: 25756696576
Total constant Mem: 65536
Max mem pitch: 2147483647
Texture Alignment: 512
— MP Information for device —
Multiprocessor count: 128
Shared mem per mp: 49152
Registers per mp: 65536
Threads in warp: 32
Max threads per block: 1024
Max thread dimensions: (1024, 1024, 64)
Max grid dimensions: (2147483647, 65535, 65535)

execution config <<<16384, 1024>>>
execution config <<<16384, 1024>>>
Kernel execution time: 0.558752 ms
array matches

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【STM32+CubeMX】 新建一个工程(STM32F407)

相关文章&#xff1a; 【HAL库】 STM32CubeMX 教程 1 --- 下载、安装 目录 第一部分、新建工程 第二部分、工程文件解释 第三部分、编译验证工程 友情约定&#xff1a;本系列的前五篇&#xff0c;为了方便新手玩家熟悉CubeMX、Keil的使用&#xff0c;会详细地截图每一步Cu…

HTML5实现喜庆的新年快乐网页源码

HTML5实现喜庆的新年快乐网页源码 前言一、设计来源1.1 主界面1.2 关于新年界面1.3 新年庆祝活动界面1.4 新年活动组织界面1.5 新年祝福订阅界面1.6 联系我们界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 HTML5实现喜庆的新年快乐网页源码&#xff0c;春节新年网…

鸿蒙的APP真机调试以及发布

目录&#xff1a; 1、创建好鸿蒙项目2、创建AGC项目3、实现自动签名3.1、手动方式创建签名文件和密码 4、运行项目5、无线真机调试 1、创建好鸿蒙项目 2、创建AGC项目 &#xff08;1&#xff09;在File->Project Structure->Project->Signing Configs中进行登录。(未…

概率基本概念 --- 离散型随机变量实例

条件概率&独立事件 随机变量 - 离散型随机变量 - 非离散型随机变量 连续型随机变量奇异性型随机变量 概率表示 概率分布函数概率密度函数概率质量函数全概率公式贝叶斯公式 概率计算 数学期望方差协方差 计算实例 假设有两个离散型随机变量X和Y&#xff0c;它们代…

【Linux】Linux指令apt、systemctl、软链接、日期时区

一、apt命令 1.1 Linux系统的应用商店 操作系统安装软件有许多种方式&#xff0c;一般分为&#xff1a; 下载安装包自行安装 如win系统使用exe文件、msi文件等如mac系统使用dmg文件、pkg文件等 系统的应用商店内安装 如win系统有Microsoft Store商店如mac系统有AppStore商…

OSI模型的网络层中产生拥塞的主要原因?

&#xff08; 1 &#xff09;缓冲区容量有限&#xff1b;&#xff08; 1.5 分&#xff09; &#xff08; 2 &#xff09;传输线路的带宽有限&#xff1b;&#xff08; 1.5 分&#xff09; &#xff08; 3 &#xff09;网络结点的处理能力有限&#xff1b;&#xff08; 1 分…

C++list

1. list的介绍及使用 1.1list的介绍 list的文档介绍 1.list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双相迭代 2.list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过…

Java 日期时间格式化标准

文章目录 Java日期时间格式化符号ISO 8601中的日期时间ISO 8601标准的定义ISO 8601日期时间格式 周数年份ISO 8601中的周数年份Java中的周数年份 Java跨年日期格式化BUG注意事项 Java日期时间格式化符号 JDK官网截图&#xff1a; 格式化符号梳理&#xff1a; 符号描述符号用…

【计算机视觉】单目深度估计模型-Depth Anything-V2

概述 本篇将简单介绍Depth Anything V2单目深度估计模型&#xff0c;该模型旨在解决现有的深度估计模型在处理复杂场景、透明或反射物体时的性能限制。与前一代模型相比&#xff0c;V2版本通过采用合成图像训练、增加教师模型容量&#xff0c;并利用大规模伪标签现实数据进行学…

如何在Windows上编译OpenCV4.7.0

前言 ​ 参考&#xff1a;Win10 下编译 OpenCV 4.7.0详细全过程&#xff0c;包含xfeatures2d 这里在其基础上还出现了一些问题&#xff0c;仅供参考。 正文 一、环境 1、win10 2、cmake-gui 3、opencv4.7.0 4、VS2019 二、编译过程 1、下载需要的文件&#xff1a; 通…

ros2-4.1 服务通信介绍

服务是ROS图中节点之间的另一种通信方法。服务分为客户端和服务端&#xff0c;客户端发送请求给服务端&#xff0c;服务端可以根据客户端的请求做一些处理&#xff0c;然后返回结果给客户端。也称为为请求-响应模型。 服务和话题的不同之处&#xff0c;话题是没有返回的&#…

代码随想录算法训练营第四十天 | 股票问题

LeetCode 121.买卖股票的最佳时机&#xff1a; 文章链接 题目链接&#xff1a;121.买卖股票的最佳时机 思路 方法1&#xff1a;暴力 看到题目最直接的想法是双层遍历求最大区间差 class Solution:def maxProfit(self, prices):if len(prices) < 1:return 0result 0for…

EyeSoothe: Your Ultimate Eye Health Companion

In today’s screen-dominated world, our eyes deserve extra care. EyeSoothe is the ultimate app for anyone looking to track their vision, rejuvenate tired eyes, and find the perfect eyewear—all powered by intelligent AI and packed into one seamless app. h…

AnaConda下载PyTorch慢的解决办法

使用Conda下载比较慢&#xff0c;改为pip下载 复制下载链接到迅雷下载 激活虚拟环境&#xff0c;安装whl&#xff0c;即可安装成功 pip install D:\openai.wiki\ChatGLM2-6B\torch-2.4.1cu121-cp38-cp38-win_amd64.whl

【python】matplotlib(radar chart)

文章目录 1、功能描述和原理介绍2、代码实现3、效果展示4、完整代码5、多个雷达图绘制在一张图上6、参考 1、功能描述和原理介绍 基于 matplotlib 实现雷达图的绘制 一、雷达图的基本概念 雷达图&#xff08;Radar Chart&#xff09;&#xff0c;也被称为蛛网图或星型图&…

鸿蒙APP之从开发到发布的一点心得

引言&#xff1a; 做鸿蒙开发大概有1年左右时间了&#xff0c;从最开始的看官方文档、看B站视频&#xff0c;到后来成功发布两款个人APP&#xff08;房贷计算极简版、时简时钟 轻喷&#xff0c;谢谢&#xff09;。简单描述一下里边遇到的坑以及一些经历吧。 学习鸿蒙开发 个…

Clisoft SOS与CAD系统集成

Clisoft SOS与CAD系统集成 以下内容大部分来自官方文档&#xff0c;目前只用到与Cadence Virtuoso集成&#xff0c;其他还未用到&#xff0c;如有问题或相关建议&#xff0c;可以留言。 与Keysight ADS集成 更新SOS客户端配置文件sos.cfg&#xff0c;以包含支持ADS的模板&am…

IP查询于访问控制保护你我安全

IP地址查询 查询方法&#xff1a; 命令行工具&#xff1a; ①在Windows系统中&#xff0c;我们可以使用命令提示符&#xff08;WINR&#xff09;查询IP地址&#xff0c;在弹窗中输入“ipconfig”命令查看本地网络适配器的IP地址等配置信息&#xff1b; ②在Linux系统中&…

人工智能训练师一级(高级技师)、二级(技师)考试指南

随着经济快速发展&#xff0c;人工智能技术在制造业、交通运输、农业、医疗健康、金融服务、物流配送以及城市服务等多个领域得到了广泛的应用。不仅带来产业的转型升级&#xff0c;更是对具备相应技能的人工智能训练师需求的激增。 根据教育部发布的《关于做好职业教育“…

ArmSoM RK3588/RK3576核心板,开发板网络设置

ArmSoM系列产品都搭配了以太网口或WIFI模块&#xff0c;PCIE转以太网模块、 USB转以太网模块等&#xff0c;这样我们的网络需求就不止是上网这么简单了&#xff0c;可以衍生出多种不同的玩法。 1. 网络连接​ 连接互联网或者组成局域网都需要满足一个前提–设备需要获取到ip&a…