Skip to content

Commit 3c221fd

Browse files
BenHuddlestondaverigby
authored andcommitted
MB-36029: Shard Timings::interval_counters by core.
Cache contention was observed when many threads attempt to update the same interval_counters elements at the same time. Shard this by core to reduce the contention. False sharing was also observed with Bucket::response_counters. Cacheline pad the Timings object to prevent this. Perf stats (Triton 2 Node 80/20 R/W test): Before: 3,511,611 (Average of 24 runs) After: 3,563,007 (Average of 5 runs) Change-Id: I854bc654072f6789c82296a6e10cb54e8d5cdd13 Reviewed-on: http://review.couchbase.org/111868 Reviewed-by: Dave Rigby <[email protected]> Tested-by: Build Bot <[email protected]>
1 parent 0dd246f commit 3c221fd

File tree

2 files changed

+22
-13
lines changed

2 files changed

+22
-13
lines changed

daemon/timings.cc

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ void Timings::collect(cb::mcbp::ClientOpcode opcode,
5151
get_or_create_timing_histogram(
5252
std::underlying_type<cb::mcbp::ClientOpcode>::type(opcode))
5353
.add(duration_cast<microseconds>(nsec));
54-
auto& interval = interval_counters
55-
[std::underlying_type<cb::mcbp::ClientOpcode>::type(opcode)];
54+
auto& interval =
55+
interval_counters
56+
.get()[std::underlying_type<cb::mcbp::ClientOpcode>::type(
57+
opcode)];
5658
interval.count++;
5759
interval.duration_ns += nsec.count();
5860
}
@@ -170,19 +172,21 @@ void Timings::sample(std::chrono::seconds sample_interval) {
170172
cb::sampling::Interval interval_lookup, interval_mutation;
171173

172174
for (auto op : timings_mutations) {
173-
interval_mutation += interval_counters
174-
[std::underlying_type<cb::mcbp::ClientOpcode>::type(op)];
175-
interval_counters[std::underlying_type<cb::mcbp::ClientOpcode>::type(
176-
op)]
177-
.reset();
175+
for (auto intervals : interval_counters) {
176+
interval_mutation += intervals
177+
[std::underlying_type<cb::mcbp::ClientOpcode>::type(op)];
178+
intervals[std::underlying_type<cb::mcbp::ClientOpcode>::type(op)]
179+
.reset();
180+
}
178181
}
179182

180183
for (auto op : timings_retrievals) {
181-
interval_lookup += interval_counters
182-
[std::underlying_type<cb::mcbp::ClientOpcode>::type(op)];
183-
interval_counters[std::underlying_type<cb::mcbp::ClientOpcode>::type(
184-
op)]
185-
.reset();
184+
for (auto intervals : interval_counters) {
185+
interval_mutation += intervals
186+
[std::underlying_type<cb::mcbp::ClientOpcode>::type(op)];
187+
intervals[std::underlying_type<cb::mcbp::ClientOpcode>::type(op)]
188+
.reset();
189+
}
186190
}
187191

188192
{

daemon/timings.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <mcbp/protocol/opcode.h>
2222

23+
#include <platform/corestore.h>
2324
#include <utilities/hdrhistogram.h>
2425
#include <array>
2526
#include <mutex>
@@ -72,5 +73,9 @@ class Timings {
7273
// histogram class
7374
std::array<std::atomic<Hdr1sfMicroSecHistogram*>, MAX_NUM_OPCODES> timings;
7475
std::mutex histogram_mutex;
75-
std::array<cb::sampling::Interval, MAX_NUM_OPCODES> interval_counters;
76+
77+
// Sharded by core as cache contention was observed due to the number of
78+
// threads attempting to update the same timings stats.
79+
CoreStore<std::array<cb::sampling::Interval, MAX_NUM_OPCODES>>
80+
interval_counters;
7681
};

0 commit comments

Comments
 (0)