Начало работы с CUDA в Нумбе - PullRequest
0 голосов
/ 20 июня 2019

Я пытаюсь изучить основы CUDA в Нумбе с помощью этого урока. https://github.com/harrism/numba_examples/blob/master/mandelbrot_numba.ipynb

Ожидаемое поведение заключается в том, что для версии без JIT и CUDA требуется много времени, для JIT-версии - намного короче, а для CUDA - еще меньше.

Он работает, переходя от обычной версии к JIT, но затем, версия CUDA в среднем вдвое дольше, чем версия JIT. Я использую ноутбук с NVidia Geforce GTX 950M. Я хотел бы знать, происходит ли проблема из-за того, что мой графический процессор недостаточно мощный или потому, что моя программа написана неправильно.

Вот мои версии:

Нет: https://pastebin.com/hczvLC8F

import numpy as np
from pylab import imshow, show
from timeit import default_timer as timer

def mandel(x, y, max_iters):
  c = complex(x, y)
  z = 0.0j
  for i in range(max_iters):
    z = z*z + c
    if (z.real*z.real + z.imag*z.imag) >= 4:
      return i

  return max_iters

def create_fractal(min_x, max_x, min_y, max_y, image, iters):
  height = image.shape[0]
  width = image.shape[1]

  pixel_size_x = (max_x - min_x) / width
  pixel_size_y = (max_y - min_y) / height

  for x in range(width):
    real = min_x + x * pixel_size_x
    for y in range(height):
      imag = min_y + y * pixel_size_y
      color = mandel(real, imag, iters)
      image[y, x] = color

image = np.zeros((1024, 1536), dtype = np.uint8)
start = timer()
create_fractal(-2.0, 1.0, -1.0, 1.0, image, 20) 
dt = timer() - start

print("Mandelbrot created in {} s".format(dt))
imshow(image)
show()

JIT: https://pastebin.com/NStX7MVi

@jit
def mandel(x, y, max_iters):

@jit
def create_fractal(min_x, max_x, min_y, max_y, image, iters):

CUDA: https://pastebin.com/4V3BgdAv

mandel_gpu = cuda.jit(device=True)(mandel)

@cuda.jit
def mandel_kernel(min_x, max_x, min_y, max_y, image, iters):
  height = image.shape[0]
  width = image.shape[1]

  pixel_size_x = (max_x - min_x) / width
  pixel_size_y = (max_y - min_y) / height

  startX, startY = cuda.grid(2)
  gridX = cuda.gridDim.x * cuda.blockDim.x
  gridY = cuda.gridDim.y * cuda.blockDim.y

  for x in range(startX, width, gridX):
    real = min_x + x * pixel_size_x
    for y in range(startY, height, gridY):
      imag = min_y + y * pixel_size_y
      image[y, x] = mandel_gpu(real, imag, iters)

gimage = np.zeros((1024, 1536), dtype = np.uint8)
blockdim = (32, 8)
griddim = (32,16)

start = timer()
d_image = cuda.to_device(gimage)
mandel_kernel[griddim, blockdim](-2.0, 1.0, -1.0, 1.0, d_image, 20)
d_image.to_host()
dt = timer() - start

Я ожидал, что версия CUDA будет еще быстрее, чем версия JIT, но на самом деле это занимает вдвое больше времени.

Я запускал их несколько раз, и вот результаты на моем ноутбуке:

None: 6.24s on average
JIT: 0.42s on average
CUDA: 0.86s on average
...