CUDA GPU编程


CUDA

随着显卡的发展,GPU越来越强大,而且GPU为显示图像做了优化。在计算上已经超越了通用的CPU。如此强大的芯片如果只是作为显卡就太浪费了,因此NVidia推出CUDA,让显卡可以用于图像计算以外的目的。

host 指代CPU及其内存,
device指代GPU及其内存。

CUDA程序中既包含host程序,又包含device程序,它们分别在CPU和GPU上运行。同时,host与device之间可以进行通信,它们之间可以进行数据拷贝。

GPU并行化的工作流程:

CPU发送一种称为kernel的函数到GPU。
GPU同时运行该函数的多个版本,称为threads。thread可以组合成block,一个kernel里的所有thread称为一个grid。

threads :thread的不同版本
block : 多个thread组成
grid:一个kernel里的所有thread

修饰符

__host__ 修饰符
__global__ 修饰符
__device__ 修饰符


__global__

__global__CUDA C/C++的函数修饰符,表示该函数为一个kernel函数,且

  1. 该函数会在GPU(device)上执行。
  2. 必须返回void
  3. 由主机(host)代码调用。
  4. 只能被CPU调用。

在调用kernel函数时,函数名后的<<<b, t>>>

  • b代表block的数目。
  • t代表每个block中thread的数目。
//kernel函数需要运行在4个block上,每个block有2个thread
__global__ void myKernel() {
	// ...
}

void main()
{
	int block,thread;
	block=4;
	thread=2;
	myKernel<<<block,thread>>>();
}

__host__

  • 运行在CPU上,每次调用运行一次。
  • 只能被CPU调用。
  • 所有未显式标明函数前置修饰符的函数均为host函数。

__device__

  • 运行在GPU上,每次调用运行一次。
  • 只能被GPU调用。
#include <stdio.h>

__device__ int dev1() {
}
__device__ int dev2() {
}
__global__ void run10Times() {
	//your code here
	dev1();
	dev2();
	//end of your code
}

int main() {
	run10Times<<<2, 5>>>();
	printf("Hello, World!\n");
	return 0;
}

内存分配

cudaMalloc 分配设备上的内存
cudaMemcpy 将不同内存段的数据进行拷贝
cudaFree 释放先前在设备上申请的内存空间

__host__ cudaError_t cudaMalloc (void **devPtr, size_t size)
	/*该函数主要用来分配设备上的内存(即显存中的内存)。该函数被声明为了__host__,即表示被host所调用,即在cpu中执行的代码所调用。
    返回值:为cudaError_t类型,实质为cudaError的枚举类型,其中定义了一系列的错误代码。如果函数调用成功,则返回cudaSuccess。
    第一个参数,void ** 类型,devPtr:用于接受该函数所分配的内存地址。
    第二个参数,size_t类型,size:指定分配内存的大小,单位为字节。*/ 

__host__ cudaError_t cudaMemcpy (void *dst, const void *src, size_t count, enum cudaMemcpyKind kind)
    /*
    该函数主要用于将不同内存段的数据进行拷贝,内存可用是设备内存,也可用是主机内存
    第一个参数,void*类型,dst:为目的内存地址
    第二个参数,const void *类型,src:源内存地址
    第三个参数,size_t类型,count:将要进行拷贝的字节大小
    第四个参数,enum cudaMemcpyKind类型,kind:拷贝的类型,决定拷贝的方向。
    cudaMemcpyKind类型如下:cudaMemcpyHostToHost, cudaMemcpyHostToDevice, cudaMemcpyDeviceToHost, cudaMemcpyDeviceToDevice, cudaMemcpyDefault。*/ 
    
__host__ cudaError_t cudaFree (void* devPtr)
    /*该函数用来释放先前在设备上申请的内存空间(通过cudaMalloc、cudaMallocPitch等函数),注意,不能释放通过标准库函数malloc进行申请的内存。
    返回值:为错误代码的类型值。
    第一个参数,void**类型,devPtr:指向需要释放的设备内存地址。*/ 

cudaMemcpyKind类型如下:
cudaMemcpyHostToHost,
cudaMemcpyHostToDevice,
cudaMemcpyDeviceToHost,
cudaMemcpyDeviceToDevice,
cudaMemcpyDefault。

#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <cuda_runtime.h> 

__global__ void colonel(int *a_d){
	//your code here
    *a_d = 2;
	//end of your code
}

int main(){
	int a = 0, *a_d;
	cudaMalloc((void**) &a_d, sizeof(int));
	cudaMemcpy(a_d, &a, sizeof(int), cudaMemcpyHostToDevice);
	colonel<<<1, 1>>>(a_d); 
  
	cudaMemcpy(&a, a_d, sizeof(int), cudaMemcpyDeviceToHost);

	printf("a = %d\n", a);
	cudaFree(a_d);
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值