2012-06-22 5 views
6

У меня есть приложение, которое решает систему уравнений в CUDA, я точно знаю, что каждый поток может найти до 4 решений, но как я могу скопировать их обратно на хост?Как эффективно собирать данные из потоков в CUDA?

Я прохожу мимо огромного массива с достаточным пространством для всех потоков, хранящим 4 решения (4 двухместных для каждого решения), а другой - с количеством решений на поток, однако это наивное решение и является текущим узким местом моего ядра.

Я действительно хочу оптимизировать эту тему. Основная проблема заключается в конкатенации переменной количества решений на поток в одном массиве.

+0

Было бы намного легче помочь, если бы я знал что-то о вашей программе. Насколько мне известно (прошло около года с тех пор, как я возился с кудой, поэтому я мог ошибаться), memcopies - единственный способ получить информацию, и они медленны. А какая версия куды на какой карточке? – 8bitwide

+0

У меня есть CUDA 4.0 и 4.2. – RSFalcon7

+0

Код слишком велик, чтобы поместить его здесь. Я согласен с тем, что cudaMemCpy - это единственный способ получить результаты, но я мог избежать копирования мусора. – RSFalcon7

ответ

5

Функциональность, которую вы ищете, называется уплотнением потока.

Возможно, вам необходимо предоставить массив, содержащий место для 4 решений на поток, поскольку попытка прямого хранения результатов в компактной форме, вероятно, создаст так много зависимостей между потоками, что производительность, получаемая при копировании меньше данных обратно на хост теряется более длительным временем выполнения ядра. Исключением является то, что почти все потоки не найдут решений. В этом случае вы можете использовать атомную операцию для поддержания индекса в массиве. Итак, для каждого найденного решения вы сохраните его в массиве с индексом, а затем используйте атомную операцию для увеличения индекса. Я думаю, что для этого было бы безопасно использовать atomicAdd(). Прежде чем сохранить результат, поток будет использовать atomicAdd(), чтобы увеличить индекс на единицу. atomicAdd() возвращает старое значение, и поток может сохранять результат, используя старое значение в качестве индекса.

Однако, учитывая более распространенную ситуацию, когда имеется множество результатов, лучшим решением будет выполнение операции уплотнения в виде отдельного шага. Один из способов сделать это - thrust::copy_if. См. this question для получения дополнительной информации.

Смежные вопросы