Я разрабатываю ядро пересечения плоскости луча CUDA.
Предположим, моя структура плоскости (лица):
typedef struct _Face {
int ID;
int matID;
int V1ID;
int V2ID;
int V3ID;
float V1[3];
float V2[3];
float V3[3];
float reflect[3];
float emmision[3];
float in[3];
float out[3];
int intersects[RAYS];
} Face;
Я вставил всю структуру, чтобы вы могли получитьИдея его размера. RAYS равно 625 в текущей конфигурации.В следующем коде предположим, что размер массива Faces составляет, например, 1270 (обычно - тысячи).
Теперь до сегодняшнего дня я очень наивно запускал свое ядро:
const int tpb = 64; //threads per block
dim3 grid = (n +tpb-1)/tpb; // n - face count in array
dim3 block = tpb;
//.. some memory allocation etc.
theKernel<<<grid,block>>>(dev_ptr, n);
внутри ядра у меня был цикл:
__global__ void theKernel(Face* faces, int faceCount) {
int offset = threadIdx.x + blockIdx.x*blockDim.x;
if(offset >= faceCount)
return;
Face f = faces[offset];
//..some initialization
int RAY = -1;
for(float alpha=0.0f; alpha<=PI; alpha+= alpha_step ){
for(float beta=0.0f; beta<=PI; beta+= beta_step ){
RAY++;
//..calculation per ray in (alpha,beta) direction ...
faces[offset].intersects[RAY] = ...; //some assignment
Это об этом.Я перебрал все направления и обновил массив face .Я работал правильно, но вряд ли был быстрее, чем код процессора.
Поэтому сегодня я попытался оптимизировать код и запустить ядро с гораздо большим количеством потоков.Вместо 1 нити на лицо я хочу 1 нить на луч лица (то есть 625 нитей работают на 1 лицо).Модификации были просты:
dim3 grid = (n*RAYS +tpb-1)/tpb; //before launching . RAYS = 625, n = face count
и само ядро:
__global__ void theKernel(Face *faces, int faceCount){
int threadNum = threadIdx.x + blockIdx.x*blockDim.x;
int offset = threadNum/RAYS; //RAYS is a global #define
int rayNum = threadNum - offset*RAYS;
if(offset >= faceCount || rayNum != 0)
return;
Face f = faces[offset];
//initialization and the rest.. again ..
И этот код не работает вообще.Зачем?Теоретически, должен работать только 1-й поток (из 625 на одну грань), так почему же это приводит к плохим (почти никаким) вычислениям?
С уважением, например.