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);
};