如果“buffer”是“coherent”,那么读取字段或执行“atomicAdd(field, 0)”之间有什么区别吗?

2024-01-06

这是 Vulkan 语义(如果有什么不同的话)。

假设如下:

layout(...) coherent buffer B
{
    uint field;
} b;

假设该字段正在被同一着色器(或派生着色器)的其他调用修改atomic*()功能。

如果着色器调用想要从中执行原子读取field(具有相同的语义atomicCounter()在 GLES 中,如果这是atomic_uint相反),以下两者之间有什么区别(除了显然其中一个既可以写也可以读)?

uint read_value = b.field;
uint read_value2 = atomicAdd(b.field, 0);

为了直接回答这个问题,这两行代码生成不同的指令,具有不同的性能特征和硬件管道使用情况。

uint read_value = b.field;                 // generates a load instruction
uint read_value2 = atomicAdd(b.field, 0);  // generates an atomic instruction
  • AMD拆解可以看这个在线Shader Playground http://shader-playground.timjones.io/0733f88ba4b8ddd197c0242b1273044d -- buffer_load_dword versus buffer_atomic_add
  • 通过微基准测试剖析 NVIDIA Volta GPU 架构 https://arxiv.org/abs/1804.06826 -- LDG versus ATOM

The GLSL规格 https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.40.pdf第 4.10 节内存限定符指出coherent仅涉及跨调用(着色器线程)的读取和写入的可见性。他们还对隐含的性能发表了评论:

当使用未声明为一致的变量访问内存时,着色器访问的内存可能会被实现缓存,以服务将来对同一地址的访问。内存存储可以以这样的方式进行缓存:写入的值对于访问同一内存的其他着色器调用可能不可见。该实现可以缓存由内存读取获取的值,并将相同的值返回到访问同一内存的任何着色器调用,即使自第一次内存读取以来底层内存已被修改。虽然未声明为一致的变量可能对着色器调用之间的通信没有用处,但使用非一致访问可能会带来更高的性能。

