2015-03-19 3 views
0

Я пытался ускорить реализацию Mandrellbrot с использованием OpenCl через PyOpenCl. У меня теперь есть некоторые странные проблемы с производительностью с Intel OpenCl по сравнению с AMD APP. Я использую Ubuntu 14.10 на HP Elitebook 840 G1 с Intel Core i7-4600U.Увеличение производительности после ошибки в PyOpenCl с Intel OpenCl

Основная часть является функцией для вычисления числа итераций для данной точки на сетке (изображение) является:

platforms = cl.get_platforms() 
devs = platforms[1].get_devices(device_type=cl.device_type.CPU) 

def Mandelbrot(xmin, xmax, ymin, ymax, xsize, ysize, maxit, col, image): 
    ctx = cl.Context(devices = devs) 
    queue = cl.CommandQueue(ctx) 

    mf = cl.mem_flags 
    output_opencl = cl.Buffer(ctx, mf.WRITE_ONLY, image.nbytes) 

    dx = (xmax - xmin)/xsize 
    dy = (ymax - ymin)/ysize 

    prg = cl.Program(ctx,code).build() 

    prg.mandelbrot(queue, (xsize, ysize), None, np.float64(xmin), np.float64(ymax), 
       np.float64(dx), np.float64(dy), np.uint16(maxit), np.uint16(col), output_opencl) 

    cl.enqueue_copy(queue, image, output_opencl).wait() 

Здесь platforms[0] бы быть AMD APP и platforms[1] является Intel OpenCL, устройство является Core i7 оба раза. code будет ядром, написанным в OpenCl C.

Использование Core i7 на AMD APP Эта функция работает с частотой около 0,075 для изображения с разрешением 1024x1024 с глубиной итерации 200. Использование Intel OpenCl составляет около 0,25 с , что неожиданно, так как Intel OpenCl обычно лучше работает с Core i7.

Теперь я получаю странное поведение. Если я позволю программе завершить ошибку, изменив что-нибудь в функции Mandelbrot (например, любой синтаксис, аргументы), запустите ее в консоли IPython и получите сообщение об ошибке, исправьте ошибку и запустите ее снова, а затем производительность на Intel OpenCl увеличивается до 0,045 с (коэффициент 5-6). После этого производительность всегда лучше, чем с AMD APP, пока я не перезапущу консоль IPython. Если я запускаю программу в командной строке, используя python3 file.py, производительность плоха. Он работает только в том случае, если я позволяю ему запускаться в той же самой консоли IPython, сначала заканчивая какой-либо ошибкой, а затем правильный ...

Я действительно не знаю, что может вызвать такую ​​странную ошибку. Скорее всего, какая-то ошибка с исполняющей Intel OpenCL, хотя я не знаю, где начать смотреть ...

Большое спасибо

+0

Какой у вас выбор времени? Это целая функция Мандельброта или просто вычисление? – jprice

+0

Вся функция «Мандельброт», которая включает в себя создание контекста и всего и фактическое вычисление. – somebody

ответ

0

Вы синхронизации всех инициализации процедур, которые включают в себя создание контекста OpenCL , выделение памяти, копирование памяти на хост и на устройство (с учетом того, что в этом случае это одно и то же, все еще есть memcpy) и компиляция программы.

Все это существенно повлияет на время работы, которое вы наблюдаете. В частности, компиляция программ стоит дорого, а разные поставщики (Intel, AMD) будут выполнять различные программные преобразования и проходы оптимизации. Скорее всего, ваше первое несоответствие происходит (AMD выглядит намного быстрее, чем Intel).

Странное поведение, которое вы наблюдаете, вероятно, связано с тем, что некоторые из этих процедур инициализации выполняются до прерывания вашей индуцированной ошибки. Во второй раз, когда вы запускаете код из одного и того же интерпретатора, эти процедуры могут не понадобиться снова запускать (скомпилированные программы могут быть кэшированы, сохраняются выделения памяти, потоки не уничтожены и т. Д.), Что приводит к значительно более быстрому второму запуску.

Вы можете проверить все это, разделив код, чтобы разделить инициализацию OpenCL и фактическое вычисление. Если вы это сделаете, вы, скорее всего, увидите гораздо более последовательные результаты (для вычисления).

Когда я хочу бенчмарка вычислений OpenCL, я обычно пишу программу с этой структурой:

# Initialise OpenCL context, program, buffers etc 

# Copy memory to device 

# Run kernel once to 'warm-up' 

# Start timing 
# Run kernel several times in a loop 
# Stop timing 

# Read results back and verify 

# De-initialise OpenCL 

(Хотя в зависимости от вашего потребительной случае, вы можете включить переноса данных в сроках) ,

+0

Спасибо за ваш ответ, уже много помогли. Теперь я сделал несколько измерений времени. Расчет только и передача памяти ожидаются, что замедляет работу программы, создает контекст, который кажется. Строка 'ctx = cl.Context (devices = devs)' занимает до 0.2 секунд на Intel OpenCl, тогда как на AMD APP нет времени (10^-5 с). Как только я позволяю ему работать с ошибкой на одном и том же интерпретаторе, время также уменьшается до 10^-5 ... Обратите внимание, что если я просто позволю программе работать несколько раз, время не изменится. Только когда я позволяю ему работать с ошибкой, поведение меняется. – somebody

+0

Итак: создание контекста на Intel OpenCL занимает довольно много времени по сравнению с AMD APP (0.2s против 10^-5s). Я не знаю, почему это происходит и ничего не нашел в Интернете. После любой ошибки при компиляции кода OpenCl C в том же интерпретаторе поведение изменяется и создается контекст на Intel OpenCl работает быстро, как ожидалось. Только решение, которое я нашел, чтобы обойти проблему, создает контекст вне функции. Затем каждый раз, когда я вызываю функцию, она должна выполнять вычисления, которые не требуют времени. Но о том, почему для создания контекста требуется много времени, я до сих пор не знаю .. – somebody

+0

@somebody Это может быть много вещей - мы просто не знаем (например, создание и закрепление рабочих потоков, резервирование областей памяти, настройка внутренних данных структуры, загрузка вспомогательных библиотек и т. д.). Это не имеет значения - вам нужно только создать контекст один раз, а затем повторно использовать его во всей вашей программе. – jprice

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

  • Нет связанных вопросов^_^