OpenCL是否总是对设备内存进行零初始化?

9

我注意到通常情况下,globalconstant设备内存被初始化为0。这是一条普遍的规则吗?我在标准文档中没有找到相关说明。


在PC上它可能被初始化为零,因为PC经常包含敏感或机密信息。在控制台上可能不会有这样的担忧。 - Potatoswatter
我的nbody模拟器在速度重置器出现之前一直崩溃。 - huseyin tugrul buyukisik
CaptainObvious的回答是正确的。标准中没有规定。每个设备供应商都可以按照自己的方式进行操作。在分配内存后立即将其清零将为您节省很多麻烦。 - Michael Haidl
3个回答

10
不,它不会。例如,我有一个小内核来测试原子加法:
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)

所有设备上都一切正常。


2
据我所知,标准中没有规定这一点。也许有些驱动程序实现会自动执行此操作,但您不应该依赖它。
我记得曾经有一个案例,其中缓冲区未初始化为0,但我无法记住“操作系统+驱动程序”的设置。
可能正在发生的是,典型的操作系统现在甚至不使用设备内存的1%。因此,当您启动OpenCL时,很有可能会掉入空区域。

有趣的答案推理。然而,在CPU上,内存通常也会被初始化为0。 - 1''
内存通常不会被初始化,除非在调试模式下。然而,如果您启动任何系统,所有内存都将为零。如果不使用,它将保持不变。据我所知,GPU内存很少被使用。 - DarkZeros

0

这取决于您正在开发的平台。正如@DarkZeros在之前的回答中提到的,规范并没有暗示任何内容。请参阅OpenCL 2.1 Spec的第104页。

然而,根据我们在Mali GPU上的经验,驱动程序会将新分配的缓冲区的所有元素初始化为零。这是为了第一次触摸。随着时间的推移,当我们释放此缓冲区并且其内存空间被新缓冲区占用时,该内存空间不会被初始化为零。“同样,第一次触摸会看到零值。之后,您会看到正常的无意义值。”

希望这可以在这么长的时间后对您有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接