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

Investigate implementation of Nebari SortStage that doesn't require double virtual dispatch

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

      Current implementation of SortStage completely hides private template implementation, but this is done at a cost of double virtual method call in getNext and some field indirection.

      We should consider implementing a variant that only requires one virtual dispatch and doesn't require field indirection, but that may require some framework changes. Few ideas:

       

      1) [anna.wawrzyniak@mongodb.com] Use static factory methods, like SortStage::make(...) rather than makeS<SortStage>. This pattern would relax the requirement of makeS returning a runtime instance of strictly SortStage and instead allow for returning subtypes of SortStage. This would allow for SortStage to have specialized derived implementation classes that can be templatized, without callers. 

      The side benefit of doing for all stages is better IDE interaction.

      It may also allow for more control over the creation process (i.e. [martin.neupauer@mongodb.com ] idea of memory usage tracking)

      A POC of such implementation for SortStage is here:

      https://github.com/10gen/mongo/compare/anna.wawrzyniak/sort_perf_make?expand=1

       

      2) [andrew.paroski@mongodb.com ] Use an aligned char buffer for individual key/value pair storage (and use reinterp-cast as needed), and see how much we can move from SortImpl to SortStage. I'm not sure how this experiment would play out, but I'd be interested to spend a few hours trying it out and seeing if anything interesting comes from it, and looking at if perf and machine code quality and size is better or worse.

      3)  [andrew.paroski@mongodb.com ] I've been thinking about a general optimization for PlanStage::getNext(), where instead of using C++ virtual methods instead we use function pointers. The neat thing about this is that a given stage's "getNext" func ptr could then return a pair<Result, func-ptr-type> and provide a (potentially different) function pointer to call next time. Certain stages like LoopJoinStage that could take advantage of this to improve perf. This would also reduce the number of memory accesses needed for dispatch. (I'm also interested in seeing if it would be a win for each node's parent to hold its getNext func ptr.) (edited) 

            Assignee:
            backlog-query-execution [DO NOT USE] Backlog - Query Execution
            Reporter:
            anna.wawrzyniak@mongodb.com Anna Wawrzyniak
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: