ArrayFire против необработанного программирования CUDA?

Я новичок в программировании на GPU, но поскольку у меня есть задача с интенсивными вычислениями, я обратился к GPU для возможного увеличения производительности.

Я попытался переписать свою программу с помощью версии ArrayFire Free. Это действительно быстрее, чем моя процедура ЦП с включенной многопоточностью, но не в той степени, которую я ожидал (то есть <100% ускорение), и возвращаемые результаты не совсем правильные (<1% ошибка по сравнению с процедурой ЦП, предполагая, что результаты процедуры CPU верны).

Моя задача - это в основном поэлементные математические операции с плавающей запятой-32 над большими матрицами (размером 300-500 МБ) с небольшими случаями if-thens / switch и т. Д. Я предполагаю, что узким местом производительности является пропускная способность между ЦП и памятью графического процессора, поскольку существует много чтения данных и т. д. Я тестировал графический процессор GeForce 580GTX с 3 ГБ видеопамяти.

Есть ли еще какие-то значительные возможности для оптимизации, если я напишу необработанный код CUDA (с CUBLAS и т. Д. И средней оптимизацией) вместо использования ArrayFire для моей задачи? Я прочитал несколько руководств по оптимизации NVIDIA; похоже, что есть некоторые уловки с доступом к памяти для более быстрого доступа к данным и уменьшения конфликтов банков. Использует ли ArrayFire эти общие приемы автоматически или нет?


person brbs2002    schedule 29.09.2012    source источник


Ответы (1)


Спасибо за сообщение. Рад слышать, что первые результаты дали некоторое ускорение. Я работаю над ArrayFire и могу ответить на ваши вопросы.

Прежде всего, здесь действительно требуется код, чтобы любой мог помочь с конкретикой. Вы можете поделиться написанным кодом?

Во-вторых, вы должны думать о CUDA и ArrayFire следующим образом: CUDA - это способ программирования графического процессора, который дает вам возможность писать любой код графического процессора, который вы хотите. Но существует огромная разница между наивным кодом CUDA (часто более медленным, чем процессор) и экспертным, рассчитанным по времени, оптимизированным вручную кодом CUDA. ArrayFire (и некоторые другие библиотеки графических процессоров, такие как CUBLAS) имеют много человеко-лет оптимизации и обычно дают лучшие результаты, чем большинство нормальных людей успеет достичь самостоятельно. Однако есть также различия в том, насколько хорошо кто-то использует ArrayFire (или другие библиотеки). Есть переменные, которые можно и нужно настраивать при использовании вызовов библиотеки ArrayFire, чтобы добиться максимальной производительности. Если вы разместите свой код, мы поможем поделиться некоторыми из них здесь.

В-третьих, ArrayFire использует CUBLAS в функциях, которые полагаются на BLAS, поэтому вы вряд ли заметите большую разницу, используя CUBLAS напрямую.

В-четвертых, да, ArrayFire использует все оптимизации, доступные в Руководстве по программированию NVIDIA CUDA (например, более быстрая передача данных и уменьшение конфликтов банков памяти, как вы упомянули). Именно здесь основная часть разработки ArrayFire сосредоточена на оптимизации подобных вещей.

Наконец, обнаруженные вами расхождения в данных, вероятно, связаны с особенностями вычислений CPU и GPU. Поскольку это разные устройства, вы часто будете видеть несколько разные результаты. Дело не в том, что ЦП дает лучшие результаты, чем ГП, а в том, что они оба работают с конечной точностью немного по-разному. Если вы используете одинарную точность вместо двойной, вы можете подумать об этом. Почтовый индекс также поможет нам в этом.

Рад расширить свой ответ после публикации кода.

person arrayfire    schedule 29.09.2012
comment
Разве они не соответствуют спецификациям IEEE? Я предполагаю, что использование «Single Precision» для обоих должно дать одинаковый результат. Опять же, предполагая, что порядок вычислений такой же. - person Royi; 17.05.2014