Skip to content

Instantly share code, notes, and snippets.

Index: jctools-core/src/main/java/org/jctools/maps/NonBlockingHashMap.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jctools-core/src/main/java/org/jctools/maps/NonBlockingHashMap.java (revision a2191c1e0243c8cd4690990d6b250b26a3ca8bfa)
+++ jctools-core/src/main/java/org/jctools/maps/NonBlockingHashMap.java (revision )
@@ -650,134 +650,130 @@
int reprobe_cnt=0;
Object K=null, V=null;
0.18% 0.00% │││ │ 0x00007f485a84780d: lock addl $0x0,(%rsp) ;*invokevirtual putObjectRelease {reexecute=0 rethrow=0 return_oop=0}
│││ │ ; - sun.misc.Unsafe::putOrderedObject@7 (line 1042)
│││ │ ; - org.jctools.util.UnsafeRefArrayAccess::soElement@6 (line 77)
│││ │ ; - org.jctools.queues.SpscArrayQueue::offer@64 (line 187)
│││ │ ; - org.jctools.jmh.throughput.QueueThroughputBackoffNone::offer@8 (line 92)
│││ │ ; - org.jctools.jmh.throughput.generated.QueueThroughputBackoffNone_tpt_jmhTest::offer_thrpt_jmhStub@17 (line 299)
22.58% 31.59% │││ │ 0x00007f485a847812: inc %rbp ;*ladd {reexecute=0 rethrow=0 return_oop=0}
│││ │
// CPP, OpenJDK C2 compiler style... this is from:
// http://hg.openjdk.java.net/jdk9/jdk9/hotspot/file/b756e7a2ec33/src/share/vm/opto/graphKit.cpp#l4285
void GraphKit::g1_write_barrier_post(Node* oop_store,
Node* obj,
Node* adr,
uint alias_idx,
Node* val,
BasicType bt,
bool use_precise) {
/// ... Loads of other crap here...
# c2, level 4, org.jctools.jmh.throughput.generated.QueueThroughputBackoffNone_tpt_jmhTest::offer_thrpt_jmhStub, version 643 (89 bytes)
0,46%| 0xb254: mov %r11,%rcx ;*getfield buffer {reexecute=0 rethrow=0 return_oop=0}
| ; - org.jctools.queues.SpscArrayQueue::offer@14 (line 176)
| ; - org.jctools.jmh.throughput.QueueThroughputBackoffNone::offer@8 (line 92)
| ; - org.jctools.jmh.throughput.generated.QueueThroughputBackoffNone_tpt_jmhTest::offer_thrpt_jmhStub@17 (line 299)
| 0xb257: lea 0x10(%r11,%r10,4),%r13 ;*invokevirtual getObjectVolatile {reexecute=0 rethrow=0 return_oop=0}
| ; - sun.misc.Unsafe::getObjectVolatile@5 (line 923)
| ; - org.jctools.util.UnsafeRefArrayAccess::lvElement@5 (line 103)
| ; - org.jctools.queues.SpscArrayQueue::offerSlowPath
protected final boolean offerColdPath(final E[] buffer, final long mask, final E e, final long index,
final long offset) {
final long lookAheadStep = this.lookAheadStep;
// normal case, go around the buffer or resize if full (unless we hit max capacity)
if (lookAheadStep > 0) {
long lookAheadElementOffset = calcElementOffset(index + lookAheadStep, mask);
// Try and look ahead a number of elements so we don't have to do this all the time
if (null == lvElement(buffer, lookAheadElementOffset)) {
producerBufferLimit = index + lookAheadStep - 1; // joy, there's plenty of room
writeToQueue(buffer, e, index, offset);
@Override
protected final boolean offerColdPath(E[] buffer, long mask, E e, long pIndex, long offset) {
// use a fixed lookahead step based on buffer capacity
final long lookAheadStep = (mask + 1) / 4;
long pBufferLimit = pIndex + lookAheadStep;
long pQueueLimit = producerQueueLimit;
// out of known space
if (pIndex >= pQueueLimit) {
// we tested against a potentially out of date queue limit, refresh it
private E newBufferPoll(E[] buffer, final long index) {
final E[] newBuffer = lvNextArrayAndUnlink(buffer);
final long newMask = newBuffer.length - 2; // because buffer last element is for linking
// update consumer view on buffer
consumerBuffer = nextBuffer;
consumerMask = newMask;
// poll element, must be visible in new buffer
final long offsetInNew = calcElementOffset(index, newMask);
@nitsanw
nitsanw / SpscLAQUnbounded.java
Created October 21, 2016 10:59
Unbounded SPSC LAQ cold path
@Override
protected boolean offerColdPath(E[] buffer, long mask, E e, long pIndex, long offset) {
// use a fixed lookahead step based on buffer capacity
final long lookAheadStep = (mask + 1) / 4;
long pBufferLimit = pIndex + lookAheadStep;
// go around the buffer or add a new buffer
if (null == lvElement(buffer, calcElementOffset(pBufferLimit, mask))) {
// the element lookAheadStep away is empty, so we can use up to the element before it
producerBufferLimit = pBufferLimit - 1;
@nitsanw
nitsanw / SpscLAQ.java
Last active October 21, 2016 10:53
Hot path SPSC LAQ
@Override
public boolean offer(final E e) {
Objects.requireNonNull(e);
// local load of fields to avoid repeated loads after volatile reads
final E[] buffer = producerBuffer;
final long index = producerIndex;
final long mask = producerMask;
final long offset = calcElementOffset(index, mask);
TotalCount=241116
Period(ms)=59994
Throughput(ops/sec)=4019.00
Min=164
Mean=630.28
50.000ptile=425
90.000ptile=1116
99.000ptile=3080
99.900ptile=11517
99.990ptile=50757