Back to all reviewers

Optimize memory access

dotnet/runtime
Based on 9 comments
C#

When implementing performance-critical algorithms, carefully consider memory access patterns. Document alignment assumptions when using low-level operations like `MemoryMarshal.Cast` or SIMD intrinsics. Prefer reference-based APIs over pinning to avoid GC interference. For bulk operations, use specialized helpers like `LoadUnsafe(ref T source, nuint...

Algorithms C#

Reviewer Prompt

When implementing performance-critical algorithms, carefully consider memory access patterns. Document alignment assumptions when using low-level operations like MemoryMarshal.Cast or SIMD intrinsics. Prefer reference-based APIs over pinning to avoid GC interference. For bulk operations, use specialized helpers like LoadUnsafe(ref T source, nuint elementOffset) instead of pointer arithmetic.

// Less optimal: Uses pinning that can hinder GC
unsafe void ProcessBytes(ReadOnlySpan<byte> source)
{
    fixed (byte* ptr = source)
    {
        for (int i = 0; i < source.Length - 7; i += 8)
        {
            ulong value = *(ulong*)(ptr + i);
            // Process 8 bytes at once
        }
    }
}

// More optimal: Uses ref-based API without pinning
void ProcessBytes(ReadOnlySpan<byte> source)
{
    ref byte sourceRef = ref MemoryMarshal.GetReference(source);
    for (int i = 0; i + 8 <= source.Length; i += 8)
    {
        // Use LoadUnsafe with explicit offset
        ulong value = Vector64.LoadUnsafe(ref sourceRef, (nuint)i);
        // Process 8 bytes at once
    }
}

When handling data in bulk, consider the impact of alignment requirements and document edge cases like zero-length inputs. For operations on numeric types, select appropriate operations based on platform characteristics (e.g., prefer unsigned division over signed when possible).

9
Comments Analyzed
C#
Primary Language
Algorithms
Category

Source Discussions