Ⅱ.INTRODUCTION TO CUDA C (CUDA C 入门)

前言

上一节环境配置好了,我们开始吧!

一、A First Program

1. Hello, World!

我们先写一个C语言的 Hello, World! 作为对比

int main(void){
  printf("Hello, World!\n");
  return 0;
}

大家应该知道这个代码运行在CPU上吧,我们CPU和系统的内存称作 host,GPU及其内存称作 device。

#include <stdio.h>

__global__ void kernel(void){

}

int main(void){
  kernel<<<1,1>>>();
  printf("Hello,World!\n");
  return 0;
}

这个程序:
① 有一个叫kernal且被 global 修饰的函数
② 调用这个kernal函数用了 <<<1,1>>>

C语言部分的代码就是用vs编译的,CUDA C 这部分,也就是带有 global 的代码,将在GPU上编译(在GPU上执行的函数称为CUDA核函数(Kernel Function))。
(NVIDIA工具将C语言交给C编译器,核函数交给device:函数kernel()将被交给编译device代码的编译器,而main()函数将被交给host编译器)

2. Passing Parameters

#include "stdio.h"

__global__ void add(int a, int b, int *c){
  *c = a+b;
}

int main(){
  int c;
  int *dev_c;
cudaMalloc((void**)&dev_c, sizeof(int));

  add<<<1,1>>>(2,7,dev_c);

cudaMemcpy(&c,
    dev_c,
    sizeof(int),
    cudaMemcpyDeviceToHost);
   printf("2+7 = %d\n",c);
   cudaFree(dev_c);
   return 0;
}

① 我们可以像C代码那样传递参数调用 global 函数
② 要先在device上申请内存,然后操作后返回给host

我们说一下 cudaMalloc:
和C的malloc很相似,不同的是,这个函数是要在 device – GPU 上申请内存。
第一个参数:
是一个指向指针的指针,因为我们需要新开辟内存的地址
第二个参数:
是内存大小
除了传参不同,这个函数返回值是CUDA中定义的一个错误代码。
CUDA C淡化了主机代码和设备代码之间的差异,这样的话,我们思考一个问题,我们可以在host端使用(解引用) dev_c 吗?
大家思考3秒钟…

当然不能,这是 CUDA 返回过来的,这可是GPU的内存哦。
你使用的话,编译器可是识别不出来的,要小心!
所以这里有几条限制:
① 可以将cudaMalloc()分配的指针传递给在device上执行的函数
② 可以在device代码中使用cudaMalloc()分配的指针进行内存读写操作
③ 可以将cudaMalloc()分配的指针传递给在host上执行的函数
④ 不能在主机代码中使用cudaMalloc()分配的指针进行内存读写操作

这③和④大家觉得是不是有歧义哦,是这样的:③的意思是在host可以传递参数 – 赋值操作是没问题的;④的意思是在host上解引用操作是不行的。大家可以理解吧。同样的道理,host的指针在device中也会出错哦。
cudaFree() 和 cudaMalloc() 相对应,一个释放,一个申请。
下面说一下 cudaMemcpy(dst, src, count, kind) :

  1. 前2个为指针,指向device 和 host 内存
  2. 第三个为拷贝的数据大小
  3. 第四个为拷贝的方向
  4. 返回值是错误代码
    用kind标注这个复制的方向,这次程序里的是 cudaMemcpyDeviceToHost,也就是说源地址是device,目的地址是host。
    反方向的是cudaMemcpyHostToDevice,还有一个很奇怪的cudaMemcpyDeviceToDevice,不知道这和 memcpy 有什么区别…
    这些使用方法大家可以再去英伟达官网上瞅瞅:
    https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__MEMORY.html#group__CUDART__MEMORY_1ga042655cbbf3408f01061652a075e094

2. Querying Devices

我们可以通过代码接口查看设备的情况:

#include "stdio.h"

int main() {
	int count;
	cudaGetDeviceCount(&count);
    cudaDeviceProp prop;

     for (int i = 0; i < count; i++) {
          cudaGetDeviceProperties(&prop, i);
          printf("   --- General Information for device %d ---\n", i);
          printf("Name:  %s\n", prop.name);
          printf("Compute capability:  %d.%d\n", prop.major, prop.minor);
          printf("Clock rate:  %d\n", prop.clockRate);
          printf("Device copy overlap:  ");
          if (prop.deviceOverlap)
               printf("Enabled\n");
          else
               printf("Disabled\n");
          printf("Kernel execution timeout :  ");
          if (prop.kernelExecTimeoutEnabled)
               printf("Enabled\n");
          else
               printf("Disabled\n");

          printf("   --- Memory Information for device %d ---\n", i);
          printf("Total global mem:  %ld\n", prop.totalGlobalMem);
          printf("Total constant Mem:  %ld\n", prop.totalConstMem);
          printf("Max mem pitch:  %ld\n", prop.memPitch);
          printf("Texture Alignment:  %ld\n", prop.textureAlignment);

          printf("   --- MP Information for device %d ---\n", i);
          printf("Multiprocessor count:  %d\n",
               prop.multiProcessorCount);
          printf("Shared mem per mp:  %ld\n", prop.sharedMemPerBlock);
          printf("Registers per mp:  %d\n", prop.regsPerBlock);
          printf("Threads in warp:  %d\n", prop.warpSize);
          printf("Max threads per block:  %d\n",
               prop.maxThreadsPerBlock);
          printf("Max thread dimensions:  (%d, %d, %d)\n",
               prop.maxThreadsDim[0], prop.maxThreadsDim[1],
               prop.maxThreadsDim[2]);
          printf("Max grid dimensions:  (%d, %d, %d)\n",
               prop.maxGridSize[0], prop.maxGridSize[1],
               prop.maxGridSize[2]);
          printf("\n");
     }
}

