c++ nvcc编译CUDA程序入门示例
nvcc
nvcc是NVIDIA CUDA Compiler,用来编译host和device程序。
这里的术语:
- host:指CPU及其内存
- device:指GPU及其内存
使用nvcc,就可以编译CUDA程序,CUDA程序包括host代码和device代码。
在安装CUDA Toolkit后,nvcc内含其中。
注意要安装与显卡版本匹配的CUDA Toolkit。
我的nvcc版本:
% nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2019 NVIDIA Corporation
Built on Wed_Oct_23_19:24:38_PDT_2019
Cuda compilation tools, release 10.2, V10.2.89
hello, world
作为第一个示例,非“hello, world”莫属。
编写以下代码,保存为demo.cpp:
#include <iostream>
#include <cuda_runtime.h>using namespace std;int main()
{cout << "hello, world!" << endl;return 0;
}
那么,该文件可以使用以下方式编译:
g++ demo.cpp
或者:
nvcc demo.cpp
它们都生成a.out,都输出“hello, world!”。
ok,这是第一次成功使用nvcc。
加入device代码
修改代码:
#include <iostream>
#include <cuda_runtime.h>using namespace std;__global__ void demo(void)
{}int main()
{demo<<<1,1>>>();cout << "hello, world!" << endl;return 0;
}
其中,__global__是CUDA C/C++关键字,指定该段代码在device上执行,并且从host上调用。
再用这两种方式编译时,都编译失败了。使用g++编译失败是必然,使用nvcc编译报错如下:
% nvcc demo.cpp
hello.cpp: In function ‘int main()’:
hello.cpp:12:11: error: expected primary-expression before ‘<’ tokendemo<<<1,1>>>();^
hello.cpp:12:17: error: expected primary-expression before ‘>’ tokendemo<<<1,1>>>();^
hello.cpp:12:19: error: expected primary-expression before ‘)’ tokendemo<<<1,1>>>();
这是因为nvcc使用文件扩展名来确定如何处理文件的内容。
如果文件中包含CUDA语法,则文件扩展名必须为.cu,否则nvcc会将未修改的文件直接传递给主机编译器,从而导致语法错误。
所以,把demo.cpp文件名修改为demo.cu即可使用nvcc编译通过。
输出同上。
ok,这是第一次成功使用nvcc编译device代码。
做点有意义的事
上个示例中,在device上什么也没有做,这次做一下矩阵加法运算,代码如下:
#include <iostream>
#include <cuda_runtime.h>using namespace std;__global__ void add(int *a, int *b, int *c, int n)
{int index = threadIdx.x + blockIdx.x * blockDim.x;if (index < n) {c[index] = a[index] + b[index];}
}void random_ints(int* a, int n)
{for (int i = 0; i < n; ++i)a[i] = rand();
}int main()
{int n = (2048 * 2048);int threads_per_block = 512;int *a, *b, *c;int *d_a, *d_b, *d_c;int size = n * sizeof(int);cudaMalloc((void**)&d_a, size);cudaMalloc((void**)&d_b, size);cudaMalloc((void**)&d_c, size);a = (int*)malloc(size);random_ints(a, n);b = (int*)malloc(size);random_ints(b, n);c = (int*)malloc(size);cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice);cudaMemcpy(d_b, b, size, cudaMemcpyHostToDevice);add<<<(n + threads_per_block - 1)/threads_per_block, threads_per_block>>>(d_a, d_b, d_c, n);cudaMemcpy(c, d_c, size, cudaMemcpyDeviceToHost);cudaFree(d_a);cudaFree(d_b);cudaFree(d_c);for (int i = 0; i < n; ++i) {cout << c[i] << ",";}cout << endl;cout << cudaGetErrorString(cudaGetLastError()) << endl;free(a);free(b);free(c);return 0;
}
示例虽小,五脏俱全。
流程梳理如下:
- 准备待处理数据
- 在device上分配存储空间
- 把数据从host拷贝到device
- 执行device运算
- 把结果从device拷贝回host
- 结束后释放device空间
- 回收host资源
更具体的细节后续博客中介绍。
小结
CUDA的入门还是比较简单的,根据这个流程做就行。
需要特别注意的是CUDA程序的文件名必须以cu后缀,这个有点反Linux,哈哈。
还有很多细节需要深刻理解,否则GPU的优势难以发挥,有点大炮打蚊子的嫌疑了。
c++ nvcc编译CUDA程序入门示例相关推荐
- CUDA编译(一)---使用nvcc编译cuda
CUDA编译(一)-使用nvcc编译cuda nvcc介绍 示例 nvcc介绍 nvcc是编译cuda程序的编译器,CDUA C是在C语言上的扩展,所以它依赖C编译器(C编译器在window下是cl. ...
- 使用gcc编译c语言程序,用GCC编译C ++程序
在这里,我们将看到如何使用GCC(GNU C编译器)编译C ++程序.让我们考虑一下,我们要编译这个程序. 示例#include using namespace std; main() { cout ...
- BizTalk 2006 简单入门示例程序(附源项目文件下载)
BizTalk 2006 简单入门示例程序(附源项目文件下载) 为初学BizTalk Server 2006的开发人员,提供一个简单入门的示例程序,包括一个Receive Port.Send Port ...
- cuda入门——改良第一个 CUDA程序
cuda入门--改良第一个 CUDA程序 在上篇中,我们做了一个计算一大堆数字的平方和的程序.不过,我们也提到这个程序的执行效率并不理想.当然,实际上来说,如果只是要做计算平方和的动作,用 CPU 做 ...
- CUDA以及NVCC编译流程
文章转载自: http://chenrudan.github.io/ 在安装CUDA的时候,会安装三个大的组件[1],分别是NVIDIA驱动.toolkit和samples.驱动用来控制gpu硬件,t ...
- canoe开发从入门到精通_xmake从入门到精通7:开发和构建Cuda程序
xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验. 本文我们会详细介绍下如何通过xmake来构建cud ...
- ADO.NET Entity Framework 入门示例向导(附Demo程序下载)
ADO.NET Entity Framework 入门示例向导(附Demo程序下载) ADO.NET Entity Framework 是.Net Framework 3.5 SP1 引入的实体框架, ...
- JavaFX官方教程(三)之JavaFX示例应用程序入门
翻译自 JavaFX示例应用程序入门 此示例应用程序集旨在帮助您开始使用常见的JavaFX任务,包括使用布局,控件,样式表,FXML和视觉效果. Hello World,JavaFX Style ...
- CUDA下的GPU编程入门--第一个CUDA程序
CUDA是NVIDIA公司开发的一个用于GPU编程的开源框架,用于将GPU用于更广泛的数学计算,充当cpu的功能,所以只能在nvidia的GPU下实现,如果你的GPU不是nvidia的,赶紧去换一个吧 ...
最新文章
- 第1关:利用栈实现整数的十进制转八进制
- docker编译Linux内核,c – 如何编译在docker中使用内核函数的C代...
- LINUX 下设置系统时间 DATE 命令
- Linux系统安装Apache 2.4.6
- 崛起于Springboot2.X之Mysql读写分离(6)
- linux 设置时钟 教程,Linux hwclock命令参数及用法详解--Linux显示/设置硬件时钟命令...
- 【个人总结】清除样式(间距、浮动、定位)
- 计算机不用鼠标怎么移动,如何在不使用鼠标的情况下拖动文件
- 基于Python的医院信息管理系统的设计与实现
- scratch 打字游戏
- STM32—TIMx输出PWM信号驱动MG996R舵机
- 故事系列之一:围棋世界里看天赋和勤奋
- Java 生成验证码。随机产生一个四位数的验证码,每位数可能是数字、大写字母或小写字母。
- 端午福利怎么发?苏宁大客户帮你“听取掌声一片”
- 简述PCM 30/32帧结构图
- 幂函数在计算机中怎么下,对数指数幂函数模拟计算机.doc
- 微型计算机是计算器吗,小型计算机和微型计算机是同一个吗?
- 【MSP430】基于MSP430G2553的超声波测距仪
- python程序设计丁亚涛版_Python程序设计
- canvas离线画板画图
热门文章
- 循环辅助:continue
- 综合布线 、 子网划分
- 外贸客户如何选择供应商:5R原则
- 2023.1完整版:适合的网盘,各大网盘对比测试,速度,安全性,可预计的未来
- 计算机组成,南北桥,倍频,通信,频率一致才可以通信
- linux用户的邮件存在哪里,在Linux系统中收发及查看邮件
- 曲速未来 发布:新基建下,区块链将急速发展
- HTML期末大作业~web前端开发个人博客HTML整站模板~Web大学生网页成品 ~个人主页博客网页HTML设计制作...
- 在Windows下安装BIND作为DNS服务器
- Excel表中查找、去除重复项方法合集