【问题标题】:opengl shared memory layout and sizeopengl共享内存布局和大小
【发布时间】:2022-12-05 07:18:52
【问题描述】:

给定以下 glsl 声明(这只是一个示例):

struct S{
    f16vec3 a;
    float16_t b;
    f16vec3_t c;
    float16_t d;
};
shared float16_t my_float_array[100];
shared S my_S_array[100];

我有以下问题:

  • 给定的声明将使用多少共享内存,例如在上面的示例中?
  • 共享内存中的变量使用哪种内存布局? std140、std430 还是其他?
  • 这对银行冲突有何影响?

我能够使用程序获得所需的总共享内存glGetProgramBinary并跳到以“!!NV”开头的行指示的文本部分的开头:

...
!!NVcp5.0
OPTION NV_shader_buffer_load;
OPTION NV_internal;
OPTION NV_gpu_program_fp64;
OPTION NV_shader_storage_buffer;
OPTION NV_bindless_texture;
OPTION NV_gpu_program5_mem_extended;
GROUP_SIZE 4 4 4;
SHARED_MEMORY 4480;
SHARED shared_mem[] = { program.sharedmem };
...

虽然这是相当间接的,但并没有说明对齐/打包规则。

【问题讨论】:

    标签: opengl


    【解决方案1】:

    给定声明将使用的共享内存量取决于共享内存块中声明的变量的类型和数量。在您提供的示例中,共享内存块将使用 4480 字节的共享内存。

    共享内存中用于变量的内存布局是 std140。这意味着每个基本类型(例如 float、int 等)都存储为具有特定对齐要求的连续内存位置序列。例如,浮点值必须与 4 字节边界对齐,而 vec3 值(三个浮点值)必须与 16 字节边界对齐。

    至于存储体冲突,当 CUDA 块中的多个线程试图同时访问共享内存中的同一个存储体时,就会发生冲突。这会导致性能下降,因为一次只有一个线程可以访问给定的内存库。为避免存储区冲突,重要的是要确保变量以避免冲突的方式布置在共享内存中。例如,通过将变量对齐到其大小的倍数,或者通过使用填充来确保不同的变量映射到不同的内存库。

    要确定程序使用的共享内存量,可以使用 glGetProgramiv 函数的 GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT 和 GL_SHADER_STORAGE_BUFFER_SIZE 参数。这些参数将分别为您提供共享内存块的对齐方式和大小。

    您可以使用这些值来计算给定程序使用的共享内存量,并确定共享内存块中变量的内存布局。然而,这是一种间接的方式,可能无法确定共享内存块中变量的确切内存布局。为此,您需要使用可以提供有关共享内存中变量内存布局的更多详细信息的调试工具。

    【讨论】:

      猜你喜欢
      • 2016-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-29
      • 1970-01-01
      • 2011-09-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多