Основным замедлением будет доступ к основной памяти. Поэтому я бы посоветовал вам выбрать большой размер блока нитей в зависимости от имеющегося у вас оборудования. 256 (16x16) - хороший выбор для кросс-аппаратной совместимости. Каждый из этих потоковых блоков будет рассчитывать результаты для немного меньшей секции платы - если вы использовали 16x16, они будут вычислять результаты для секции 14x14 платы, поскольку существует граница из одного элемента. (Причиной использования блока 16x16 для вычисления фрагмента 14x14 вместо фрагмента 16x16 является объединение чтения памяти.)
Разделите доску на (скажем) 14x14 кусков; это ваша сетка (организована так, как вы считаете нужным, но, скорее всего, что-то вроде board_width / 14
, board_height / 14
.
В ядрах каждый поток загружает свой элемент в общую память. Тогда синхронизируй. Затем средние элементы 14x14 рассчитывают новое значение (используя значения, хранящиеся в общей памяти) и записывают его обратно в глобальную память. Использование разделяемой памяти помогает минимизировать глобальное чтение и запись. Это также является причиной того, чтобы размер блока вашего потока был как можно большим - ребра и углы «теряют» глобальный доступ к памяти, поскольку извлекаемые там значения используются только 1 или 3 раза, а не 9 раз.