CUDAExample: 波纹示例
需要用到的已经封装好的辅助类: CPUAnimBitmap
定义个grid 和 block 的维度都是二维的
#include"cpu_anim.h"
#include "cuda_runtime.h"
#include <device_launch_parameters.h>#define DIM 512
static void CheckCudaErrorAux(const char*, unsigned, const char*, cudaError_t);
#define CUDA_CHECK_RETURN(value) CheckCudaErrorAux(__FILE__,__LINE__, #value, value)struct DataBlock
{unsigned char* dev_bitmap;CPUAnimBitmap* bitmap;
};void cleanup(DataBlock *d)
{cudaFree(d->dev_bitmap);
}// 第一个指针来指向北村输出像素值的设备内存,是一个全局变量
// ticks 表示当前的动画时间
__global__ void kernel(unsigned char * imageptr, int ticks)
{// 每个线程都得到它在线程块中的索引,以及这个线程块在线程格中的索引// 并将这两个值转换为图形中的唯一索引(x,y)int x = threadIdx.x + blockIdx.x * blockDim.x;int y = threadIdx.y + blockIdx.y * blockDim.y;int offset = x + y * blockDim.x * gridDim.x;// 计算当前位置上的值float fx = x - DIM / 2;float fy = y - DIM / 2;float d = sqrtf(fx * fx + fy * fy);unsigned char grey = (unsigned char)(128.0f + 127.0f * cos(d / 10.0f - ticks / 7.0f) / (d / 10.0f + 1.0f));imageptr[offset * 4 + 0] = grey;imageptr[offset * 4 + 1] = 0;imageptr[offset * 4 + 2] = 255 - grey;imageptr[offset * 4 + 3] = 255;}// 根据时间戳ticks生成新的图像
void generate_frame(DataBlock *d, int ticks)
{// 线程格中包含的并行线程块的数量dim3 blocks(DIM / 16, DIM / 16);// 每个线程块中包含的线程数量dim3 threads(16, 16);kernel <<<blocks, threads>>> (d->dev_bitmap, ticks);CUDA_CHECK_RETURN(cudaMemcpy(d->bitmap->get_ptr(),d->dev_bitmap,d->bitmap->image_size(),cudaMemcpyDeviceToHost));
}int main(void)
{DataBlock data;CPUAnimBitmap bitmap(DIM, DIM, &data);data.bitmap = &bitmap;std::cout << "image size : " << data.bitmap->image_size() << std::endl;CUDA_CHECK_RETURN(cudaMalloc((void**)&data.dev_bitmap, bitmap.image_size()));// 将指向generate_frame()的函数指针传递给anim_and_exit()// 每当要生生成一帧新的动画都会调用generate_frame()bitmap.anim_and_exit((void(*)(void *,int))generate_frame, (void(*)(void*))cleanup);return 0;
}static void CheckCudaErrorAux(const char* file, unsigned line, const char* statement, cudaError_t err)
{if (err == cudaSuccess)return;std::cerr << statement << " returned " << cudaGetErrorString(err) << "(" << err << ") at " << file << ":" << line << std::endl;exit(1);
}