我注意到,global
和constant
设备内存通常被初始化为0.这是一个普遍的规则吗?我无法在standard中找到任何内容。
答案 0 :(得分:9)
不,不。例如,我有这个小内核来测试原子添加:
kernel void atomicAdd(volatile global int *result){
atomic_add(&result[0], 1);
}
使用此主机代码(pyopencl + unittest)调用它:
def test_atomic_add(self):
NDRange = (4, 4)
result = np.zeros(1, dtype=np.int32)
out_buf = cl.Buffer(self.ctx, self.mf.WRITE_ONLY, size=result.nbytes)
self.prog.atomicAdd(self.queue, NDRange, NDRange, out_buf)
cl.enqueue_copy(self.queue, result, out_buf).wait()
self.assertEqual(result, 16)
使用我的CPU时,总是返回正确的值。但是在ATI HD 5450上,返回的值总是垃圾。
如果我记得很清楚,在NVIDIA上,第一次运行返回正确的值,即16,但是对于下一次运行,值为32,48等。它重新使用相同的位置和旧值仍然存储在那里。
当我用这一行更正我的主机代码时(将0值复制到缓冲区):
out_buf = cl.Buffer(self.ctx, self.mf.WRITE_ONLY | self.mf.COPY_HOST_PTR, hostbuf=result)
在任何设备上都能正常运行。
答案 1 :(得分:1)
据我所知,标准中没有任何句子表明这一点。 也许某些驱动程序实现会自动执行此操作,但您不应该依赖它。
我记得曾经有一个缓冲区未初始化为0的情况,但我记不起“OS +驱动程序”的设置了。
可能发生的事情是,典型的操作系统现在甚至不使用1%的设备内存。因此,当您启动OpenCL时,很可能会陷入空白区域。
答案 2 :(得分:0)
这取决于您正在开发的平台。正如@DarkZeros在前面的答案中提到的,该规范不包含任何内容。请参阅OpenCL 2.1 Spec的第104页。
但是,根据我们在Mali GPU中的经验,驱动程序会将新分配的缓冲区的所有元素初始化为零。这是第一次接触。稍后,随着时间的流逝,我们释放该缓冲区,并且其内存空间被新的缓冲区占用,该内存空间未初始化为零。 “再次,第一次触摸将看到零值。在那之后,您将看到正常的乱码。”
希望这么长的时间会有所帮助!