Я пытаюсь преобразовать код C++ в код Cuda, и у меня есть следующий тройной вложенный цикл цикла, который заполнит массив для дальнейшего рендеринга OpenGL (я просто создаю массив вершин координат):Cuda triple inested for loop assignement
for(int z=0;z<263;z++) {
for(int y=0;y<170;y++) {
for(int x=0;x<170;x++) {
g_vertex_buffer_data_3[i]=(float)x+0.5f;
g_vertex_buffer_data_3[i+1]=(float)y+0.5f;
g_vertex_buffer_data_3[i+2]=-(float)z+0.5f;
i+=3;
}
}
}
Я хотел бы получить более быстрые операции, поэтому я буду использовать Cuda для некоторых операций, подобных перечисленным выше. Я хочу создать один блок для каждой итерации самого внешнего цикла, и поскольку внутренние петли имеют итерации 170 * 170 = 28900 тотальных итераций, назначьте один поток для каждой самой внутренней итерации цикла. Я преобразовал C++ код в это (это просто небольшая программа, которая я сделал, чтобы понять, как использовать Cuda):
__global__ void mykernel(int k, float *buffer) {
int idz=blockIdx.x;
int idx=threadIdx.x;
int idy=threadIdx.y;
buffer[k]=idx+0.5;
buffer[k+1]=idy+0.5;
buffer[k+2]=idz+0.5;
k+=3;
}
int main(void) {
int dim=3*170*170*263;
float* g_vertex_buffer_data_2 = new float[dim];
float* g_vertex_buffer_data_3;
int i=0;
HANDLE_ERROR(cudaMalloc((void**)&g_vertex_buffer_data_3, sizeof(float)*dim));
dim3 dimBlock(170, 170);
dim3 dimGrid(263);
mykernel<<<dimGrid, dimBlock>>>(i, g_vertex_buffer_data_3);
HANDLE_ERROR(cudaMemcpy(&g_vertex_buffer_data_2,g_vertex_buffer_data_3,sizeof(float)*dim,cudaMemcpyDeviceToHost));
for(int j=0;j<100;j++){
printf("g_vertex_buffer_data_2[%d]=%f\n",j,g_vertex_buffer_data_2[j]);
}
cudaFree(g_vertex_buffer_data_3);
return 0;
}
Попытка запустить его я получаю ошибку segmenation. Знаете ли вы, что я делаю неправильно? Я думаю, проблема в том, что threadIdx.x и threadIdx.y растут одновременно, хотя я бы хотел, чтобы threadIdx.x был внутренним, а threadIdx.y - внешним.
Я отредактировал первое, спасибо! Теперь я попробую со вторым, я должен найти правильный способ установить количество блоков на сетку и потоки на каждый блок. Для моего тройного вложенного цикла я должен использовать threadsId и blockId в качестве индексов для g_vertex_buffer_data_3 или использовать разные индексы, которые я увеличиваю в каждом цикле? –
Вместо того, чтобы работать с таким большим набором данных, вы можете начать с меньшего набора данных, чтобы исправить остальные проблемы, например: k + = 3 не выполняет то, что вы ожидаете, тест для переполнения буфера и g_vertex_buffer_data_2 протекает. После этого вы можете, например, разделяйте весь набор данных и вызывайте свое ядро CUDA несколько раз, чтобы обойти ограничение HW. Но сначала получите логику правильно. –
Спасибо большое! Как я могу сделать k + = 3 с CUDA? Я имею в виду, как я могу сказать Cuda, что делать k + = 3 в C++? –