Skip to content

Commit b1f36d6

Browse files
authored
perf: optimize pointer bytes on mesgdef (#620)
* perf: optimize pointer bytes on mesgdef structs * fitgen: generate mesgdef
1 parent b6485b6 commit b1f36d6

124 files changed

Lines changed: 537 additions & 543 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

internal/cmd/fitgen/profile/mesgdef/builder.go

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -354,35 +354,29 @@ func (b *Builder) createDynamicField(mesgName string, field *Field, parserField
354354

355355
func (b *Builder) simpleMemoryAlignment(fields []Field) {
356356
// In 64 bits machine, the layout is per 8 bytes.
357-
// If the size is a multply of 8, set 8.
357+
358+
// We sort fields by field's size in bytes in descending order.
359+
// Except for "pointer types" such as string, slice and array of string,
360+
// they are placed at the beginning of the struct to reduce how many bytes GC needs to scan.
361+
// We need this optimization because we have many instances of
362+
// mesgdef's structs and they are typically heap-allocated.
363+
//
364+
// More on "pointer bytes":
365+
// https://cs.opensource.google/go/x/tools/+/refs/tags/v0.44.0:go/analysis/passes/fieldalignment/fieldalignment.go;l=30-44
358366
for i := range fields {
359-
if strings.HasPrefix(fields[i].Type, "[]") { // Slice
360-
fields[i].Size = 24 // pointer to array (8 bytes), len (8 bytes), cap (8 bytes)
361-
} else if strings.HasPrefix(fields[i].Type, "[") { // Array
362-
size := basetype.FromString(fields[i].BaseType).Size() * fields[i].FixedArraySize
363-
rem := size % 8
364-
if rem == 0 {
365-
fields[i].Size = size
366-
} else if rem%4 == 0 {
367-
fields[i].Size = 4
368-
} else if rem%2 == 0 {
369-
fields[i].Size = 2
370-
} else {
371-
fields[i].Size = 1
372-
}
373-
} else if isTypeTime(fields[i].ProfileType) { // time.Time
367+
switch {
368+
case fields[i].BaseType == "string": // []string and [N]string are also included
369+
fields[i].Size = 255 // Actual size 16: pointer to array (8 bytes) + len (8 bytes)
370+
case strings.HasPrefix(fields[i].Type, "[]"): // Slice
371+
fields[i].Size = 255 // Actual size 24: pointer to array (8 bytes), len (8 bytes), cap (8 bytes)
372+
case isTypeTime(fields[i].ProfileType): // time.Time
374373
fields[i].Size = 24 // wall (8 bytes), ext (8 bytes), *loc (8 bytes)
375-
} else if fields[i].BaseType == "string" {
376-
fields[i].Size = 16 // pointer to array (8 bytes) + len (8 bytes)
377-
} else { // Everything else, 8 bytes or lower.
374+
default: // Everything else: Array or single value order by its (element) size.
378375
fields[i].Size = basetype.FromString(fields[i].BaseType).Size()
379376
}
380377
}
381378
// Order by the size desc.
382379
slices.SortStableFunc(fields, func(a, b Field) int {
383-
if a.Size%8 == 0 && b.Size%8 == 0 {
384-
return 0
385-
}
386380
if a.Size > b.Size {
387381
return -1
388382
} else if a.Size < b.Size {

internal/cmd/fitgen/profile/mesgdef/mesgdef.tmpl

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,18 @@ import (
2121
// Note: The order of the fields is optimized using a memory alignment algorithm.
2222
// Do not rely on field indices, such as when using reflection.
2323
type {{ .Name }} struct {
24+
UnknownFields []proto.Field // UnknownFields are fields that are exist but they are not defined in Profile.xlsx
25+
{{ if and (not (eq .Name "FileId")) (not (eq .Name "DeveloperDataId")) (not (eq .Name "FieldDescription")) -}}
26+
DeveloperFields []proto.DeveloperField // DeveloperFields are custom data fields [Added since protocol version 2.0]
27+
{{ end }}
28+
2429
{{ range .OptimizedFields -}}
2530
{{ .Name }} {{ .Type }} {{ if .Comment }} // {{ .Comment }} {{ end }}
26-
{{ end }}
27-
28-
{{ if gt .MaxFieldExpandNum 1 -}}
31+
{{ end -}}
32+
33+
{{ if gt .MaxFieldExpandNum 1 }}
2934
state [{{ .StateSize }}]uint8 // Used for tracking expanded fields.
30-
{{ end }}
31-
32-
UnknownFields []proto.Field // UnknownFields are fields that are exist but they are not defined in Profile.xlsx
33-
{{- if and (not (eq .Name "FileId")) (not (eq .Name "DeveloperDataId")) (not (eq .Name "FieldDescription")) }}
34-
DeveloperFields []proto.DeveloperField // DeveloperFields are custom data fields [Added since protocol version 2.0]
35-
{{- end }}
35+
{{ end -}}
3636
}
3737

3838
// New{{ .Name }} creates new {{ .Name }} struct based on given mesg.

profile/mesgdef/aad_accel_features_gen.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

profile/mesgdef/accelerometer_data_gen.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

profile/mesgdef/activity_gen.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

profile/mesgdef/ant_channel_id_gen.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

profile/mesgdef/ant_rx_gen.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

profile/mesgdef/ant_tx_gen.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

profile/mesgdef/aviation_attitude_gen.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

profile/mesgdef/barometer_data_gen.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)