GPU 内存系统中的一致性点通常是最后一级缓存(L2 缓存),这意味着所有一致性访问都必须由 L2 缓存执行。这也意味着相干缓冲区无法缓存在 L1 或更靠近着色器处理器的其他缓存中。现代 GPU 还在 L2 缓存中配备了专用的原子硬件;普通负载不会使用这些,但是atomicAdd(..., 0)会经历那些。原子硬件的带宽通常比完整的二级缓存低。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果“buffer”是“coherent”,那么读取字段或执行“atomicAdd(field, 0)”之间有什么区别吗? 的相关文章

  • 如何将 mat4 数组作为统一传递

    我必须将 mat4 数组作为统一传递给我的顶点着色器 如下所示 在顶点着色器中 uniform mat4 u jointMatrix 2 在我的 C 程序中 我这样做了 glm mat4 jointM 2 I filled jointM w
  • WebGL 中的 AlphaFunctions?

    是否可以实现透明度低于 0 5 的片段被丢弃 而 alpha 高于 0 5 的片段渲染为不透明的效果 从我读到的来看 glEnable GL ALPHA TEST glAlphaFunc GL GREATER 0 5 这将是我正在寻找的 但
  • 您应该如何有效地批处理复杂的网格?

    渲染复杂网格的最佳方法是什么 我在下面写了不同的解决方案 想知道您对它们有何看法 让我们举个例子 如何渲染 Crytek Sponza 网格 PS 我不使用Ubershader 只使用单独的着色器 如果您通过以下链接下载网格 http gr
  • glDrawBuffer(GL_NONE) 与 glColorMask 设置为全部 GL_FALSE

    glDrawBuffer GL NONE 和 glColorMask GL FALSE GL FALSE GL FALSE GL FALSE 有什么区别 两者只是丢弃对颜色缓冲区的任何绘制的另一种方式吗 还是有一些差异 首先也是最重要的 g
  • 如何在 WebGL 中创建合适的圆角矩形?

    我试图实现答案这个问题 https stackoverflow com questions 43970170 bordered rounded rectangle in glsl但似乎有点问题 如果您打开他们的 ShaderToys 并尝试
  • 无法将简单的无符号字节 RGB 纹理映射到四边形:

    我有一个非常简单的程序 将虚拟红色纹理映射到四边形 下面是 C 中的纹理定义 struct DummyRGB8Texture2d uint8 t data 3 4 int width int height DummyRGB8Texture2
  • 什么时候关闭光栅化步骤才有意义?

    在 vulkan 中 有一个创建管道所需的结构 名为VkPipelineRasterizationStateCreateInfo 在这个结构体中有一个名为rasterizerDiscardEnable 如果该成员设置为VK TRUE那么在光
  • 如何快速将一个float打包为4个字节?

    我一直在寻找一种在 WebGL 纹理上存储浮动的方法 我找到了一些解决方案 http aras p info blog 2009 07 30 encoding floats to rgba the final 在互联网上 但那些只处理 0
  • OpenGL 将着色器附加到程序

    有没有办法访问附加到程序的着色器 也就是说 给定一个程序 我可以做类似的事情 vertexShader getVertexShaderFromProgram program 我想在验证我的程序的函数中记录着色器编译状态 但我只保留对程序的引
  • GLSL - 计算表面法线

    我有一个用 GLSL 编写的简单顶点着色器 我想知道是否有人可以帮助我计算表面的法线 我正在 升级 一个平面 所以当前的灯光模型看起来 很奇怪 这是我当前的代码 varying vec4 oColor varying vec3 oEyeNo
  • 即使在顶点着色器中使用,glGetUniformLocation()也会返回-1

    我正在尝试用法线渲染一个简单的立方体 我使用以下代码来初始化着色器 void initShader const char vertexShaderPath const char fragmentShaderPath cout lt lt I
  • 为什么拥有单独的投影矩阵但结合模型和视图矩阵会有好处?

    当您学习 3D 编程时 您会被告知用 3 个变换矩阵来思考是最简单的 模型矩阵 该矩阵对于每个模型都是独立的 它根据需要旋转和缩放对象 最后将其移动到 3D 世界中的最终位置 模型矩阵将模型坐标转换为世界坐标 视图矩阵 对于大量对象 如果不
  • GL_CULL_FACE使所有对象消失

    我正在尝试在 openGL3 3 中创建一些简单的多边形 我有两种类型的对象 具有以下属性 对象 1 10 个顶点 按顺序在下面列出 存储在GL ARRAY BUFFER并使用GL TRIANGLE FAN v x y z w v 0 0
  • 使用 GLSL 直接在着色器中从位置计算平移矩阵

    我正在开发 C OpengL 程序以及 GLSL 顶点和片段着色器 我正在创建同一对象的多个实例 我只需要改变实例之间的对象位置 这是我所做的 我正在使用一个统一变量 它是一个变换矩阵数组 每个矩阵代表一个对象实例 MVP 也是一个变换矩阵
  • GLSL - 测试片段值

    假设你有一个vec3 colourIn从一个vertex shader to a frag shader 有没有办法测试一个值并根据需要覆盖它 例如 将任何蓝色值大于0 5的片段设置为白色 In my Shader frag我实施了这个测试
  • 在 Vulkan 中,图形队列系列与当前队列系列分离是否有益?

    据我所知 队列系列可能支持呈现到屏幕但不支持图形 假设我有一个同时支持图形和呈现的队列系列 以及另一个仅支持呈现的队列系列 我应该为两个进程使用第一个队列系列 还是应该将第一个队列系列委托给图形 将后者委托给呈现 或者这两种方法之间没有明显
  • GLSL 中统一浮点行为和常量浮点行为的不同

    我正在尝试在 GLSL 中实现模拟双精度 并且观察到一种奇怪的行为差异 导致 GLSL 中出现细微的浮点错误 考虑以下片段着色器 写入 4 浮点纹理以打印输出 layout location 0 out vec4 Output unifor
  • 延迟阴影映射 GLSL

    我目前正在实施延迟渲染管道 但我仍坚持使用阴影贴图 我已经成功地将其实施到前向管道中 我所做的步骤是 获取灯光视图中的位置 转换为光视图剪辑空间 使用 0 5 0 5 获取阴影纹理坐标 检查深度 编辑 使用新结果图像更新代码 float c
  • 子组调用索引是否映射到 gl_LocalInitationIndex?

    我需要计算吗gl SubgroupID gl SubgroupSize gl SubgroupInvocationID 或者我可以使用gl LocalInvocationIndex 单个子组内的调用是否连续gl SubgroupInvoca
  • GLSL memoryBarrierShared() 有用吗?

    我想知道 memoryBarrierShared 的用处 事实上 当我查找屏障功能的文档时 我读到 对于计算着色器中任何给定的静态屏障实例 单个工作组内的所有调用都必须进入该实例 然后才能允许任何调用继续超出该实例 这确保了在给定的屏障静态

随机推荐