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>