Opened 7 months ago

Last modified 7 months ago

#2271 new enhancement

CoDeL Queue with single-lock bulk put

Reported by: zab Owned by:
Priority: minor Milestone: undecided
Component: router/transport Version: 0.9.34
Keywords: codel Cc: zzz, slumlord
Parent Tickets:

Description

Profiling with YourKit shows that UDP Receiver which is a time-critical thread spends equal amount of time reading from the channel and put()-ing in the CoDeL queue. (after patch from #2253 is applied)

It would be nice to have a bulk put() in a CoDeL queue which can add multiple elements with a single lock() call. This may require either rewriting or not using an LBQ at all.

Subtickets (add)

Attachments (1)

udp-receiver.png (254.5 KB) - added by zab 7 months ago.
UDP Receiver thread splitting time between read() and put()

Download all attachments as: .zip

Change History (6)

Changed 7 months ago by zab

UDP Receiver thread splitting time between read() and put()

comment:1 Changed 7 months ago by zab

On a second thought, this might be a perfect use case for a Disruptor ring.

comment:2 Changed 7 months ago by zab

Migrated this to Disruptor and now 100% of the cpu time used by this thread is spent doing i/o :)

You can find the data structures and Disruptor 3.4.2 source code in the i2p.i2p.zab.disruptor branch.

comment:3 Changed 7 months ago by zzz

Links for research:
https://github.com/LMAX-Exchange/disruptor
https://lmax-exchange.github.io/disruptor/

Haven't gone through it yet, there's a lot to read, will take a while.

But at first glance, it uses sun.misc.Unsafe which is deprecated in Java 8/9/10 and unavailable in Android. This is problematic.

If we want a single-lock putAll() or offerAll() or addAll() in our CoDel? classes that should be easy enough to do.

comment:4 Changed 7 months ago by zab

Single-lock bulk put only makes sense if nio is used for reading from the UDP socket (#2253) because with blocking read there is never going to be a case where we receive more than one DatagramPacket per receive() call.

sun.misc.Unsafe was not deprecated in java 9, it was made public.

comment:5 Changed 7 months ago by zzz

re: addAll() comment 3 above:
our CoDel? extends LBQ which extends AbstractQueue?, which is where addAll() is. So it presumably doesn't implement single-lock. Since we don't have access to the LBQ private putLock (see e.g. http://kickjava.com/src/java/util/concurrent/LinkedBlockingQueue.java.htm )
so it isn't 'easy enough to do'

Note: See TracTickets for help on using tickets.