Увеличение функции расстояния до внутренней петли с помощью чашки - PullRequest
0 голосов
/ 14 мая 2018

Я пытаюсь увеличить скорость вычисления заданной функции расстояния - c (x, y) во время итерации массива внутреннего цикла.Я пытался использовать Cupy и бенчмарк со случайными значениями.Пока у меня есть следующий код:

import time
import contextlib
import cupy as cp
import numpy as np

squared_diff = cp.ElementwiseKernel(
    'float64 x, float64 y',
    'float64 z',
    'z = (x - y) * (x - y)',
    'squared_diff')

 x, y = np.random.randn(1000), np.random.randn(1000)
 x_gpu, y_gpu = cp.random.randn(1000), cp.random.randn(1000)

 c = np.zeros((len(x), len(y)))
 c_gpu = cp.zeros((len(x), len(y)))


 @contextlib.contextmanager
 def timer(message):
     cp.cuda.Stream.null.synchronize()
     start = time.time()
     yield
     cp.cuda.Stream.null.synchronize()
     end = time.time()
     print('%s:  %f sec' % (message, end - start))


with timer(' CPU '):
     for i in range(len(x)):
        for j in range(len(y)):
            c[i, j] = (x[i] - y[i]) ** 2

with timer(' GPU '):
     for i in range(len(x)):
         for j in range(len(y)):
            c_gpu[i, j] = squared_diff(x_gpu[i], y_gpu[j])

Однако, кажется, что время GPU значительно выше по сравнению с процессором.

CPU :  0.486763 sec
GPU :  26.627597 sec

Есть ли какой-нибудь существенный намек или проблема, которую я имеюотсутствует при рассмотрении теории увеличения скорости вычислений с помощью CUDA?

1 Ответ

0 голосов
/ 17 мая 2018

Вам нужно транслировать входные массивы для поэлементного вычисления.

def bcast(x, y, xp):
    return (xp.broadcast_to(x[:, None], (1000, 1000)),
            xp.broadcast_to(y, (1000, 1000)))

x, y = bcast(x, y, np)
with timer(' CPU '):
    c = (x - y) ** 2

x_gpu, y_gpu = bcast(x_gpu, y_gpu, cp)
with timer(' GPU '):
    c_gpu2 = squared_diff(x_gpu, y_gpu)
...