[SERVER-85255] [SBE] Avoid overhead of boost::optional for optional SlotIds Created: 16/Jan/24  Updated: 22/Jan/24

Status: Backlog
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Kevin Cherkauer Assignee: Backlog - Query Execution
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Assigned Teams:
Query Execution
Participants:

 Description   

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.


Generated at Thu Feb 08 06:57:17 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.