Uploaded image for project: 'WiredTiger'
  1. WiredTiger
  2. WT-11932

Potential 12% latency improvement for query by reducing WT checks

    • Type: Icon: Improvement Improvement
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Labels:
      None
    • StorEng - Refinement Pipeline

      I did a change to remove all the checks in the next and prev code paths that are not relevant to mongodb's correctness. I ran the same test as ian.boros@mongodb.com did in WT-9786. My change improves the query latency from around 569ms to 503ms on my dev box. The checks I remove are listed in the below diff:

      diff --git a/src/third_party/wiredtiger/src/cursor/cur_file.c b/src/third_party/wiredtiger/src/cursor/cur_file.c
      index 9fc7efd7d7b..ed8b36e6173 100644
      --- a/src/third_party/wiredtiger/src/cursor/cur_file.c
      +++ b/src/third_party/wiredtiger/src/cursor/cur_file.c
      @@ -179,11 +179,6 @@ __curfile_next(WT_CURSOR *cursor)
       
           cbt = (WT_CURSOR_BTREE *)cursor;
           CURSOR_API_CALL(cursor, session, next, CUR2BT(cbt));
      -    API_RETRYABLE(session);
      -    CURSOR_REPOSITION_ENTER(cursor, session);
      -    WT_ERR(__cursor_copy_release(cursor));
      -
      -    WT_ERR(__curfile_check_cbt_txn(session, cbt));
       
           WT_WITH_CHECKPOINT(session, cbt, ret = __wt_btcur_next(cbt, false));
           WT_ERR(ret);
      @@ -194,8 +189,6 @@ __curfile_next(WT_CURSOR *cursor)
               F_MASK(cursor, WT_CURSTD_VALUE_SET) == WT_CURSTD_VALUE_INT);
       
       err:
      -    CURSOR_REPOSITION_END(cursor, session);
      -    API_RETRYABLE_END(session, ret);
           API_END_RET_STAT(session, ret, cursor_next);
       }
       
      @@ -242,11 +235,6 @@ __curfile_prev(WT_CURSOR *cursor)
       
           cbt = (WT_CURSOR_BTREE *)cursor;
           CURSOR_API_CALL(cursor, session, prev, CUR2BT(cbt));
      -    API_RETRYABLE(session);
      -    CURSOR_REPOSITION_ENTER(cursor, session);
      -    WT_ERR(__cursor_copy_release(cursor));
      -
      -    WT_ERR(__curfile_check_cbt_txn(session, cbt));
       
           WT_WITH_CHECKPOINT(session, cbt, ret = __wt_btcur_prev(cbt, false));
           WT_ERR(ret);
      @@ -257,8 +245,6 @@ __curfile_prev(WT_CURSOR *cursor)
               F_MASK(cursor, WT_CURSTD_VALUE_SET) == WT_CURSTD_VALUE_INT);
       
       err:
      -    API_RETRYABLE_END(session, ret);
      -    CURSOR_REPOSITION_END(cursor, session);
           API_END_RET_STAT(session, ret, cursor_prev);
       }
      
      diff --git a/src/third_party/wiredtiger/src/include/api.h b/src/third_party/wiredtiger/src/include/api.h
      index 8a5513aa2bc..7f1cd81ce28 100644
      --- a/src/third_party/wiredtiger/src/include/api.h
      +++ b/src/third_party/wiredtiger/src/include/api.h
      @@ -50,21 +50,13 @@
       
       /* Standard entry points to the API: declares/initializes local variables. */
       #define API_SESSION_INIT(s, h, n, dh)                                   \
      -    WT_TRACK_OP_DECL;                                                   \
           API_SESSION_PUSH(s, h, n, dh);                                      \
      -    /*                                                                  \
      -     * No code before this line, otherwise error handling won't be      \
      -     * correct.                                                         \
      -     */                                                                 \
      -    WT_ERR(WT_SESSION_CHECK_PANIC(s));                                  \
           WT_SINGLE_THREAD_CHECK_START(s);                                    \
      -    WT_TRACK_OP_INIT(s);                                                \
           if ((s)->api_call_counter == 1 && !F_ISSET(s, WT_SESSION_INTERNAL)) \
               __wt_op_timer_start(s);                                         \
           /* Reset wait time if this isn't an API reentry. */                 \
           if ((s)->api_call_counter == 1)                                     \
               (s)->cache_wait_us = 0;                                         \
      -    __wt_verbose((s), WT_VERB_API, "%s", "CALL: " #h ":" #n)
       
       #define API_CALL_NOCONF(s, h, n, dh) \
           do {                             \
      @@ -79,7 +71,6 @@
       
       #define API_END(s, ret)                                                                    \
           if ((s) != NULL) {                                                                     \
      -        WT_TRACK_OP_END(s);                                                                \
               WT_SINGLE_THREAD_CHECK_STOP(s);                                                    \
               if ((ret) != 0)                                                                    \
                   __wt_txn_err_set(s, ret);                                                      \
      @@ -179,7 +170,6 @@
       
       #define API_END_RET_STAT(s, ret, api) \
           do {                              \
      -        API_END_STAT(s, ret, api);    \
               API_END_RET(s, ret);          \
           } while (0)
       
      @@ -223,9 +213,7 @@
           do {                                                       \
               if ((s)->api_call_counter == 0) {                      \
                   int __prepare_ret;                                 \
      -            API_SESSION_PUSH(s, WT_SESSION, n, NULL);          \
                   __prepare_ret = __wt_txn_context_prepare_check(s); \
      -            API_SESSION_POP(s);                                \
                   WT_RET(__prepare_ret);                             \
               }                                                      \
           } while (0)
      @@ -244,21 +232,15 @@
           (s) = CUR2S(cur);                                                                      \
           SESSION_API_PREPARE_CHECK(s, WT_CURSOR, n);                                            \
           API_CALL_NOCONF(s, WT_CURSOR, n, ((bt) == NULL) ? NULL : ((WT_BTREE *)(bt))->dhandle); \
      -    if (F_ISSET(cur, WT_CURSTD_CACHED))                                                    \
      -    WT_ERR(__wt_cursor_cached(cur))
       
       #define CURSOR_API_CALL_CONF(cur, s, n, config, cfg, bt)                                         \
           (s) = CUR2S(cur);                                                                            \
           SESSION_API_PREPARE_CHECK(s, WT_CURSOR, n);                                                  \
           API_CALL(s, WT_CURSOR, n, ((bt) == NULL) ? NULL : ((WT_BTREE *)(bt))->dhandle, config, cfg); \
      -    if (F_ISSET(cur, WT_CURSTD_CACHED))                                                          \
      -    WT_ERR(__wt_cursor_cached(cur))
       
       #define CURSOR_API_CALL_PREPARE_ALLOWED(cur, s, n, bt)                                     \
           (s) = CUR2S(cur);                                                                      \
           API_CALL_NOCONF(s, WT_CURSOR, n, ((bt) == NULL) ? NULL : ((WT_BTREE *)(bt))->dhandle); \
      -    if (F_ISSET(cur, WT_CURSTD_CACHED))                                                    \
      -    WT_ERR(__wt_cursor_cached(cur))
      

      I haven't done the test to remove each individual check to see how much performance we can get for each of them. Some checks are not impacting correctness but provides important functions for diagnosis, such as code to track api stats and op track. It may not be possible to remove them. In addition, I believe there are more checks we can get rid of in __wt_cursor_func_init if we refactor the code.

      This is the ticket to facilitate initial discussion on how we can improve the code. We need to create separate tickets to remove the individual check if we decide to do so.

            Assignee:
            backlog-server-storage-engines [DO NOT USE] Backlog - Storage Engines Team
            Reporter:
            chenhao.qu@mongodb.com Chenhao Qu
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: