This is an automated email from the ASF dual-hosted git repository.

granthenke pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git


The following commit(s) were added to refs/heads/master by this push:
     new f7caae0  client: allocate InFlightOp from a Batcher Arena
f7caae0 is described below

commit f7caae03dc61ef48cfcc86cc279b63c46adee46a
Author: Todd Lipcon <[email protected]>
AuthorDate: Mon Jul 13 12:10:38 2020 -0700

    client: allocate InFlightOp from a Batcher Arena
    
    InFlightOps are always associated with a single Batcher, and Batchers
    are always associated with a single "flush". Given that, we can allocate
    them from a Batcher-local Arena instead of from the heap. This improves
    CPU consumption and throughput of the client by about 10%.
    
    Before:
    
    INSERT report
        rows total: 40000000
        time total: 10302.3 ms
      time per row: 0.000257559 ms
    Dropping auto-created table 
'default.loadgen_auto_0334edaa55fe4fdba242b0b4fcc5d360'
    
     Performance counter stats for './build/latest/bin/kudu perf loadgen 
localhost -num_rows_per_thread=5000000 -num_threads=8':
    
             100857.18 msec task-clock                #    9.738 CPUs utilized
                124584      context-switches          #    0.001 M/sec
                  6047      cpu-migrations            #    0.060 K/sec
                 31199      page-faults               #    0.309 K/sec
          412192743252      cycles                    #    4.087 GHz            
          (83.24%)
           95984615757      stalled-cycles-frontend   #   23.29% frontend 
cycles idle     (83.35%)
           80498019077      stalled-cycles-backend    #   19.53% backend cycles 
idle      (83.22%)
          225757843097      instructions              #    0.55  insn per cycle
                                                      #    0.43  stalled cycles 
per insn  (83.38%)
           43262879676      branches                  #  428.952 M/sec          
          (83.37%)
             276103070      branch-misses             #    0.64% of all 
branches          (83.43%)
    
          10.356736781 seconds time elapsed
    
          98.263563000 seconds user
           2.646264000 seconds sys
    
    After:
    
    INSERT report
        rows total: 40000000
        time total: 9730.09 ms
      time per row: 0.000243252 ms
    Dropping auto-created table 
'default.loadgen_auto_ffc0ea72dd064db7b3fa12b037454eb2'
    
     Performance counter stats for './build/latest/bin/kudu.client-opt perf 
loadgen localhost -num_rows_per_thread=5000000 -num_threads=8':
    
              91317.10 msec task-clock                #    9.327 CPUs utilized
                 57090      context-switches          #    0.625 K/sec
                  6661      cpu-migrations            #    0.073 K/sec
                 34568      page-faults               #    0.379 K/sec
          374170608484      cycles                    #    4.097 GHz            
          (83.31%)
           82165215635      stalled-cycles-frontend   #   21.96% frontend 
cycles idle     (83.35%)
           57601295335      stalled-cycles-backend    #   15.39% backend cycles 
idle      (83.25%)
          218776486065      instructions              #    0.58  insn per cycle
                                                      #    0.38  stalled cycles 
per insn  (83.35%)
           41762336591      branches                  #  457.333 M/sec          
          (83.34%)
             140528380      branch-misses             #    0.34% of all 
branches          (83.40%)
    
           9.790174460 seconds time elapsed
    
          89.079083000 seconds user
           2.276474000 seconds sys
    
    Change-Id: I446a8d21253b7a274872bff6d3e76705ac95d0d5
    Reviewed-on: http://gerrit.cloudera.org:8080/16189
    Tested-by: Kudu Jenkins
    Reviewed-by: Andrew Wong <[email protected]>
---
 src/kudu/client/batcher.cc | 16 +++++++---------
 src/kudu/client/batcher.h  |  3 +++
 2 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/src/kudu/client/batcher.cc b/src/kudu/client/batcher.cc
index 3653173..abe0dd6 100644
--- a/src/kudu/client/batcher.cc
+++ b/src/kudu/client/batcher.cc
@@ -45,7 +45,6 @@
 #include "kudu/common/wire_protocol.h"
 #include "kudu/common/wire_protocol.pb.h"
 #include "kudu/gutil/atomic_refcount.h"
