Почему часть кода моего графического процессора работает намного медленнее, чем процессор

Это один из стандартных примеров кода, который мы находим повсюду...

import time
import numpy

import pycuda.gpuarray as gpuarray
import pycuda.cumath as cumath
import pycuda.autoinit

size = 1e7

t0 = time.time()
x = numpy.linspace(1, size, size).astype(numpy.float32)
y = numpy.sin(x)
t1 = time.time()

cpuTime = t1-t0
print(cpuTime)

t0 = time.time()
x_gpu = gpuarray.to_gpu(x)
y_gpu = cumath.sin(x_gpu)
y = y_gpu.get()
t1 = time.time()

gpuTime = t1-t0
print(gpuTime)

результаты: 200 мс для процессора и 2,45 с для графического процессора ... более чем в 10 раз.

У меня Win 10... vs 2015 с PTVS...

С наилучшими пожеланиями...

Стеф


person stedes_dev    schedule 22.06.2016    source источник
comment
Для начала вам, вероятно, следует использовать timeit для точного определения среднего времени выполнения кода. Во-вторых, возможно, что в вызове gpuarray.to_gpu(x) есть много накладных расходов. Попробуйте выполнить эту настройку вне вашей временной функции. Наконец, имейте в виду, что numpy очень оптимизирован для таких операций. Таким образом, вполне разумно видеть более низкую производительность на графическом процессоре в некоторых случаях, в том числе без оптимизации кода графического процессора.   -  person Andrew Guy    schedule 22.06.2016
comment
Я запустил приведенный выше код, используя модуль timeit. Я получаю 20,6 мс на цикл (100 циклов) для кода GPU и 129 мс на цикл для кода процессора numpy. ГП=GTX760, ЦП=i5-2400. Интересно, что код GPU работает медленнее при первом запуске в интерактивной подсказке Python (400 мс), но быстрее (20 мс) при повторных запусках в одном и том же экземпляре.   -  person Andrew Guy    schedule 22.06.2016
comment
Спасибо... да, я вижу то же самое... довольно накладные расходы... для первого прохода...   -  person stedes_dev    schedule 28.06.2016


Ответы (1)


Похоже, что pycuda вводит некоторые дополнительные накладные расходы при первом вызове функции cumath.sin() (~ 400 мс в моей системе). Я подозреваю, что это связано с необходимостью компилировать код CUDA для вызываемой функции. Что еще более важно, эти накладные расходы не зависят от размера массива, передаваемого в функцию. Дополнительные вызовы cumath.sin() выполняются намного быстрее, поскольку код CUDA уже скомпилирован для использования. В моей системе код GPU, указанный в вопросе, выполняется примерно за 20 мс (при повторных запусках) по сравнению с примерно 130 мс для кода numpy.

Я не утверждаю, что знаю много о внутренней работе pycuda, поэтому было бы интересно услышать мнение других людей по этому поводу.

person Andrew Guy    schedule 22.06.2016
comment
Большое спасибо за ваш ответ ... Да, похоже, у него много накладных расходов ... - person stedes_dev; 28.06.2016