wan*_*gsy 2 opengl graphics glsl
我搜索并阅读了一些关于不连贯内存访问的wiki ,例如https://en.wikipedia.org/wiki/Memory_coherence、https://www.khronos.org/opengl/wiki/Memory_Model
据我所知,内存访问不一致的主要原因是同一内存地址的多个本地缓存。在高速缓存架构中,处理器通常不直接访问内存,而是访问高速缓存。对于多处理器系统,每个处理器都有自己的缓存,但共享一个内存,这可能会导致同一内存地址的多个副本。因此,即使在另一个进程写入某个内存地址之后,一个处理器也可能会读取该地址的旧数据。
然而,共享变量应该位于缓存中,并且只能由在同一处理器上执行的同一工作组内的调用访问。因此不应存在共享变量的多个版本。即使共享变量的大小超过了缓存的最大大小,部分数据仍会在内存中,共享变量只存在于一个缓存中。为什么对共享变量的访问不一致?
另外,通过工作组内的调用访问一致的图像/缓冲区变量是否不一致?
据我了解,计算着色器中有两种障碍。
barrierglsl的函数,用于控制着色器代码的执行,并确保前面的写操作确实发生在后面的读操作之前。incoherent memory access这意味着即使读取操作发生在写入操作之后,着色器调用写入的值也不一定对其他调用可见。内存屏障就是用来处理这种情况的。我真正想问的是,关于一个工作组的调用,incoherent memory access我是否可以描述共享、缓冲区或图像变量发生的情况?换句话说,对于一个工作组的调用,如果我用来barrier确保读操作发生在写操作之后,写入的值对读操作是否可见?
以我的思维方式,在上述情况下,写入的值对于后续的读取操作始终是可见的。因为,一个工作组仅在一个计算单元上执行,因此同一内存地址不存在多个缓存。但我对此并不确定。
工作组大小限制通常比实际执行单元的波前/扭曲大小大很多倍。将调用收集到工作组中的目的是能够让它们共享信息并在它们之间设置执行障碍。
如果工作组大于调用子组(或者由于条件执行不同而存在执行分歧),共享内存仍然需要工作。如果波前大小为 32,但工作组大小为 128,当调用 2 位于不同波前时,调用号 97 如何读取调用 2 写入的数据?
实现可以在同一计算单元上顺序执行它们。执行前 32 个调用,然后执行下一个调用,依此类推。这会将所有共享内存保留在本地存储中,但是如何读取另一个调用写入的数据呢?您需要一个执行屏障,以便实现知道停止执行当前的 32 并移至工作组内的下一个波前。内存访问是不连贯的,因为您无法知道哪些调用甚至在没有显式屏障的情况下执行了写入。
此类工作组的任何串行执行方式都意味着共享内存必须在不同的计算单元之间共享。这意味着缓存。