第一个CUDA程序
教材《GPU高性能编程CUDA实战》第三章
将CPU以及系统的内存成为主机,将GPU及其内存称为设备,在GPU设备上执行的函数通常称为核函数(kernel)
- 可以将cudaMalloc()分配的指针传递给在设备上执行的函数
- 可以在设备代码中使用cudaMalloc()分配的指针进行内存读/写操作。
- 可以将cudaMalloc()分配的指针传递给主机上执行的函数。
- 不能在主机代码中使用cudaMalloc()分配的指针进行内存读/写操作。
- 主机指针只能访问主机代码中的内存,设备指针只能访问设备代码中的内存。
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
#include <stdio.h>
#include <Windows.h>//包含system
#include "book.h"//头文件包含HANDLE_ERROR,头文件下载地址见文末
__global__ void kernel() {//核函数,__global__修饰符告诉编译器,函数应改编译为在设备而不是主机运行
}
__global__ void add(int a, int b, int *c) {
*c = a + b;
}
int main() {//交给主机编译器(vs编译器)
kernel <<<1, 1>>> ();//函数调用,调用设备代码,交给编译设备代码的编译器
//<<<1,1>>>为修饰字符,这些参数并不是传给设备代码的参数,而是告诉运行时如何启动设备代码,括号中的参数和标准函数调用一样
printf("hello world\n");
int c;
int *dev_c;
HANDLE_ERROR(cudaMalloc((void**)&dev_c, sizeof(int)));//和C的malloc类似,开辟内存,返回void*
add <<<1, 1 >>>(2, 7, dev_c);
HANDLE_ERROR(cudaMemcpy(&c, dev_c, sizeof(int), cudaMemcpyDeviceToHost));//和C的memcpy类似,内存拷贝,cudaMemcpyDeviceToHost表示从设备拷贝到主机
printf("2+7=%d\n", c);
cudaFree(dev_c);//类似C的free,释放
int count;
int dev;
cudaDeviceProp prop;//包含设备属性的结构体
HANDLE_ERROR(cudaGetDeviceCount(&count));//获取本机支持CUDA的处理器数量
std::cout << count << std::endl;//count=1
for (int i = 0; i < count; i++) {
HANDLE_ERROR(cudaGetDeviceProperties(&prop, i));//获取设备属性,将结果存入prop中
printf("Name: %s\n", prop.name);//设备名称
printf("Compute capability:%d.%d\n", prop.major, prop.minor);//主版本号.次版本号
}
cudaDeviceProp prop1;
int dev1;
HANDLE_ERROR(cudaGetDevice(&dev));//返回当前CUDA设备的的ID
std::cout << dev << std::endl;//dev=0
memset(&prop1, 0, sizeof(cudaDeviceProp));//将地址prop1处的前sizeof(cudaDeviceProp)字节的内存赋为0
prop1.major = 1;
prop1.minor = 1;//将版本号属性填充为6.1
HANDLE_ERROR(cudaChooseDevice(&dev, &prop));//返回值是上述版本号最相近的设备IDdev
std::cout << dev << std::endl;//dev=0
HANDLE_ERROR(cudaSetDevice(dev));//将上述返回的ID传过来,以后所有操作都在这个设备上执行
system("pause");
return 0;
}
book.h头文件:https://pan.baidu.com/s/13rQOm
cuda编程指南5.0:https://pan.baidu.com/s/1i3BReEp