UE4 Compute Shader缓存命中率优化为何适得其反?
对GPU内存访问模式的误解
GPU缓存是按**缓存行(Cache Line)**批量加载的,常见尺寸是64或128字节。你之前觉得分散访问需要多次VRAM读取,但实际情况是:只要多个线程的访问地址落在同一缓存行,GPU会一次性加载整行,后续线程直接命中缓存。而调整后的连续数据布局,反而可能让不同线程组的访问地址跨度变大,缓存行复用率降低——比如原本多个线程组的访问能共享部分缓存行,调整后每个线程组独占连续缓存行,后续线程组访问时缓存行已被替换,反而增加了缓存未命中。Structured Buffer的内置优化被破坏
现代GPU对Structured Buffer有自动内存布局优化,比如根据访问模式做数据预取、合并访问请求。你手动调整数据顺序,直接打乱了驱动的优化策略。比如驱动原本会把同一Wavefront(SIMD单元内的线程集合)频繁访问的数据自动聚合到连续内存,你强行重排后,驱动的预取逻辑失效,反而触发更多VRAM读取操作。线程组尺寸与数据对齐不匹配
你的线程组是3x3x1(共9个线程),如果调整后的数据块大小和缓存行尺寸、Wavefront大小(通常32或64线程)不匹配,会造成缓存行浪费或冲突。比如每个线程组的连续数据刚好跨多个缓存行,而Wavefront内的线程访问时,没法充分利用已加载的缓存行,反而产生更多部分缓存行读取,直接拉低命中率。PIX分析的细节偏差
PIX的缓存命中率统计是基于整个Dispatch周期的。调整数据布局后,GPU的任务调度模式可能发生变化:比如原本分散访问时GPU能并行处理更多内存请求的合并,调整后反而出现更多内存访问冲突,导致整体耗时上升。另外要确认PIX的采样范围是否准确,有没有包含其他同步或内存拷贝的额外开销。
内容的提问来源于stack exchange,提问作者Jarvan Du

