c++ - 缓存友好顶点定义

标签 c++ opengl caching

我正在编写一个 opengl 应用程序,对于顶点、法线和颜色,我使用如下单独的缓冲区:

GLuint vertex_buffer, normal_buffer, color_buffer;

我的主管告诉我,如果我定义一个像这样的结构:

struct vertex {
    glm::vec3 pos;
    glm::vec3 normal;
    glm::vec3 color;
};
GLuint vertex_buffer;

然后定义这些顶点的缓冲区,我的应用程序会变得非常快,因为当位置被缓存时,法线和颜色将在缓存行中。

我认为定义这样的结构对性能没有太大影响,因为像结构一样定义顶点会导致缓存行中的顶点减少,而将它们定义为单独的缓冲区时,将导致有 3 个不同的缓存行缓存中的位置、法线和颜色。所以,什么都没有改变。真的吗?

最佳答案

首先,为不同的顶点属性使用单独的缓冲区可能不是一个好的技术。

这里非常重要的因素是 GPU 架构。大多数(尤其是现代的)GPU 有多个缓存行(输入汇编程序阶段的数据、制服、纹理),但是从多个 VBO 获取输入属性无论如何都是低效的(总是配置文件!)。以交错格式定义它们有助于提高性能:

enter image description here

如果你使用这样的结构,这就是你会得到的。

然而,这并不总是正确的(再一次,总是剖析!)- 尽管交错数据对 GPU 更友好,但它需要正确对齐并且可能占用更多的内存空间。

但是,一般来说:

Interleaved data formats:

  • Cause less GPU cache pressure, because the vertex coordinate and attributes of a single vertex aren't scattered all over in memory. They fit consecutively into few cache lines, whereas scattered attributes could cause more cache updates and therefore evictions. The worst case scenario could be one (attribute) element per cache line at a time because of distant memory locations, while vertices get pulled in a non-deterministic/non-contiguous manner, where possibly no prediction and prefetching kicks in. GPUs are very similar to CPUs in this matter.

  • Are also very useful for various external formats, which satisfy the deprecated interleaved formats, where datasets of compatible data sources can be read straight into mapped GPU memory. I ended up re-implementing these interleaved formats with the current API for exactly those reasons.

  • Should be layouted alignment friendly just like simple arrays. Mixing various data types with different size/alignment requirements may need padding to be GPU and CPU friendly. This is the only downside I know of, appart from the more difficult implementation.

  • Do not prevent you from pointing to single attrib arrays in them for sharing.

Source

进一步阅读:

Best Practices for Working with Vertex Data

Vertex Specification Best Practices

关于c++ - 缓存友好顶点定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29623938/

相关文章:

用于在笛卡尔空间中可视化/动画化粒子的 Python 框架

跟踪缓存变量/函数依赖关系的 Pythonic 方法

具有请求授权的 HTTP 缓存

c++ - 权限被拒绝是什么意思

c++ - 每台机器上的 SDL 2.0 恒定 FPS

c++ - 我的窗口在 OpenGL 中正在调整大小

c# - AppFabric 缓存服务器和 Web 应用程序在同一台物理机器上

c++ - C++中的指针按值/引用传递

c++ - 容器模板参数的 value_type

xcode - 在 Swift 中初始化 NSOpenGLPixelFormat