Краткая версия моего вопроса:
У меня есть программа CUDA, где каждый поток должен хранить числа в разных «корзинах», и я идентифицирую каждую из этих корзин целым числом. Для типичного запуска моей программы каждый поток CUDA может хранить только числа в 100 из миллионов бинов, поэтому я хотел бы знать, существует ли какая-либо структура данных, кроме массива, которая позволила бы мне хранить эти данные. Каждый поток будет иметь свою собственную копию этой структуры. Если бы я программировал на Python, я бы просто использовал словарь, в котором номера бинов являются ключами, например, mydict [0] = 1.0, mydict [2327632] = 3.0, а затем в конце цикла я посмотрел бы на ключи и что-то с ними делать (и игнорировать бункеры, где в них нет чисел, так как их нет в словаре). Я попытался реализовать хеш-таблицу для каждого потока в моей программе cuda, и это снизило производительность.
Длинная версия:
У меня есть симуляция CUDA Monte Carlo, которая имитирует перенос частиц через вокселизированную геометрию (простые элементы объема). Частицы отдают энергию во время своего транспорта, и эта энергия рассчитывается на основе вокселей на воксель. Воксели представлены в виде линеаризованной трехмерной сетки, которая довольно большая, около 180 ^ 3 элементов. Каждый поток CUDA транспортирует 1-100 частиц, и я обычно стараюсь максимально увеличить количество потоков, с которыми я порождаю свое ядро. (В настоящее время я использую 384 * 512 потоков). Энергия, депонированная в данном вокселе, добавляется к линеаризованной трехмерной сетке, которая находится в глобальной памяти через atomicAdd.
Я сталкиваюсь с некоторыми проблемами в части моего моделирования, которая связана с вычислением неопределенностей в моем моделировании. Для данной частицы, я должен отслеживать, где (какие индексы вокселей) она отдает энергию, и сколько энергии для данного вокселя, чтобы я мог возвести это число в квадрат в конце переноса частицы, прежде чем перейти к новому частиц. Поскольку я назначаю каждому потоку одну (или несколько) частиц, эта информация должна храниться в объеме для каждого потока. Причина, по которой я сталкиваюсь только с этой проблемой при расчете неопределенности, заключается в том, что осаждение энергии может быть просто выполнено как атомарная операция с глобальной переменной каждый раз, когда поток должен выделять энергию, но вычисление неопределенности должно быть сделано в конце переноса частицы. Поэтому мне нужно, чтобы каждый поток отслеживал «историю» назначенных им частиц.
Моя первая идея состояла в том, чтобы реализовать хеш-таблицу, ключом которой был бы линеаризованный индекс вокселя, а значением было бы выделение энергии, и я бы просто вычеркнул каждый элемент в этой хеш-таблице и добавил его в глобальную сетку неопределенности после частицы делается транспортировка. Я пытался реализовать Uthash, но это снизило производительность моего кода. Я предполагаю, что это вызвало огромное расхождение потоков.
Я мог бы просто использовать два динамических массива, где один хранит индекс вокселя, а другой хранит энергию, отведенную для этого вокселя, но я думаю, что это также будет очень плохо для производительности. Я надеюсь, что существует структура данных, о которой я не знаю, которая могла бы пригодиться для использования в программе CUDA. Я также попытался включить много деталей на случай, если я полностью ошибаюсь в своем подходе к проблеме.
Спасибо