When to Use meshopt_optimizeVertexCacheFifo Over meshopt_optimizeVertexCache: A Complete Guide
Use meshopt_optimizeVertexCacheFifo when you need deterministic, conservative reordering that preserves the original triangle sequence and adjacency relationships, whereas meshopt_optimizeVertexCache provides aggressive Tipsify-based optimization for maximum cache hit rates at the cost of potentially disturbing the original ordering.
The zeux/meshoptimizer library provides two distinct vertex cache optimization strategies in src/meshoptimizer.h that serve different pipeline requirements. While both functions reorder triangle indices to improve GPU vertex cache utilization, choosing between meshopt_optimizeVertexCacheFifo and meshopt_optimizeVertexCache depends on whether you prioritize maximum cache efficiency or predictable, gentle reordering. Understanding the algorithmic differences between these two approaches ensures you select the right optimizer for your specific mesh processing workflow.
Understanding the Two Vertex Cache Optimizers
The Aggressive Tipsify Approach (meshopt_optimizeVertexCache)
The standard meshopt_optimizeVertexCache function implements the Tipsify algorithm, which aggressively reorders triangles to maximize cache hits for a specified cache size. As implemented in src/vcacheoptimizer.cpp, this optimizer treats the vertex cache as a fully associative structure with LRU (Least Recently Used) replacement policy, allowing it to make globally optimal decisions that may significantly perturb the original triangle ordering.
The FIFO Conservative Approach (meshopt_optimizeVertexCacheFifo)
In contrast, meshopt_optimizeVertexCacheFifo implements a FIFO (First-In-First-Out) cache model that processes triangles using a queue-based approach. According to the API declarations in src/meshoptimizer.h, this function respects the original drawing order more closely, yielding less aggressive but more predictable reordering behavior that preserves adjacency relationships and vertex winding.
Key Differences Between meshopt_optimizeVertexCacheFifo and meshopt_optimizeVertexCache
The fundamental distinction lies in their cache replacement policies and reordering strategies:
- Cache Model:
meshopt_optimizeVertexCacheassumes an LRU cache optimized for maximum hit rates, whilemeshopt_optimizeVertexCacheFifoassumes a FIFO queue that processes vertices in submission order. - Reordering Aggressiveness: The standard optimizer may drastically reorder triangles to achieve optimal cache utilization, whereas the FIFO variant maintains proximity to the original index buffer sequence.
- Determinism: The FIFO optimizer produces more predictable results across different mesh configurations, making it preferable for debugging and visual consistency.
When to Choose meshopt_optimizeVertexCacheFifo Over meshopt_optimizeVertexCache
Select the FIFO variant over the standard Tipsify optimizer when:
- You require deterministic ordering for debugging purposes or visual consistency across different optimization runs.
- The mesh already exhibits good vertex locality and only needs modest cache improvements rather than aggressive reordering.
- You must preserve vertex winding and adjacency relationships that might be broken by the more aggressive LRU-based optimizer.
- You are targeting very small GPU caches where the FIFO strategy's simplicity provides equally effective results without computational overhead.
Implementation Details from the Source Code
In src/meshoptimizer.h, both functions share similar signatures but implement distinct optimization strategies:
void meshopt_optimizeVertexCache(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count, unsigned int cache_size);
void meshopt_optimizeVertexCacheFifo(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count, unsigned int cache_size);
The implementations reside in src/vcacheoptimizer.cpp, where the standard optimizer uses a scoring system based on cache position and valuation, while the FIFO variant uses a queue-based processing approach that limits how far triangles can move from their original positions. For benchmarking comparisons, reference tools/vcachetuner.cpp, which provides side-by-side evaluation of both algorithms.
Practical Code Examples
The following example demonstrates how to invoke both optimizers with a 32-entry cache:
#include "meshoptimizer.h"
#include <vector>
// Original index buffer
std::vector<unsigned int> indices = { /* ... */ };
size_t indexCount = indices.size();
size_t vertexCount = /* number of unique vertices */;
// Aggressive Tipsify optimization
std::vector<unsigned int> optimizedIndices(indexCount);
meshopt_optimizeVertexCache(
optimizedIndices.data(),
indices.data(),
indexCount,
vertexCount,
32
);
// Conservative FIFO optimization
std::vector<unsigned int> fifoOptimizedIndices(indexCount);
meshopt_optimizeVertexCacheFifo(
fifoOptimizedIndices.data(),
indices.data(),
indexCount,
vertexCount,
32
);
Summary
meshopt_optimizeVertexCacheimplements aggressive Tipsify-based LRU cache optimization for maximum hit rates.meshopt_optimizeVertexCacheFifoprovides conservative FIFO-based reordering that preserves original triangle ordering.- Choose the FIFO variant when you need deterministic results, have meshes with good existing locality, or must preserve adjacency relationships.
- Both functions are declared in
src/meshoptimizer.hand implemented insrc/vcacheoptimizer.cpp. - Start with the standard optimizer; switch to FIFO if aggressive reordering causes pipeline issues.
Frequently Asked Questions
Does meshopt_optimizeVertexCacheFifo produce worse cache efficiency than the standard optimizer?
Not necessarily. While the FIFO optimizer generally produces lower cache hit rates than the Tipsify-based meshopt_optimizeVertexCache on complex meshes, the difference is often negligible for meshes with good initial locality or when targeting very small cache sizes. The FIFO strategy trades maximum theoretical efficiency for predictability and preservation of input ordering.
Can I run both optimizers sequentially on the same mesh?
Running both optimizers sequentially is not recommended. Since each function completely reorders the index buffer based on different assumptions, applying one after the other would simply replace the first optimization with the second. Instead, benchmark both independently using tools/vcachetuner.cpp to determine which performs better for your specific mesh topology.
What cache size should I specify for the FIFO optimizer?
The cache_size parameter in meshopt_optimizeVertexCacheFifo represents the number of entries in your target GPU's vertex cache. Common values range from 12 to 32 entries for modern hardware. The FIFO optimizer is particularly effective with smaller cache sizes (12-16 entries) where its queue-based approach closely matches actual hardware behavior.
How do I verify which optimizer works better for my specific mesh?
Use the tools/vcachetuner.cpp utility provided in the zeux/meshoptimizer repository to benchmark both algorithms against your actual mesh data. This tool calculates ACMR (Average Cache Miss Ratio) and ATVR (Average Transform Vertex Ratio) metrics for both meshopt_optimizeVertexCache and meshopt_optimizeVertexCacheFifo, allowing you to make an empirical decision based on measurable cache performance rather than theoretical assumptions.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →