使用Intel OpenC的PyOpenCl出错后性能提高

2024-04-29 02:15:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直试图通过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运行时出错了,但我不知道从哪里开始查找。。。在

非常感谢


Tags: 函数应用程序cl错误np性能openclplatforms
1条回答
网友
1楼 · 发布于 2024-04-29 02:15:36

您正在为所有初始化例程计时,这些例程包括创建OpenCL上下文、分配内存、在主机和设备之间复制内存(即使在本例中它们是相同的,仍然存在memcpy)和编译程序。在

所有这些都将极大地影响您所观察到的运行时。特别是,编译程序是昂贵的,不同的供应商(Intel,AMD)将执行不同的程序转换和优化过程。这可能是你的第一个差异来自哪里(AMD似乎比英特尔快得多)。在

您所观察到的奇怪行为可能是由于这样一个事实,即某些初始化例程在被您的诱导错误中断之前正在执行。第二次从同一个解释器运行代码时,这些例程可能不需要再次运行(编译的程序可能被缓存,内存分配仍然存在,线程没有被破坏等等),因此导致第二次运行的速度要快得多。在

您可以通过分割代码来验证这一切,将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

(尽管取决于您的用例,您可能希望在计时中包含数据传输)。在

相关问题 更多 >