Медленное сравнение GPU в Cupy
Я хочу с помощью cupy проверить, является ли число с плавающей точкой положительным, например:
import cupy as cp
u = cp.array(1.3)
u < 2.
>>> array(True)
Моя проблема в том, что эта операция очень медленная:%timeit u < 2.
дает 26 микросекунд на моем компьютере. Это на несколько порядков больше, чем то, что я получаю в процессоре. Я подозреваю, что это потому, что вы должны быть наложены на процессор...
Я пытаюсь найти более быстрый способ сделать эту операцию.
Спасибо!
Изменить для уточнения
Мой код что-то вроде:
import cupy as cp
n = 100000
X = cp.random.randn(n) # can be greater
for _ in range(100): # There may be more iterations
result = X.dot(X)
if result < 1.2:
break
И кажется узким местом этого кода (для этого n
) это оценка result < 1.2
, Это все еще намного быстрее, чем на процессоре, так как dot
стоит намного меньше.
2 ответа
Выполнение одной операции на GPU - это всегда плохая идея. Чтобы получить прирост производительности от вашего графического процессора, вам необходимо реализовать хорошую "интенсивность вычислений"; то есть количество вычислений, выполненных относительно движения памяти; либо из глобального ram в gpu mem, либо из gpu mem в сами ядра. Если у вас нет по крайней мере нескольких провальных флопов на байт интенсивности вычислений, вы можете спокойно забыть о любом ускорении графического процессора. Тем не менее, ваша проблема может привести к ускорению графического процессора, но вы, конечно, не можете сравнивать подобные заявления изолированно каким-либо значимым образом.
Но даже если ваш алгоритм состоит из объединения ряда таких простых операций с низкой интенсивностью вычислений в графическом процессоре, вы все равно будете разочарованы ускорением. Ваше узкое место будет пропускной способностью памяти GPU; что на самом деле не так уж и много по сравнению с пропускной способностью памяти процессора, как может показаться на бумаге. Если вы не будете писать свои собственные вычислительные ядра или не планируете запускать большие fft или что-то подобное с использованием cupy, не думайте, что это даст вам ускорение с помощью "серебряной пули", просто перенеся ваш тупой код.
Я думаю, проблема здесь в том, что вы просто используете одно устройство с графическим процессором. Подумайте об использовании, скажем, 100, чтобы выполнить все вычисления параллельно (хотя в случае вашего простого примера кода это потребуется сделать только один раз). https://docs-cupy.chainer.org/en/stable/tutorial/basic.html
Также есть большая функция, которую вы можете использовать для сравнения в графическом процессоре.
Кроме того, при первом вызове точки функция ядра должна быть скомпилирована для графического процессора, что займет значительно больше времени, чем последующие вызовы.
Это может быть связано с тем, что при использовании CUDA массив должен быть скопирован в графический процессор перед обработкой. Поэтому, если ваш массив имеет только один элемент, он может быть медленнее в графическом процессоре, чем в процессоре. Вы должны попробовать больший массив и посмотреть, продолжает ли это происходить