Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

map: zero-allocation operations for common types #1062

Merged
merged 1 commit into from
Sep 14, 2023

Commits on Sep 14, 2023

  1. map: zero-allocation operations for common types

    Map keys and values are currently marshaled into []byte by souped
    up versions of binary.Write and binary.Read. This allows users to
    be blissfully unaware of compiler inserted padding on the Go side.
    This is wasteful in case the Go in-memory representation matches
    what the kernel expects because we need additional allocations.
    
    Refactor syscall marshaling into a new package sysenc which
    encapsulates the logic we need to determine whether a Go type
    is safe for zero-allocation / zero-copy marshaling. The type
    must be a pointer to or a slice of:
    
    * A primitive type like uint32, ... or
    * An array of valid types or
    * A struct made up of valid types without any compiler
      inserted padding between fields
    
    Per-CPU maps don't support zero-allocation operations for now,
    but the new code already makes things a little bit cheaper.
    
    Structs with trailing padding also don't benefit from the
    optimization for now. Consider
    
        type padded struct { A uint32; B uint16 }
    
    Allowing such a type creates an edge case: make([]padding, 1)
    uses zero-allocation marshaling while make([]padding, 2)
    doesn't, due to interior padding. It's simpler to skip such
    types for now.
    
        goos: linux
        goarch: amd64
        pkg: github.com/cilium/ebpf
        cpu: 12th Gen Intel(R) Core(TM) i7-1260P
                                             │ unsafe.txt  │
                                             │   sec/op    │
        Marshaling/ValueUnmarshalReflect-16    356.1n ± 2%
        Marshaling/KeyMarshalReflect-16        368.6n ± 1%
        Marshaling/ValueBinaryUnmarshaler-16   378.6n ± 2%
        Marshaling/KeyBinaryMarshaler-16       356.2n ± 1%
        Marshaling/KeyValueUnsafe-16           328.0n ± 2%
        PerCPUMarshalling/reflection-16        1.232µ ± 1%
    
                                             │  unsafe.txt  │
                                             │     B/op     │
        Marshaling/ValueUnmarshalReflect-16    0.000 ± 0%
        Marshaling/KeyMarshalReflect-16        0.000 ± 0%
        Marshaling/ValueBinaryUnmarshaler-16   24.00 ± 0%
        Marshaling/KeyBinaryMarshaler-16       8.000 ± 0%
        Marshaling/KeyValueUnsafe-16           0.000 ± 0%
        PerCPUMarshalling/reflection-16        280.0 ± 0%
    
                                             │  unsafe.txt  │
                                             │  allocs/op   │
        Marshaling/ValueUnmarshalReflect-16    0.000 ± 0%
        Marshaling/KeyMarshalReflect-16        0.000 ± 0%
        Marshaling/ValueBinaryUnmarshaler-16   1.000 ± 0%
        Marshaling/KeyBinaryMarshaler-16       1.000 ± 0%
        Marshaling/KeyValueUnsafe-16           0.000 ± 0%
        PerCPUMarshalling/reflection-16        3.000 ± 0%
    
    Signed-off-by: Lorenz Bauer <lmb@isovalent.com>
    lmb committed Sep 14, 2023
    Configuration menu
    Copy the full SHA
    dba3917 View commit details
    Browse the repository at this point in the history