Почему sklearn быстрее на процессоре, чем Theano на GPU?

Я сравнил время обработки с theano (CPU), theano (GPU) и Scikit-learn (CPU) с использованием Python. Но я получил странный результат. Вот посмотрите на график, который я рисую.

Сравнение времени обработки:

Сравнение времени обработки

вы можете увидеть результат scikit-learn, который быстрее, чем theano (GPU). Программа, прошедшее время которой я проверил, состоит в том, чтобы вычислить евклидову матрицу расстояний из матрицы, состоящей из n * 40 элементов.

Вот часть кода.

points = T.fmatrix("points")
edm = T.zeros_like(points)

def get_point_to_points_euclidean_distances(point_id):
    euclideans = (T.sqrt((T.sqr(points- points[point_id, : ])).sum(axis=1)))

    return euclideans

def get_EDM_CPU(points):
    EDM = np.zeros((points.shape[0], points.shape[0])).astype(np.float32)
    for row in range(points.shape[0]):
        EDM[row, :] = np.sqrt(np.sum((points - points[row, :])**2, axis=1))

    return EDM

def get_sk(points):
    EDM = sk.pairwise_distances(a, metric='l2')

    return EDM

seq = T.arange(T.shape(points)[0])
(result, _) = theano.scan(fn = get_point_to_points_euclidean_distances, \
outputs_info = None , \
sequences = seq)

get_EDM_GPU = theano.function(inputs = [points], outputs = result, allow_input_downcast = True)

Я думал, что причина, по которой GPU работает медленнее, чем обучение с помощью научного набора, вероятно, заключается во времени передачи. Поэтому я профилировал GPU с помощью команды nvprof. тогда я получил это.

==27105== NVPROF is profiling process 27105, command: python ./EDM_test.py
Using gpu device 0: GeForce GTX 580 (CNMeM is disabled, cuDNN not available)
data shape :  (10000, 40)
get_EDM_GPU elapsed time :  1.84863090515 (s)
get_EDM_CPU elapsed time :  8.09937691689 (s)
get_EDM_sk elapsed time :  1.10968112946 (s)
ratio :  4.38128395145
==27105== Profiling application: python ./EDM_test.py
==27105== Warning: Found 9 invalid records in the result.
==27105== Warning: This could be because device ran out of memory when profiling.
==27105== Profiling result:
Time(%)      Time     Calls       Avg       Min       Max  Name
 71.34%  1.28028s      9998  128.05us  127.65us  128.78us  kernel_reduce_01_node_316e2e1cbfbe8cfb8e4a101f329ffeec_0(int, int, float const *, int, int, float*, int)
 19.95%  357.97ms      9997  35.807us  35.068us  36.948us  kernel_Sub_node_bc41b3f8f12c93d29f2c4360ad445d80_0_2(unsigned int, int, int, float const *, int, int, float const *, int, int, float*, int, int)
  7.32%  131.38ms         2  65.690ms  1.2480us  131.38ms  [CUDA memcpy DtoH]
  1.25%  22.456ms      9996  2.2460us  2.1140us  2.8420us  kernel_Sqrt_node_23508f8f49d12f3e8369d543f5620c15_0_Ccontiguous(unsigned int, float const *, float*)
  0.12%  2.1847ms         1  2.1847ms  2.1847ms  2.1847ms  [CUDA memset]
  0.01%  259.73us         5  51.946us     640ns  250.36us  [CUDA memcpy HtoD]
  0.00%  17.086us         1  17.086us  17.086us  17.086us  kernel_reduce_ccontig_node_97496c4d3cf9a06dc4082cc141f918d2_0(unsigned int, float const *, float*)
  0.00%  2.0090us         1  2.0090us  2.0090us  2.0090us  void copy_kernel<float, int=0>(cublasCopyParams<float>)

Перенос [CUDA memcpy DtoH] был выполнен дважды { 1.248 [us], 131.38 [ms] }

Перенос [CUDA memcpy HtoD] выполнен 5x { min: 640 [ns], max: 250.36 [us] }

Время передачи составляет около 131,639 мс (131,88 мс + 259,73 мкс). но разрыв между GPU и scikit-learn составляет около 700 мс (1,8–1,1 с). Таким образом, разрыв составляет время передачи.

