最近在学习cuda by example第六章时发现代码看不太懂(本人小菜鸡勿喷),经过学习(chatgpt的帮助)后对这段代码有了比较清晰的理解,于是打算对这段代码进行一个注解,仅供学习,如果大家有发现不对的地方欢迎指正
定义线程块与线程一个线程块包含一个16*16的线程
int dim=1024
//dim3 是 CUDA 中定义三维向量的类型,用于指定网格的维度。网格是由多个线程块组成的。grids 定义了网格的尺寸为 64x64,这意味着在网格中会有 64 行和 64 列,总共 4096 个线程块
dim3 grids(DIM / 16, DIM / 16);
//这行代码定义了每个线程块的尺寸,也使用 dim3 这种三维向量类型。threads(16, 16) 表示每个线程块由 16x16 个线程组成,总共 256 个线程。
dim3 threads(16, 16);
以下是结构体注释
#include "cuda.h"
#include "../common/book.h"
#include "../common/cpu_bitmap.h"
#define DIM 1024//相当于设定了一个1024*1024的像素分布
#define rnd( x ) (x * rand() / RAND_MAX)
#define INF 2e10f
//定义一个球形结构体
struct Sphere {
float r, b, g; //定义球体颜色
float radius; //半径
float x, y, z; //原点坐标
__device__ float hit(float ox, float oy, float* n) {//ox,oy为平面上的一点可以理解为书中所说的像素,float* n用来返回一个比例系数
float dx = ox - x;//计算某一像素x坐标与球体x坐标的差值
float dy = oy - y;//计算某一像素y坐标与球体y坐标的差值
if (dx * dx + dy * dy < radius * radius) {//在xOy平面上判断是否在球面内
float dz = sqrtf(radius * radius - dx * dx - dy * dy);//通过勾股定理算以球中心点的xOy平面上这个像素到球体表面的距离
*n = dz / sqrtf(radius * radius);//计算一个比例系数(用来模拟光线减弱)
return dz + z;//返回实际上的像素点到球体表面的距离
}
return -INF;
}
};
#define SPHERES 20
以下是核函数的解释
__constant__ Sphere s[SPHERES];
__global__ void kernel(unsigned char* ptr) {
// map from threadIdx/BlockIdx to pixel position
//x 和 y:当前线程所负责的像素的 x 和 y 坐标。
/*blockIdx.x表示线程块的x方向(第一维)上的序号,
blockDim.x表示线程块x方向(第一维)上有几个线程*/
int x = threadIdx.x + blockIdx.x * blockDim.x;
/*blockIdx.y表示线程块的y方向(第二维)上的序号,
blockDim.y表示线程块y方向(第二维)上有几个线程*/
int y = threadIdx.y + blockIdx.y * blockDim.y;
//offset:计算每个像素在图像数据数组中的位置。offset 是 ptr 数组的索引,用于定位像素在内存中的位置。
int offset = x + y * blockDim.x * gridDim.x;//这里以一个二维数组去联想,x相当于列的序号,y相当于行的序号
//将 (x, y) 从图像的左上角为原点的坐标系转换到图像中心为原点的坐标系
float ox = (x - DIM / 2);
float oy = (y - DIM / 2);
//给一个默认r,g,b参数,即背景参数(注意下面代码*255,这几个参数相当于系数)
float r = 1, g = 1, b = 1;
float maxz = -INF;
for (int i = 0; i < SPHERES; i++) {
float n;//比例系数用来模拟光线减弱
float t = s[i].hit(ox, oy, &n);
if (t > maxz) {
float fscale = n;//之前所说的比例系数,用来模拟光线减弱
r = s[i].r * fscale;
g = s[i].g * fscale;
b = s[i].b * fscale;
maxz = t;
}
}
//一个像素有四个属性r,g,b,透明度
ptr[offset * 4 + 0] = (int)(r * 255);
ptr[offset * 4 + 1] = (int)(g * 255);
ptr[offset * 4 + 2] = (int)(b * 255);
ptr[offset * 4 + 3] = 255;
}
计算时间的代码就不注释了,主要就解释一下核函数以及结构体,如果有错误还请大家指正