Я написал это ядро CUDA для игры жизни Конвея:
__global__ void gameOfLife(float* returnBuffer, int width, int height) {
unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
float p = tex2D(inputTex, x, y);
float neighbors = 0;
neighbors += tex2D(inputTex, x+1, y);
neighbors += tex2D(inputTex, x-1, y);
neighbors += tex2D(inputTex, x, y+1);
neighbors += tex2D(inputTex, x, y-1);
neighbors += tex2D(inputTex, x+1, y+1);
neighbors += tex2D(inputTex, x-1, y-1);
neighbors += tex2D(inputTex, x-1, y+1);
neighbors += tex2D(inputTex, x+1, y-1);
__syncthreads();
float final = 0;
if(neighbors < 2) final = 0;
else if(neighbors > 3) final = 0;
else if(p != 0) final = 1;
else if(neighbors == 3) final = 1;
__syncthreads();
returnBuffer[x + y*width] = final;
}
Я ищу ошибки / оптимизацию. Параллельное программирование для меня довольно ново, и я не уверен, правильно ли я понял, как это сделать.
Остальное - это memcpy из входного массива в 2D-текстуру inputTex, привязанную к массиву CUDA. Вывод запоминается из глобальной памяти на хост, а затем обрабатывается.
Как вы можете видеть, поток имеет дело с одним пикселем. Я не уверен, что это самый быстрый способ, поскольку некоторые источники предлагают делать строку или больше для каждого потока. Если я правильно понял, сами NVidia говорят, что чем больше потоков, тем лучше. Я хотел бы получить совет от кого-нибудь с практическим опытом.