вычисляет ли он только верхнюю треугольную матрицу из симметричной матрицы?

что делает scikit-learn таким быстрым?


person Holden    schedule 05.09.2017    source источник
comment
Что такое CPU и GPU на первом графике?   -  person Worthy7    schedule 05.09.2017
comment
@ Worthy7 CPU означает, что он вычисляет евклидову матрицу расстояний с помощью оператора for-loop, а GPU означает, что он вычисляет матрицу с помощью библиотеки theano с GPU.   -  person Holden    schedule 05.09.2017
comment
Нет, но ЦП — это аппаратное обеспечение, а SKLEARN — это фреймворк Python. Вы не можете просто поместить эти два на график. В любом случае, я думаю, вы просто имеете в виду использование чистого python вместо правильного использования sklearn. sklearn оптимизирован внутри — это так просто. Пожалуйста, попробуйте гораздо больший набор данных :) Скажем, в 100 раз больше.   -  person Worthy7    schedule 06.09.2017
comment
@ Worthy7 Theano имеет серверную часть как ЦП, так и ГП. Он говорит об использовании этого.   -  person Kh40tiK    schedule 12.09.2017
comment
Справедливо. Большой тест!   -  person Worthy7    schedule 12.09.2017


Ответы (1)


Что делает scikit-learn (на чистом процессоре) таким быстрым?

Мои первоначальные кандидаты будут представлять собой смесь:

  • высокоэффективное использование доступных процессорных ядер размеров L1-/L2 на самых быстрых расстояниях [ns]
  • интеллектуальное numpy векторное выполнение, дружественное к кэш-строкам ЦП
  • набор данных настолько небольшой, что он может полностью остаться неисключенным из кэша (протестируйте, чтобы масштабировать анализируемый набор данных намного выше размеров кэша L2-/L3, чтобы увидеть влияние затрат памяти DDRx на наблюдаемая производительность (подробности в URL-адресе ниже))
  • numpy может оказаться еще лучше, если вы избегаете .astype() конверсий (проверьте)

Факты о GPU

  • у автоматически сгенерированных ядер GPU не так много шансов получить максимальные уровни глобальной маскировки задержки памяти по сравнению с ядрами, настроенными вручную, адаптированными к соответствующей кремниевой архитектуре GPU / задержкам, наблюдаемым в естественных условиях.
  • структуры данных, размер которых превышает несколько КБ, по-прежнему оплачивают расстояния GPU-SM/GDDR-MEM ~ большие сотни [нс], почти [нас] -v/s- по сравнению с небольшими единицами ~ небольшие десятки [нс] на ЦП /L1/L2/L3/DDRx ) исх. подробности о времени в >>> https://stackoverflow.com/a/33065382
  • неспособность использовать большую часть мощности GPU/SMX из-за очевидного низкого повторного использования точек данных в этой задаче и размера набора данных, превышающего ограничения GPU/SM-silicon, что вызывает и должно вызывать переливы емкости GPU/SM-регистра в любом вид попыток проектирования и настройки ядра графического процессора
  • глобальная задача состоит в том, чтобы не иметь минимального разумного количества асинхронных, изолированных (не сообщающихся островков) математически плотных, но SMX-локальных шагов обработки GPU-ядра (не так много нужно вычислять, чтобы приспособиться к надстройке накладные расходы и высокая стоимость памяти SMX/GDDR)

Графические процессоры могут прекрасно демонстрировать свою лучшую производительность, если выполняются достаточно плотно запутанные операции повторной обработки - как при крупномасштабной обработке изображений с высоким разрешением - на матрицах ядра [m,n,o] свертки, настолько маленьких, что так как все эти m*n*o постоянные значения могут находиться локально для SM, внутри доступного набора SMX-SM_registers, и если средства запуска ядра GPU оптимально настроены геометрией макета обработки 3D-tblock/grid, так что глобальный доступ к памяти задержки максимально маскируются, поскольку все потоки графического процессора принудительно реализованы в аппаратных средствах планирования потоков SMx:WarpScheduler RoundRobin с выравниванием по WARP (первый переход из режима Round-Robin в режим Greedy-WarpSchedule проигрывает всю битву в случае расходящиеся пути выполнения в коде ядра GPU).

person user3666197    schedule 05.09.2017