Python numpy的运行速度比OpenCL快吗?

Python numpy的运行速度比OpenCL快吗?,python,numpy,pyopencl,Python,Numpy,Pyopencl,我在pyopencl中尝试了一些基本的例子,并注意到,无论我做什么,numpy都比pyopengl运行得更快。我在Intel i5嵌入式HD4400上运行脚本。显然没什么特别的,但是numpy的运行速度至少是pyopengl的两倍。我尝试的最后一个脚本: import pyopencl as cl from pyopencl import algorithm import numpy as np from time import time from pyopencl.clrandom impor

我在pyopencl中尝试了一些基本的例子,并注意到,无论我做什么,numpy都比pyopengl运行得更快。我在Intel i5嵌入式HD4400上运行脚本。显然没什么特别的,但是numpy的运行速度至少是pyopengl的两倍。我尝试的最后一个脚本:

import pyopencl as cl
from pyopencl import algorithm
import numpy as np
from time import time
from pyopencl.clrandom import rand
from pyopencl.array import to_device

if __name__ == '__main__':
    ctx = cl.create_some_context()
    queue = cl.CommandQueue(ctx)
    q = np.random.random_integers(-10**6,high=10**6, size=2**24)
    r = to_device(queue, q)
    begin = time()
    out, count, even = algorithm.copy_if(r, "ary[i] < 42", queue=queue)
    out.get()
    print("OpenCL takes {:9.6F} seconds".format(time() - begin))
    begin = time()
    b = q[q<42]
    print("numpy takes {:9.6F} seconds".format(time() - begin))

为什么我没有看到并行性的一些优势?另外,我也很欣赏到结构良好的(py)opencl教程或文档的链接。提前谢谢

在一次极其廉价的操作中比较两者并不是一个很好的比较

对于大多数设备,OpenCL必须将所有数据移动到设备上或从设备上移出(例如,从主内存移动到GPU内存,然后再移动回来),当操作很琐碎时,成本要高于操作本身。它还必须编译/传输代码以执行操作,这具有非零成本、设备和主机之间的同步等。尝试找到真正的工作要做(理想情况下,没有条件分支的真正工作);在不向设备传输数据的情况下完成的实际工作越多,OpenCL将做得越好。请注意,
numpy
仍然会做得很好,因为它将在可用时使用向量化操作本身;SSE操作可能无法像GPGPU代码那样扩展,但当操作简单且不需要在设备之间进行内存传输时,
numpy
可以做得很好


为了进行比较,您可以尝试检查数据传输本身需要多长时间;假设
pyopencl
没有对其进行优化,您可以尝试一个noop操作,只将数据发送到设备,然后将其拉回来,看看数据传输会产生何种开销。从那里,您可以看到
pyopencl
涉及到什么样的基本开销;如果
numpy
没有做足够的工作来显著超过这一开销,那么
pyopencl
将无济于事。

在一个极其廉价的操作上比较这两种方法不是一个很好的比较

对于大多数设备,OpenCL必须将所有数据移动到设备上或从设备上移出(例如,从主内存移动到GPU内存,然后再移动回来),当操作很琐碎时,成本要高于操作本身。它还必须编译/传输代码以执行操作,这具有非零成本、设备和主机之间的同步等。尝试找到真正的工作要做(理想情况下,没有条件分支的真正工作);在不向设备传输数据的情况下完成的实际工作越多,OpenCL将做得越好。请注意,
numpy
仍然会做得很好,因为它将在可用时使用向量化操作本身;SSE操作可能无法像GPGPU代码那样扩展,但当操作简单且不需要在设备之间进行内存传输时,
numpy
可以做得很好


为了进行比较,您可以尝试检查数据传输本身需要多长时间;假设
pyopencl
没有对其进行优化,您可以尝试一个noop操作,只将数据发送到设备,然后将其拉回来,看看数据传输会产生何种开销。从那里,您可以看到
pyopencl
涉及到什么样的基本开销;如果
numpy
没有做足够的工作来显著超过该开销,那么
pyopencl
将不会有帮助。

如果您确实在嵌入式芯片上运行,传输开销不应该太大。但也要注意,这个琐碎的操作是内存限制的;numpy和opencl代码都来自同一个内存系统;因此,您不应该期望在这个基准测试中获得任何东西。但是使用opencl确实会迫使您在内存上进行两次额外的传递,以在(ram中)opencl上下文中进行复制。不过,opencl显然有额外的开销,我无法真正解释;也许从来没有人为这个芯片组制作过半个像样的opencl驱动程序?

如果您确实在嵌入式芯片上运行,那么传输开销应该不会太大。但也要注意,这个琐碎的操作是内存限制的;numpy和opencl代码都来自同一个内存系统;因此,您不应该期望在这个基准测试中获得任何东西。但是使用opencl确实会迫使您在内存上进行两次额外的传递,以在(ram中)opencl上下文中进行复制。不过,opencl显然有额外的开销,我无法真正解释;也许从来没有人为这个芯片组制作过半途而废的opencl驱动程序?

没错!我想添加一个简单的现实生活类比:这就像在5米远的地方试着开车,然后得出结论说走路更快。我们必须考虑启动汽车、加快速度等因素。如果距离足够远,为所有这些步骤投入的时间都会有回报。这一切都是关于每个工具相关联的权衡。(步行是numpy,OpenCL是汽车)一个更好的类比:计算100个单位数的双倍数。在计算器中输入数字,然后将数字复制到纸上,这比脑力计算要慢。但是,如果要将100个5位数与5位数相乘,计算器会更好(除非你是沙孔塔拉-德维联盟的成员)。在这里,心理计算是numpy,计算器是OpenCLExactly!我想添加一个简单的现实生活类比:这就像在5米远的地方试着开车,然后得出结论说走路更快。我们必须考虑启动汽车、加快速度等因素。如果距离足够远,为所有这些步骤投入的时间都会有回报。这一切都是关于每个工具相关联的权衡。(步行是numpy,OpenCL是汽车)一个更好的类比:计算100个单位数的双倍数。在计算器中输入数字,然后将数字复制到纸上,这比脑力计算要慢。但是,如果要将100个5位数与5位数相乘,计算器会更好(除非你是沙孔塔拉-德维联盟的成员)。这里是心理计算
OpenCL takes  1.223419 seconds
numpy takes  0.269451 seconds