segment_bench_test.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. //go:build linux && !android && !e2e_testing
  2. package tio
  3. import (
  4. "testing"
  5. "github.com/slackhq/nebula/wire"
  6. )
  7. // fakeBatch stands in for batch.TxBatcher inside the bench — same shape
  8. // of pointer-capturing closure that sendInsideMessage builds.
  9. type fakeBatch struct{ buf [65536]byte }
  10. func (b *fakeBatch) Reserve(sz int) []byte { return b.buf[:sz] }
  11. func (b *fakeBatch) Commit([]byte) {}
  12. type fakeHostInfo struct {
  13. remoteIndexId uint32
  14. counter uint64
  15. }
  16. type fakeIface struct {
  17. rebindCount uint8
  18. hi *fakeHostInfo
  19. }
  20. // BenchmarkSegmentSuperpacketAllocsTSO measures allocation per
  21. // PerSegment call when a closure captures pointer-bearing receivers — the
  22. // realistic shape of sendInsideMessage's closure.
  23. func BenchmarkSegmentSuperpacketAllocsTSO(b *testing.B) {
  24. const mss = 1400
  25. const numSeg = 32
  26. pkt := buildTSOv6(mss*numSeg, mss)
  27. gso := wire.GSOInfo{
  28. Size: mss,
  29. HdrLen: 60, // 40 (IPv6) + 20 (TCP)
  30. CsumStart: 40,
  31. Proto: wire.GSOProtoTCP,
  32. }
  33. p := wire.TunPacket{Bytes: pkt, Meta: gso}
  34. hi := &fakeHostInfo{remoteIndexId: 0xdeadbeef}
  35. f := &fakeIface{rebindCount: 7, hi: hi}
  36. fb := &fakeBatch{}
  37. // PerSegment consumes pkt destructively; refresh from a master copy
  38. // each iter (matches the production pattern where every TUN read hands
  39. // the segmenter a fresh kernel-supplied buffer).
  40. master := append([]byte(nil), pkt...)
  41. work := make([]byte, len(pkt))
  42. p.Bytes = work
  43. b.ReportAllocs()
  44. b.ResetTimer()
  45. for i := 0; i < b.N; i++ {
  46. copy(work, master)
  47. err := p.PerSegment(func(seg []byte) error {
  48. out := fb.Reserve(16 + len(seg) + 16)
  49. out[0] = byte(f.rebindCount)
  50. out[1] = byte(hi.counter)
  51. hi.counter++
  52. fb.Commit(out)
  53. return nil
  54. })
  55. if err != nil {
  56. b.Fatalf("PerSegment: %v", err)
  57. }
  58. }
  59. }