Opencl 从缓冲区复制的速度差异

Opencl 从缓冲区复制的速度差异,opencl,pyopencl,Opencl,Pyopencl,我无法理解为什么这些示例中的复制速度变化如此之大。我从他们那里得到了几乎不真实的图像。“更快”变量的计算时间也更快 没有帮助: 将“slow”变量的所有变量移到内核中,各种内存标志几乎不会改变结果 原来问题出在内核中,但问题到底是什么 警告!我粘贴了整个文件 将pyopencl导入为cl 将numpy作为np导入 从PIL导入图像 导入时间 更快的变体。从缓冲区复制大约需要0.15秒 width=800 高度=800 X=0 Y=0 R=2 最大值=80000 xmin=X-R xmax=X+

我无法理解为什么这些示例中的复制速度变化如此之大。我从他们那里得到了几乎不真实的图像。“更快”变量的计算时间也更快

没有帮助: 将“slow”变量的所有变量移到内核中,各种内存标志几乎不会改变结果

原来问题出在内核中,但问题到底是什么

警告!我粘贴了整个文件

将pyopencl导入为cl
将numpy作为np导入
从PIL导入图像
导入时间
更快的变体。从缓冲区复制大约需要0.15秒

width=800
高度=800
X=0
Y=0
R=2
最大值=80000
xmin=X-R
xmax=X+R
ymin=Y-R
ymax=Y+R
ctx=cl.创建一些上下文()
queue=cl.CommandQueue(ctx)
r1=np.linspace(xmin,xmax,width,dtype=np.float64)
r2=np.linspace(ymin,ymax,height,dtype=np.float64)
q=r1+r2[:,无]*1j
q=np.ravel(q)
输出=np.empty(宽度*高度,数据类型=np.uint8)
mf=cl.mem_标志
q_opencl=cl.Buffer(ctx,mf.READ_ONLY | mf.COPY_HOST_PTR,hostbuf=q)
output_opencl=cl.Buffer(仅限ctx、mf.WRITE_、output.nbytes)
prg=cl.Program(ctx),“”
__核无效mandelbrot(uu全局双2*q,
__全局uchar*输出,ushort常量(最大值)
{
int gid=获取全局id(0);
双nreal,实数=0;
双imag=0;
输出[gid]=0.0;
int-curiter=0;
用于(curiter=0;curiter4.0f){
打破
}
}
if(库里特
较慢的变体。从缓冲区复制大约需要0.78秒

size=(800800)
X=0
Y=0
R=2
最大值=80000
ctx=cl.创建一些上下文()
queue=cl.CommandQueue(ctx)
输出=np.empty(大小[0]*size[1],数据类型=np.uint8)
mf=cl.mem_标志
output_cl=cl.Buffer(仅限ctx、mf.WRITE_、output.nbytes)
prg=cl.Program(ctx),“”
__核空曼德尔布罗特(
__全球uchar*out,
整数宽度,
整数高度,
双重真实,
双图像,
双常数半径,
整数常量(最大值){
int id=获取全局id(0);
int i=id%宽度;
int j=id/宽度;
双窗_半径=(宽度<高度)?宽度:高度;
双x0=实值+半径*(2*i-(浮动)宽度)/窗口半径;
双y0=图像-半径*(2*j-(浮动)高度)/窗口半径;
双x=0;
双y=0;
int n=0;
双x_温度=0;
对于(n=0;n4.0f){
打破
}
}
if(n
在第一版中,您将向maxiter提供80000,这是一个未签名的短款。最多65535。溢出并环绕到14k ish值

第二个版本是32位的int。80k传球正确

14.5k/80.0k迭代

0.15/0.78秒


一致的

在第一版中,您将给maxiter 80000,这是未签名的短款。最多65535。溢出并环绕到14k ish值

第二个版本是32位的int。80k传球正确

14.5k/80.0k迭代

0.15/0.78秒

一致的

我无法理解为什么这些示例中的复制速度变化如此之大

原因是:您没有测量复制命令的时间

你说“prg.mandelbrot()执行内核并进行所有计算”——它不是这样做的。它使内核排队。然后将copy命令排入队列,然后调用
wait()
。有些实现在排队后立即开始执行,但有些实现直到调用
clFinish/clFlush/clWaitForEvents
(最后一个是PyOpenCL的
Event.wait()
所做的-在代码中,
cl.enqueue\u copy()
返回一个事件)

问题是,您正在犯一个初学者的错误,即试图使用主机CPU时间来测量OpenCL(GPU)时间。它永远不起作用。您必须通过OpenCL事件评测在GPU上测量时间。怎么做

我无法理解为什么这些示例中的复制速度变化如此之大

原因是:您没有测量复制命令的时间

你说“prg.mandelbrot()执行内核并进行所有计算”——它不是这样做的。它使内核排队。然后将copy命令排入队列,然后调用
wait()
。有些实现在排队后立即开始执行,但有些实现直到调用
clFinish/clFlush/clWaitForEvents
(最后一个是PyOpenCL的
Event.wait()
所做的-在代码中,
cl.enqueue\u copy()
返回一个事件)

问题是你