# When to Use meshopt_optimizeVertexCacheFifo Over meshopt_optimizeVertexCache: A Complete Guide

> Learn when to use meshopt_optimizeVertexCacheFifo versus meshopt_optimizeVertexCache. Discover deterministic reordering for preserved triangle sequences or aggressive optimization for maximum cache hits.

- Repository: [Arseny Kapoulkine/meshoptimizer](https://github.com/zeux/meshoptimizer)
- Tags: how-to-guide
- Published: 2026-07-12

---

**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`](https://github.com/zeux/meshoptimizer/blob/main/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`](https://github.com/zeux/meshoptimizer/blob/main/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`](https://github.com/zeux/meshoptimizer/blob/main/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_optimizeVertexCache` assumes an LRU cache optimized for maximum hit rates, while `meshopt_optimizeVertexCacheFifo` assumes 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:

1. **You require deterministic ordering** for debugging purposes or visual consistency across different optimization runs.
2. **The mesh already exhibits good vertex locality** and only needs modest cache improvements rather than aggressive reordering.
3. **You must preserve vertex winding and adjacency relationships** that might be broken by the more aggressive LRU-based optimizer.
4. **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`](https://github.com/zeux/meshoptimizer/blob/main/src/meshoptimizer.h), both functions share similar signatures but implement distinct optimization strategies:

```cpp
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`](https://github.com/zeux/meshoptimizer/blob/main/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`](https://github.com/zeux/meshoptimizer/blob/main/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:

```cpp
#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_optimizeVertexCache` implements aggressive Tipsify-based LRU cache optimization for maximum hit rates.
- `meshopt_optimizeVertexCacheFifo` provides 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.h`](https://github.com/zeux/meshoptimizer/blob/main/src/meshoptimizer.h) and implemented in [`src/vcacheoptimizer.cpp`](https://github.com/zeux/meshoptimizer/blob/main/src/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`](https://github.com/zeux/meshoptimizer/blob/main/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`](https://github.com/zeux/meshoptimizer/blob/main/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.