在这里插入图片描述
大家见笑了,我这电脑也就是凑活能用😅
大家去这里搜这俩函数,这个 cudaDeviceProp 内容实在太多,就写了这些,大家去这里看详情:
https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__DEVICE.html#group__CUDART__DEVICE

3.Using Device Properties

假设我们需要找特定能力的GPU设备,要怎么办呢?像上面一样,把每个都打印出来一条一条挨着看吗?

int main( void ) {
    cudaDeviceProp  prop;
    int dev;

    cudaGetDevice( &dev );
    printf( "ID of current CUDA device:  %d\n", dev );

    memset( &prop, 0, sizeof( cudaDeviceProp ) );
    prop.major = 1;
    prop.minor = 3;
    cudaChooseDevice( &dev, &prop );
    printf( "ID of CUDA device closest to revision 1.3:  %d\n", dev );

    cudaSetDevice( dev );
}

我们可以用这个 cudaDeviceProp 设定出我们的需求设备,然后 cudaChooseDevice 去找找看有没有(函数返回码),有的话就去设定。

总结

我们已经在GPU上运行出来了经典的 Hello world !,大家已经入门了,继续加油哦~

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

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

相关文章

rsync如何实时同步

一、准备rsyncd服务环境 backup服务器&#xff08;rsync服务端&#xff09; 1、恢复了快照&#xff0c;重新安装rsync服务端 2、快速的部署rsyncd服务端 #!/bin/bash yum install rsync -ycat > /etc/rsyncd.conf << EOF uid www gid www port 873 fake supe…

Python的Matplotlib库应用(超详细教程)

目录 一、环境搭建 1.1 配置matplotlib库 1.2 配置seaborn库 1.3 配置Skimage库 二、二维图像 2.1 曲线&#xff08;直线&#xff09;可视化 2.2 曲线&#xff08;虚线&#xff09;可视化 2.3 直方图 2.4 阶梯图 三、三维图像 3.1 3D曲面图 3.2 3D散点图 3.3 3D散…

vue之element-ui文件上传(二)

一、点击上传&#xff0c;使用默认的action上传&#xff0c;添加校验&#xff0c;上传成功后&#xff0c;去除校验&#xff1a; <el-form-item label"文件md5" prop"fileMd5"><el-uploadv-if"!form.fileMd5"v-model"form.fileMd5&…

