我一直试图通过PyOpenCl使用OpenCl加速实现Mandelbrot集。我现在有一些奇怪的性能问题英特尔OpenCl与AMD应用程序。 我在一台搭载英特尔酷睿i7-4600U的惠普精英电子书840g1上使用了ubuntu14.10
主要部分是计算网格(图像)上给定点的迭代次数的函数是:
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应用程序,platforms[1]
是Intel OpenCl,该设备两次都是核心i7。code
将是用openclc编写的内核
使用AMD应用程序上的酷睿i7,对于1024x1024像素的图像,这个函数的时钟大约为0.075秒,迭代深度为200。使用Intel OpenCl的时间大约为0.25秒,这是出乎意料的,因为Intel OpenCl通常在核心i7上表现更好。在
现在我有一种奇怪的行为。如果我通过更改函数Mandelbrot
中的任何内容(例如任何语法、参数),让程序以错误结束,在IPython控制台中运行并获得错误消息,更正错误并再次运行,那么在Intel OpenCl上的性能将提高到0.045s(系数为5-6)。在这之后,性能总是比AMD应用程序好,直到我重新启动IPython控制台。如果我在命令行中使用python3 file.py
运行该程序,则性能会很差。只有我让它在同一个IPython控制台中运行,首先以任何错误结束,然后是正确的错误。。。在
我真的不知道是什么引起了这样一个奇怪的错误。很可能是英特尔OpenCl运行时出错了,但我不知道从哪里开始查找。。。在
非常感谢
您正在为所有初始化例程计时,这些例程包括创建OpenCL上下文、分配内存、在主机和设备之间复制内存(即使在本例中它们是相同的,仍然存在memcpy)和编译程序。在
所有这些都将极大地影响您所观察到的运行时。特别是,编译程序是昂贵的,不同的供应商(Intel,AMD)将执行不同的程序转换和优化过程。这可能是你的第一个差异来自哪里(AMD似乎比英特尔快得多)。在
您所观察到的奇怪行为可能是由于这样一个事实,即某些初始化例程在被您的诱导错误中断之前正在执行。第二次从同一个解释器运行代码时,这些例程可能不需要再次运行(编译的程序可能被缓存,内存分配仍然存在,线程没有被破坏等等),因此导致第二次运行的速度要快得多。在
您可以通过分割代码来验证这一切,将OpenCL的初始化和实际计算分开。如果您这样做,您可能会看到更加一致的结果(对于计算)。在
当我想对OpenCL计算进行基准测试时,我通常会用以下结构编写一个程序:
(尽管取决于您的用例,您可能希望在计时中包含数据传输)。在
相关问题 更多 >
编程相关推荐