01 初见CUDA

头文件

#include  

数据类型

1. cudaError_t;

返回值类型:cudaSuccess、cudaErrorInvalidDevice
如果之前是异步启动,可能返回错误码。

2.struct cudaDeviceProp;
struct cudaDeviceProp { 

char name [256]; //用于标识设备的ASCII字符串;
size_t totalGlobalMem; //可用全局存储器总量 单位:字节
size_t sharedMemPerBlock; //block可以使用共享存储器的最大值 单位:字节
int regsPerBlock;  //block可以使用的32位寄存器的最大值
                   //?多处理器上的所有block可以同时共享这些寄存器;?
int warpSize;   //考虑到latency 用warp为基本单位进行调度
                //一般 32个thread为一个warp
                //warp是调度和执行的基本单位, half-warp是存储器操作的基本单位
size_t memPitch;  
     //允许通过cudaMallocPitch()为包含存储器区域的存储器复制函数分配的最大间距(pitch)
     //以字节为单位;
int maxThreadsPerBlock; //每个block中最大线程数
int maxThreadsDim [3];  //块维度的最大值
int maxGridSize [3];    //网格各个维度的最大值;
size_t totalConstMem;   //设备上可用的不变存储器总量,以字节为单位;
int major;      //主设备号 
int minor;      //次设备号 
int clockRate;   //时钟频率 单位:千赫 kh
size_t textureAlignment; //对齐要求 
                         //与textureAlignment字节对齐的纹理基址无需对纹理取样应用偏移;
int deviceOverlap; //如果设备可在主机和设备之间并发复制存储器,同时又能执行内核,则此值为 1;
                   //否则此值为 0;
int multiProcessorCount; //设备上多处理器的数量
}

常用函数

标准 C CUDA C
malloc cudaMalloc
memcpy cudaMemcpy
memset cudaMemset
free cudaFree

1.获取CUDA设备数

    cudaError_t cudaGetDeviceCount(int*device);

例:

Int device;
cudaGetDeviceCount(&device);

2.获取CUDA设备属性

cudaError_t cudaGetDeviceProperties(cudaDeviceProp *prop, int device);

以*prop形式返回设备dev的属性。
返回值类型:cudaSuccess、cudaErrorInvalidDevice

例:

cudaDeviceProp prop;
if (cudaGetDeviceProperties(&prop, int dev) == cudaSuccess){} 

3.设置设备以供GPU使用

cudaError_t cudaSetDevice(int *dev);

4.返回当前使用的设备

cudaError_t cudaGetDevice(int *dev);

5.分配device内存空间

cudaError_t cudaMalloc (void **devPtr, size_t  size );

例:int *gpudata; //指向GPU中的数据

cudaMalloc((void**)&gpudata, sizeof(int)* DATA_SIZE);

6.Copy数据到内存

cudaError_t cudaMemcpy(void*dst, const void*src, size_t count, cudaMemcpyKind kind)

其中cudaMemcpykind的可选类型有:

cudaMemcpyHostToHost
cudaMemcpyHossToDevice
cudaMemcpyDeviceToHost
cudaMemcpuDeviceToDevice

CUDA核函数

核函数不能有返回值 需要通过参数返回结果

_global_ void function(参数表);

执行核函数:

函数名称<<>>(参数...);

计算完成后:千万别忘了还要把结果从显示芯片复制回主内存上,然后释放掉内存~

 int sum;
 //cudaMemcpy 将结果从显存中复制回内存
 cudaMemcpy(&sum, result, sizeof(int), cudaMemcpyDeviceToHost);
 //Free
 cudaFree(gpudata);
 cudaFree(result);

评估CUDA

1 核函数运行时间:

#include  

核函数无返回值 将时间作为核函数参数(clock_t* time)返回

clock_t start = clock();
…
…
*time = clock() – start;

clock_t time_used;
cudaMemcpy(&time_used, time, sizeof(clock_t), cudaMemcpyDeviceToHost);

GPU核函数运行时间: time_used/(clockRate*1000)

2 计算使用的内存带宽
数据量/运行时间

3 优化
连续的内存读取
数据读取和操作时 是按照线程的顺序循环,即在 thread0 存取等待时 thread1进行存取,依次递推。
所以想要实现读取的连续,每个thread读取的内存就是跳跃式分布的。
借图:
01 初见CUDA_第1张图片
01 初见CUDA_第2张图片

参考:

https://blog.csdn.net/sunmc1204953974/article/category/6156113

你可能感兴趣的:(并行CUDA)