gpt4 book ai didi

vulkan - Vulkan 计算着色器缓存和屏障

转载 作者:行者123 更新时间:2023-12-04 16:24:06 29 4
gpt4 key购买 nike

我试图了解整个 L1/L2 冲洗是如何工作的。假设我有一个像这样的计算着色器

layout(std430, set = 0, binding = 2) buffer Particles{
Particle particles[];
};


layout(std430, set = 0, binding = 4) buffer Constraints{
Constraint constraints[];
};


void main(){
const uint gID = gl_GlobalInvocationID.x;
for (int pass=0;pass<GAUSS_SEIDEL_PASSES;pass++){
// first query the constraint, which contains particle_id_1 and particle_id_1
const Constraint c = constraints[gID*GAUSS_SEIDEL_PASSES+pass];
// read newest positions
vec3 position1 = particles[c.particle_id_1].position;
vec3 position2 = particles[c.particle_id_2].position;
// modify position1 and position2
position1 += something;
position2 -= something;
// update positions
particles[c.particle_id_1].position = position1;
particles[c.particle_id_2].position = position2;
// in the next iteration, different constraints may use the updated positions
}
}

据我了解,最初所有数据都驻留在 L2 中。当我阅读 particles[c.particle_id_1].position我将一些数据从 L2 复制到 L1(或直接复制到寄存器)。
然后在 position1 += something我修改了 L1(或寄存器)。终于在 particles[c.particle_id_2].position = position1 ,我将数据从 L1(或寄存器)刷新回 L2,对吗?因此,如果我想在此之后运行第二个计算着色器,并且第二个着色器将读取粒子的位置,则我不需要同步 Particles .只放置一个执行屏障就足够了,没有内存屏障
void vkCmdPipelineBarrier(
VkCommandBuffer commandBuffer,
VkPipelineStageFlags srcStageMask, // here I put VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
VkPipelineStageFlags dstStageMask, // here I put VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
VkDependencyFlags dependencyFlags, // here nothing
uint32_t memoryBarrierCount, // here 0
const VkMemoryBarrier* pMemoryBarriers, // nullptr
uint32_t bufferMemoryBarrierCount, // 0
const VkBufferMemoryBarrier* pBufferMemoryBarriers, // nullptr
uint32_t imageMemoryBarrierCount, // 0
const VkImageMemoryBarrier* pImageMemoryBarriers); // nullptr

最佳答案

Vulkan 的内存模型并不将“缓存”视为缓存。它的模型建立在可用性和可见性的概念之上。如果命令/阶段 A 与命令/阶段 B 具有执行依赖性,则 GPU 命令/阶段 A 产生的值对 GPU 命令/阶段 B“可用”。GPU 命令/阶段 A 产生的值对 GPU“可见”命令/阶段 B 如果命令/阶段 A 与命令/阶段 B 具有内存依赖关系,则关于所讨论的特定内存以及 A 写入它和 B 将访问它的访问模式。
如果某个值对命令/阶段既不可用也不可见,则尝试访问它会产生未定义的行为。
可用性和可见性的实现将涉及清除缓存等。但就 Vulkan 内存模型而言,这是一个它并不关心的实现细节。您也不应该:了解 Vulkan 内存模型并编写在其中运行的代码。
您的管道屏障会创建执行依赖项,但不会创建内存依赖项。因此,在屏障之前由 CS 进程写入的值对之后的 CS 进程可用,但对它们不可见。您需要具有内存依赖性才能建立可见性。

但是,如果您想要 GPU 级别的理解……这完全取决于 GPU。 GPU 是否具有缓存层次结构、L1/L2 拆分?也许有些人会,也许不会。
无论如何,这都无关紧要,因为仅将值写入内存中的地址并不等同于“刷新”该内存周围的适当缓存。即使使用 coherent限定符只会导致在同一调度调用中执行的计算着色器操作刷新。不能保证会影响以后的调度调用。

关于vulkan - Vulkan 计算着色器缓存和屏障,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68663665/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com