-#include "kudu/gutil/basictypes.h"
 #include "kudu/gutil/map-util.h"
 #include "kudu/gutil/port.h"
 #include "kudu/gutil/strings/substitute.h"
@@ -395,7 +394,7 @@ WriteRpc::~WriteRpc() {
       }
     }
     if (i >= 0) {
-      delete ops_[i];
+      ops_[i]->~InFlightOp();
     }
   };
 
@@ -592,7 +591,8 @@ Batcher::Batcher(KuduClient* client,
     next_op_sequence_number_(0),
     timeout_(client->default_rpc_timeout()),
     outstanding_lookups_(0),
-    buffer_bytes_used_(0) {
+    buffer_bytes_used_(0),
+    arena_(1024) {
   ops_.set_empty_key(nullptr);
   ops_.set_deleted_key(reinterpret_cast<InFlightOp*>(-1));
 }
@@ -710,19 +710,18 @@ void Batcher::FlushAsync(KuduStatusCallback* cb) {
 Status Batcher::Add(KuduWriteOperation* write_op) {
   // As soon as we get the op, start looking up where it belongs,
   // so that when the user calls Flush, we are ready to go.
-  unique_ptr<InFlightOp> op(new InFlightOp());
+  InFlightOp* op = arena_.NewObject<InFlightOp>();
   string partition_key;
   
RETURN_NOT_OK(write_op->table_->partition_schema().EncodeKey(write_op->row(), 
&partition_key));
   op->write_op.reset(write_op);
   op->state = InFlightOp::kLookingUpTablet;
 
-  AddInFlightOp(op.get());
+  AddInFlightOp(op);
   VLOG(3) << "Looking up tablet for " << op->ToString();
   // Increment our reference count for the outstanding callback.
   //
   // deadline_ is set in FlushAsync(), after all Add() calls are done, so
   // here we're forced to create a new deadline.
-  auto op_raw = op.get();
   MonoTime deadline = ComputeDeadlineUnlocked();
   base::RefCountInc(&outstanding_lookups_);
   scoped_refptr<Batcher> self(this);
@@ -732,8 +731,7 @@ Status Batcher::Add(KuduWriteOperation* write_op) {
       deadline,
       MetaCache::LookupType::kPoint,
       &op->tablet,
-      [self, op_raw](const Status& s) { self->TabletLookupFinished(op_raw, s); 
});
-  ignore_result(op.release());
+      [self, op](const Status& s) { self->TabletLookupFinished(op, s); });
 
   buffer_bytes_used_.IncrementBy(write_op->SizeInBuffer());
 
@@ -773,7 +771,7 @@ void Batcher::MarkInFlightOpFailedUnlocked(InFlightOp* op, 
const Status& s) {
     << "Could not remove op " << op->ToString() << " from in-flight list";
   error_collector_->AddError(unique_ptr<KuduError>(new 
KuduError(op->write_op.release(), s)));
   had_errors_ = true;
-  delete op;
+  op->~InFlightOp();
 }
 
 void Batcher::TabletLookupFinished(InFlightOp* op, const Status& s) {
diff --git a/src/kudu/client/batcher.h b/src/kudu/client/batcher.h
index 0086869..f11148e 100644
--- a/src/kudu/client/batcher.h
+++ b/src/kudu/client/batcher.h
@@ -33,6 +33,7 @@
 #include "kudu/gutil/ref_counted.h"
 #include "kudu/util/atomic.h"
 #include "kudu/util/locks.h"
+#include "kudu/util/memory/arena.h"
 #include "kudu/util/monotime.h"
 #include "kudu/util/status.h"
 
@@ -230,6 +231,8 @@ class Batcher : public RefCountedThreadSafe<Batcher> {
   // The number of bytes used in the buffer for pending operations.
   AtomicInt<int64_t> buffer_bytes_used_;
 
+  Arena arena_;
+
   DISALLOW_COPY_AND_ASSIGN(Batcher);
 };
 

Reply via email to