java项目之旅游网站的设计与实现(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的旅游网站的设计与实现。 项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于SpringBoot的…

IOS开发如何从入门进阶到高级

针对iOS开发的学习&#xff0c;不同阶段应采取不同的学习方式&#xff0c;以实现高效提升.本文将iOS开发的学习分为入门、实战、进阶三个阶段&#xff0c;下面分别详细介绍. 一、学习社区 iOS开源中国社区 这个社区专注于iOS开发的开源项目分享与协作&#xff0c;汇集了大量开…

ubuntu编译ijkplayer,支持rmvb以及mkv

1. 准备环境 sudo apt-get update apt install gcc yasm cmake python p7zip-full vim pkg-config autoconf automake build-essential dos2unix mercurial cmake-curse-gui -y apt-get -y --force-yes install libass-dev libtheora-dev libtool libva-dev libvdpau-dev libv…

Ardupilot开源无人机之Geek SDK进展2024

Ardupilot开源无人机之Geek SDK进展202501 1. 源由2. 状态3. TODO3.1 跟踪目标框3.2 onnxruntime版本3.3 CUDA 11.8版本3.4 pytorch v2.5.1版本3.5 Inference性能3.6 特定目标集Training 4. 参考资料 1. 源由 前期搭建《Ardupilot开源无人机之Geek SDK》&#xff0c;主要目的是…

《Spring Framework实战》3:概览

欢迎观看《Spring Framework实战》视频教程 Spring Framework 为基于现代 Java 的企业应用程序提供了全面的编程和配置模型 - 在任何类型的部署平台上。 Spring 的一个关键要素是应用程序级别的基础设施支持&#xff1a;Spring 专注于企业应用程序的 “管道”&#xff0c;以便…

Linux初识——基本指令

我们在linux下输入各种指令&#xff0c;其实就相当于在windows中的相关操作&#xff0c;比如双击&#xff0c;新建文件夹等。 以下是相关基本指令基本用法 一.ls&#xff08;显示当前目录下的所有文件和目录&#xff09; 那如何显示当前目录&#xff08;我们所在的位置&…

小程序开发-页面事件之上拉触底实战案例

&#x1f3a5; 作者简介&#xff1a; CSDN\阿里云\腾讯云\华为云开发社区优质创作者&#xff0c;专注分享大数据、Python、数据库、人工智能等领域的优质内容 &#x1f338;个人主页&#xff1a; 长风清留杨的博客 &#x1f343;形式准则&#xff1a; 无论成就大小&#xff0c;…

医疗可视化大屏 UI 设计新风向

智能化交互 借助人工智能与机器学习技术&#xff0c;实现更智能的交互功能。如通过语音指令或手势控制来操作大屏&#xff0c;医护人员无需手动输入&#xff0c;可更便捷地获取和处理信息。同时&#xff0c;系统能根据用户的操作习惯和数据分析&#xff0c;自动推荐相关的医疗…

IT面试求职系列主题-Jenkins

想成功求职&#xff0c;必要的IT技能一样不能少&#xff0c;先说说Jenkins的必会知识吧。 1) 什么是Jenkins Jenkins 是一个用 Java 编写的开源持续集成工具。它跟踪版本控制系统&#xff0c;并在发生更改时启动和监视构建系统。 2&#xff09;Maven、Ant和Jenkins有什么区别…

力扣刷题:数组OJ篇(上)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 目录 1.消失的数字&#xff08;1&#xff09;题目描…

2024 高级爬虫笔记(六)scrapy框架基础知识

目录 一、Scrapy框架基础知识1.1、什么是scrapy&#xff1f;1.2、scrapy的工作流程1.3、scrapy中每个模块的作用&#xff1a;1.4、scrapy的入门使用1.4.1 安装scrapy1.4.2、scrapy项目实现流程1.4.3、创建scrapy项目1.4.4、创建爬虫1.4.5、完善spider1.4.6、配置settings文件1.…

每日一题-两个链表的第一个公共结点

文章目录 两个链表的第一个公共结点问题描述示例说明示例 1示例 2 方法及实现方法描述代码实现 复杂度分析示例运行过程示例 1示例 2 总结备注 两个链表的第一个公共结点 问题描述 给定两个无环的单向链表&#xff0c;找到它们的第一个公共节点。如果没有公共节点&#xff0c…

Elasticsearch:在 HNSW 中提前终止以实现更快的近似 KNN 搜索

作者&#xff1a;来自 Elastic Tommaso Teofili 了解如何使用智能提前终止策略让 HNSW 加快 KNN 搜索速度。 在高维空间中高效地找到最近邻的挑战是向量搜索中最重要的挑战之一&#xff0c;特别是当数据集规模增长时。正如我们之前的博客文章中所讨论的&#xff0c;当数据集规模…

两种方式实现Kepware与PLC之间的心跳检测

两种方式实现Kepware与PLC之间的心跳检测 实现Kepware与PLC之间的心跳检测1.OPCUA 外挂程序2.Kepware Advanced Tag 实现Kepware与PLC之间的心跳检测 1.OPCUA 外挂程序 这是通过上位程序来触发心跳的一种机制&#xff0c;在C#中&#xff0c;可以利用OPC UAOPCAutodll的方式…

python-leetcode-文本左右对齐

68. 文本左右对齐 - 力扣&#xff08;LeetCode&#xff09; class Solution:def fullJustify(self, words: List[str], maxWidth: int) -> List[str]:result []current_line []current_length 0for word in words:# 如果当前行加上这个单词后超过 maxWidth&#xff0c;则…

全新免押租赁系统打造便捷安全的租赁体验

内容概要 全新免押租赁系统的推出&#xff0c;标志着租赁行业的一次重大变革。这个系统的最大特点就是“免押金”&#xff0c;大大减轻了用户在租赁过程中的经济负担。从此&#xff0c;不再需要为一部手机或其他商品支付高昂的押金&#xff0c;用户只需通过简单的信用评估&…

WordPress静态缓存插件WP Super Cache与 WP Fastest Cache

引言 WordPress是一款开源的内容管理系统&#xff08;CMS&#xff09;&#xff0c;最初作为博客平台开发&#xff0c;现已发展成为一个功能强大的建站工具&#xff0c;支持创建各种类型的网站&#xff0c;包括企业网站、在线商店、个人博客等。它具有用户友好的界面、丰富的插…