В качестве альтернативы вы можете запустить двумерную сетку блоков.
blocks.x = numParticles / threadsPerBlock / repeatPerBlock.
blocks.y = numOfBoxes / 1024;
Каждый блок выполняет атомарные добавления в разделяемой памяти тогда и только тогда, когда boxnum лежит в диапазоне от 1024 * blockIdx.y до 1024 * (blockIdx.y + 1);
Затем следует сокращение вдоль блоков.x
Это может быть, а может и не быть быстрее, чем atomicAdd в глобальной памяти, так как данные читаются как блоки. Сколько раз. Однако это можно исправить, если «частицы» отсортированы по boxnum на этапе сортировки, за которым следует этап разделения.
Может быть несколько других способов сделать это, но, поскольку размер проблемы сильно варьируется, вам может понадобиться написать 2-3 различных метода, оптимизированных для данного диапазона размеров.