Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-85255

[SBE] Avoid overhead of boost::optional for optional SlotIds

    • Type: Icon: Improvement Improvement
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Execution

      Currently optional SlotIds are passed as boost::optional values that wrap the SlotId. SlotId is just an 8-byte native integer, and thus fits in a single register, whereas boost::optional is larger (a bool plus the wrapped integer, likely consuming a total of 16 bytes due to alignment). Thus there is a performance cost of fewer boost::optional arguments fitting in register for method calls, more scarce CPU cache consumed, and checking whether the value is present or boost::none needing to make a separate memory or cache lookup.

      From a performance standpoint, ideally we would not require more than 8 bytes for an optional SlotId. We would also like to avoid having to check whether a SlotId is valid in the case where the SlotId is not considered optional.

      Some ideas:

      1. constexpr SlotId NULL_SLOT_ID = -1LL;
      2. fast_optional<SlotId, -1>
      3. Debug-only assertions to check for invalid SlotIds in non-optional ones (e.g. in a struct that, in optimized builds, only contains a native integer)
      4. Prefixing the names of optional SlotId variables and arguments with "opt" as a code standard

      The performance impact of 16 bytes vs 8 bytes is probably not a lot at higher levels of code, but at lower levels, e.g. inside tight loops, it could be substantial.

            Assignee:
            backlog-query-execution [DO NOT USE] Backlog - Query Execution
            Reporter:
            kevin.cherkauer@mongodb.com Kevin Cherkauer
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: