Это обычный способ выполнения сокращений в CUDA
Внутри каждого блока
1) Сохранять текущее уменьшенное значение в общей памяти для каждого потока. Следовательно, каждый поток будет читать (я лично предпочитаю от 16 до 32) значения из глобальной памяти и обновлять уменьшенное значение из этих
2) Выполните алгоритм уменьшения в блоке, чтобы получить одно окончательное уменьшенное значение на блок.
Таким образом, вам не нужно больше разделяемой памяти, чем (число потоков) * sizeof (datatye) байтов.
Поскольку каждый блок имеет уменьшенное значение, вам потребуется выполнить второй проход сокращения, чтобы получить окончательное значение.
Например, если вы запускаете 256 потоков на блок и читаете 16 значений на поток, вы сможете уменьшить (256 * 16 = 4096) элементов на блок.
Итак, учитывая 1 миллион элементов, вам нужно будет запустить около 250 блоков на первом проходе и всего один блок на втором.
Вероятно, вам потребуется третий проход для случаев, когда количество элементов> (4096) ^ 2 для этой конфигурации.
Вы должны позаботиться о том, чтобы считывания глобальной памяти были объединены. Вы не можете объединить записи в глобальную память, но это один удар производительности, который вам нужно предпринять.