#c #c #cuda
#c #c #cuda
Вопрос:
я всегда читал, что выделение и передача данных из cpu в gpu происходит медленно. это потому, что cudaMalloc работает медленно? это потому, что cudaMemcpy работает медленно? или это потому, что оба они медленные?
Ответ №1:
В основном это связано с двумя вещами, первая из которых определяет скорость шины PCIExpress между картой и процессором. Другой связан с тем, как работают эти функции. Теперь, я думаю, что новый CUDA 4 имеет лучшую поддержку выделения памяти (стандартную или закрепленную) и способ прозрачного доступа к памяти по шине.
Теперь давайте посмотрим правде в глаза: в какой-то момент вам понадобится получить данные из точки A в точку B, чтобы что-то вычислить. Лучший способ справиться с этим — либо выполнить действительно большие вычисления, либо использовать потоки CUDA для перекрытия передачи и вычислений на графическом процессоре.
Ответ №2:
В большинстве приложений вы должны выполнять cudaMalloc один раз в начале, а затем больше не вызывать его. Таким образом, узким местом на самом деле является cudaMemcpy.
Это связано с физическими ограничениями. Для стандартного соединения PCI-E 2.0 x16 теоретически вы получите 8 ГБ / с, но на практике обычно 5-6 ГБ / с. Сравните это даже с Fermi среднего уровня, таким как GTX460, пропускная способность которого превышает 80 Гбит / с. Фактически вы на порядок сокращаете пропускную способность памяти, соответственно увеличивая время передачи данных.
Предполагается, что GPGPU являются суперкомпьютерами, и я верю, что Сеймур Крэй (специалист по суперкомпьютерам) сказал: «суперкомпьютер превращает проблемы, связанные с вычислениями, в проблемы, связанные с вводом-выводом». Таким образом, оптимизация передачи данных — это все.
По моему личному опыту, итеративные алгоритмы — это те, которые на сегодняшний день демонстрируют наилучшие улучшения при переносе на GPGPU (на 2-3 порядка величины) из-за того, что вы можете сократить время передачи, сохранив все на месте на GPU.
Комментарии:
1. в моем случае все наоборот …. я делаю один cudaMemcpy и много cudaMalloc….
2. Не могли бы вы подробнее рассказать о своем приложении? Вы просто храните много преобразованных копий?
3. что ж, в моем случае у меня есть входные данные… но я не могу определить, сколько памяти мне нужно выделить для решения этого ввода. поэтому я делаю единственную копию входных данных …. и выделяю глобальную память всякий раз, когда это необходимо. другими словами, я выделяю новую память, когда предыдущая память заполнена. (обратите внимание, что мне понадобится вся выделенная память для вычисления полного результата …)