2014-10-25 2 views
2

За последние пару дней я пытался понять, почему Numbapro (ускорение от Continuum Analytics, Inc., Я запускаю пробную версию 30 дней) не ускоряется на моем MacBook Pro (Intel Core i7, 2,6 ГГц, 16 ГБ оперативной памяти с NVIDIA GeForce GT 650M, 1 ГБ на шине PCI).Numbapro: Нет ускорения для умножения матрицы

Я взял один из примеров из кодов для умножения матриц (NxM) x (MxN), где Continuum Analytics, Inc. утверждает ускорение вычислений через CUDA, и я сравнивал время между CUDA.JIT и numpy. Моя идея - запустить, например, 1e4 итерации, а матрица B - на каждой итерации. Ниже следующего кода, который я использовал, я цитирую время, которое я получил. Есть ли для этого решение? Благодаря!

from numbapro import * 
from numba import * 
import numpy as np 
import math 
from timeit import default_timer as timer 

m=1000 
n=1000 
A = np.array(np.random.random((n,m)), dtype=np.float32) 
C = np.empty([n,n]) 

iterations = 10000 

start = timer() 
for i in range(iterations): 
    B = np.array(np.random.random((m,n)), dtype=np.float32) 
    X=np.dot(A,B) 
numpy_time=(timer() - start) 

@cuda.jit(void(float32[:,:],float32[:,:],float32[:,:])) 
def cu_square_matrix_mul(A, B, C): 

    tx = cuda.threadIdx.x 
    ty = cuda.threadIdx.y 
    bx = cuda.blockIdx.x 
    by = cuda.blockIdx.y 
    bw = cuda.blockDim.x 
    bh = cuda.blockDim.y 
    x = tx + bx * bw 
    y = ty + by * bh 
    n = C.shape[0] 

    if x >= n or y >= n: 
     return 

    cs = 0 
    for i in range(n): 
     cs += A[y,i]*B[i,x] 
    C[y,x]= cs 

    cuda.syncthreads() 

blockdim = 256,3 
griddim = 10,3 

stream = cuda.stream() 
dA = cuda.to_device(A, stream) 
dC = cuda.to_device(C, stream) 

start = timer()  
for i in range(iterations): 
    B = np.array(np.random.random((m,n)), dtype=np.float32) 
    dB = cuda.to_device(B, stream) 
    cu_square_matrix_mul[griddim,blockdim,stream](dA, dB, dC) 
    dC.to_host() 
    stream.synchronize() 
cuda_time = (timer() - start)  

print 
print("Numpy took %f seconds" % numpy_time) 
print("CUDA JIT took %f seconds, %.5fx speedup" % (cuda_time, numpy_time/cuda_time)) 

результаты в:

Vendor: Continuum Analytics, Inc. 
Package: mkl 
Message: trial mode expires in 30 days 
Vendor: Continuum Analytics, Inc. 
Package: mkl 
Message: trial mode expires in 30 days 
Vendor: Continuum Analytics, Inc. 
Package: numbapro 
Message: trial mode expires in 30 days 

Numpy took 378.328881 seconds 
CUDA JIT took 342.723757 seconds, 1.10389x speedup 
+0

Сколько общего времени потрачено на (1) генерацию случайных матриц B [] (2) передачу данных между CPU-> GPU-> CPU? Я не знаком с 'numpy', но вызов' stream.synchronize() 'предполагает, что код активно блокирует перекрытие между работой графического процессора и ЦП и перекрывается между копиями данных с/на графический процессор и выполнение ядра, т.е. все выполняется полностью синхронно. – njuffa

+0

Импортированные имена из 'from numbapro import *' перезаписываются следующим импортом 'from numba import *'. Это предназначено? – sebix

ответ

3

Это совершенно наивным умножения матриц рутина на GPU, в то время как Numpy рутина, будучи фактически библиотека вызова:

X=np.dot(A,B) 

, скорее всего, быть высоко оптимизированным. Я впечатлен тем, что GPU работает быстрее.

«Решение» будет состоять из make a call to CUBLAS для матричного умножения, а не для написания собственного ядра.

Смежные вопросы