2014-05-21 29 views
5

Czy mamy przyspieszone GPU wersji numpy.max(X, axis=None) w Theano. Zajrzałem do dokumentacji i znalazłem theano.tensor.max(X, axis=None), ale jest to 4-5 razy wolniej niż implementacja numpy.Czy w Theano jest implementacja przyspieszania GPU w wersji numpy.max (X, axis = 0)?

Mogę was zapewnić, że nie jest wolny z powodu złego wyboru rozmiaru matrycy. Ta sama matryca pod theano.tensor.exp jest 40 razy szybsza niż jego numpy odpowiednik.

Wszelkie sugestie?

Odpowiedz

5

Poprzednia odpowiedź jest częściowa. Ta sugestia nie powinna działać, ponieważ praca jest używana w ostatecznym skompilowanym kodzie. Istnieje optymalizacja, która automatycznie wykona tę transformację.

Tytuł pytania nie jest taki sam jak treść. Różnią się one od argumentu osi. Odpowiem na oba pytania.

Jeśli oś jest równa 0 lub Brak, obsługujemy to w GPU dla tej operacji dla macierzy. Jeśli oś jest Brak, mamy podstawową implementację, która nie jest dobrze zoptymalizowana, ponieważ trudniej jest zrównoleglić. Jeśli oś wynosi 0, mamy podstawową implementację, ale jest ona szybsza, ponieważ łatwiej jest zrównoleglić.

Ponadto, w jaki sposób wykonałeś swój pomiar czasu? Jeśli po prostu wykonasz jedną funkcję tylko z tą operacją i przetestujesz ją za pomocą flag urządzenia = gpu, aby wykonać porównanie, będzie to czas transferu pomiędzy procesorem a GPU. Jest to operacja związana z pamięcią, więc jeśli uwzględnisz transfer w ustawianiu czasowym, personalna, nie oczekuję żadnego oporu prędkości dla tej sprawy. Aby zobaczyć tylko operację GPU, użyj profilera Theano: uruchom z flagą Theano = True.

+0

Tak, miałem na czasie całą kopię + obliczenia. Będę próbował profilera Theano. Chcę przyspieszyć operację max (X, axis = 0), w tym koszty ogólne kopiowania. Wydaje mi się, że nie mogę tego uzyskać dla dowolnych rozmiarów matrycy. Co sugerujesz? – hrs

+2

Jak próbowałem powiedzieć w odpowiedzi, nie sądzę, że będziesz w stanie uzyskać przyspieszenie do maksymalnej redukcji jeśli uwzględnisz czas transferu z dowolnym systemem, nie tylko Theano. Aby zredukować procesor, wąskim gardłem jest odczyt z pamięci.Przeniesienie na GPU odbywa się wolniej, niż odczyt z pamięci CPU przez rdzenie procesora. Jeśli chcesz przyspieszyć procesor graficzny, który obejmuje transfer, potrzebujesz więcej obliczeń do wykonania na GPU. – nouiz

3

Operacje max i exp są zasadniczo różne; exp (i inne operacje, takie jak dodawanie, sin, itp.) Jest operacją elementarną, która jest zawstydzająco równoległa, podczas gdy max wymaga algorytmu skanowania równoległego, który zasadniczo buduje drzewo porównań parami w tablicy. Przyspieszenie max nie jest niemożliwe, ale nie jest tak łatwe jak exp.

Zresztą realizacja theano z max w zasadzie składa się z następujących linii (w Theano/tensora/basic.py):

try: 
    out = max_and_argmax(x, axis)[0] 
except Exception: 
    out = CAReduce(scal.maximum, axis)(x) 

gdzie max_and_argmax jest kilka kodu niestandardowego, że do mojego oka, narzędzia operacja max + argmax przy użyciu numpy i CAReduce to standardowa akcelerowana przez GPU operacja skanowania używana jako rezerwowa (która, zgodnie z komentarzami, nie obsługuje grad itp.). Możesz spróbować użyć kreacji zastępczej bezpośrednio i sprawdzić, czy jest to szybsze, może coś takiego:

from theano.tensor.elemwise import CAReduce 
from theano.scalar import maximum 

def mymax(X, axis=None): 
    CAReduce(maximum, axis)(X) 
+0

To się nie poprawiło, przynajmniej wydajność jest teraz równa wydajności procesora. Próbowałem różnych rozmiarów matrycy, żeby się upewnić. – hrs

+0

Edycja: nadal jest 4 razy wolniejsza dla moich większych macierzy. – hrs

+2

Nie jest zaskoczeniem, że znalezienie maksimum jest związane z pamięcią. – tillsten