Python 使用“英特尔OpenCl”在PyOpenCl中出错后性能提高

Python 使用“英特尔OpenCl”在PyOpenCl中出错后性能提高,python,performance,opencl,intel,pyopencl,Python,Performance,Opencl,Intel,Pyopencl,我一直在尝试通过PyOpenCl使用OpenCl加速我对Mandelbrot集的实现。与AMD应用程序相比,英特尔OpenCl现在有一些奇怪的性能问题。 我在HP Elitebook 840 G1上使用的是Ubuntu 14.10,带有Intel Core i7-4600U 主要部分是计算网格(图像)上给定点的迭代次数的函数: 这里的platforms[0]将是AMD应用程序,而platforms[1]是Intel OpenCl,这两款设备都是i7的核心代码将是用OpenCLC编写的内核 使用A

我一直在尝试通过PyOpenCl使用OpenCl加速我对Mandelbrot集的实现。与AMD应用程序相比,英特尔OpenCl现在有一些奇怪的性能问题。 我在HP Elitebook 840 G1上使用的是Ubuntu 14.10,带有Intel Core i7-4600U

主要部分是计算网格(图像)上给定点的迭代次数的函数:

这里的
platforms[0]
将是AMD应用程序,而
platforms[1]
是Intel OpenCl,这两款设备都是i7的核心<代码>代码将是用OpenCLC编写的内核

使用AMD应用程序上的Core i7,对于迭代深度为200的1024x1024像素图像,此函数的时钟约为0.075秒。使用英特尔OpenCl的时间约为0.25秒,这是出乎意料的,因为英特尔OpenCl通常在核心i7上表现更好

现在我有一种奇怪的行为。如果我通过更改函数
Mandelbrot
中的任何内容(例如,任何语法、参数)而让程序以错误结束,请在IPython控制台中运行此操作并获得错误消息,更正错误并再次运行,则英特尔OpenCl上的性能将提高到0.045s(系数5-6)。在此之后,性能总是比AMD应用程序好,直到我重新启动IPython控制台。如果我在命令行中使用
python3 file.py
运行该程序,性能会很差。只有当我让它在同一个IPython控制台中运行时,它才能工作,首先以任何错误结束,然后是正确的错误结束

我真的不知道是什么导致了这样一个奇怪的错误。很可能是英特尔OpenCl运行时出现了一些错误,尽管我不知道从哪里开始查找


非常感谢

您正在对所有初始化例程进行计时,包括创建OpenCL上下文、分配内存、将内存复制到设备上以及从主机复制到设备上(尽管在本例中它们是相同的,但仍然有一个memcpy),以及编译程序

所有这些都将极大地影响您观察到的运行时。特别是,编译程序非常昂贵,不同的供应商(英特尔、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

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

您在计时什么?是整个
Mandelbrot
函数,还是仅仅是计算?整个
Mandelbrot
函数,包括创建上下文和所有内容以及实际计算。感谢您的回答,已经帮了很多忙。我现在做了更多的时间测量。单独的计算和内存的传输正如预期的那样,减慢程序速度的是它似乎在创建上下文。在英特尔OpenCl上,ctx=cl.Context(devices=devs)一行占用的时间高达0.2秒,而在AMD应用程序上则没有时间(10^-5s)。一旦我让它在同一个解释器上出错,时间也会下降到10^-5。。。但是请注意,如果我只是让程序运行多次,时间不会改变。只有当我让它遇到错误时,行为才会改变。因此:与AMD应用程序相比,在英特尔OpenCL上创建上下文需要相当长的时间(0.2s vs 10^-5s)。我不知道为什么会这样,也没有在网上找到任何东西。在同一解释器中编译OpenCl C代码时出现任何错误后,行为会发生变化,在“英特尔OpenCl”上创建上下文的速度会如预期的那样快。我发现绕过这个问题的唯一解决方案是在函数外部创建上下文。然后每次我调用函数时,它只需进行计算,而不需要花费时间。但至于为什么创建上下文需要花费很长时间,我仍然不知道。@someone它可能在做很多事情——我们只是不知道(例如,创建和固定工作线程、保留内存区域、设置内部数据结构、加载辅助库等)。不过这并不重要——您只需要创建一次上下文,然后在整个程序中重复使用它。
# 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